Compare commits
11 Commits
57142c6645
...
4d6ada502d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d6ada502d | ||
|
|
c624a111dc | ||
| da5d80a1c8 | |||
| e35a1eeda1 | |||
| dc18aaaf03 | |||
| 6b6919fed2 | |||
| 085973963a | |||
| 6664709189 | |||
| 11cbf9687e | |||
| 466d2807e6 | |||
|
|
b2c4547842 |
22
.github/workflows/rust.yml
vendored
Normal file
22
.github/workflows/rust.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Rust
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Build
|
||||||
|
run: cargo build --verbose
|
||||||
|
- name: Run tests
|
||||||
|
run: cargo test --verbose
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
name = "i3status-custom-pim"
|
name = "i3status-custom-pim"
|
||||||
description = "Generates JSON output for use with custom block of i3status-rust."
|
description = "Generates JSON output for use with custom block of i3status-rust."
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Martin Bley <martin@mb-oss.de>"]
|
authors = ["Martin Bley <dev@mb-oss.de>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
65
README.md
65
README.md
@@ -1,3 +1,66 @@
|
|||||||
# i3status-custom-pim
|
# i3status-custom-pim
|
||||||
Generates JSON output for use with _custom_ block of [i3status-rust](https://github.com/greshake/i3status-rust)
|

|
||||||
|
|
||||||
|
`i3status-custom-pim` is a tool to output JSON content for users of the [pimutils](https://github.com/pimutils)
|
||||||
|
|
||||||
|
- [khal](https://github.com/pimutils/khal) and
|
||||||
|
- [todoman](https://github.com/pimutils/todoman).
|
||||||
|
|
||||||
|
The output can be used for the custom block of [i3status-rust](https://github.com/greshake/i3status-rust) to display events or due dates in the i3 status bar.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
In order to build a binary, you need the Rust language and the package manager `cargo`. And of course you need the pimutils [khal](https://github.com/pimutils/khal) and/or
|
||||||
|
[todoman](https://github.com/pimutils/todoman). Please refer to the documentation on the project pages in order to install and configure these tools.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
There are no packaged versions yet, so you have to compile `i3status-cutom-pim` yourself.
|
||||||
|
```
|
||||||
|
$ cargo install --git https://github.com/theamma/i3status-custom-pim i3status-custom-pim
|
||||||
|
```
|
||||||
|
By default, this will install the binary to `~/.cargo/bin/i3status-custom-pim`. Please make sure, this is in your $PATH or copy the binary to an appropriate location (like `/usr/local/bin`).
|
||||||
|
|
||||||
|
You may also compile manually
|
||||||
|
```
|
||||||
|
$ git clone https://github.com/theamma/i3status-custom-pim
|
||||||
|
$ cd i3status-custom-pim && cargo build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
To add the blocks, add this to your i3status-rs configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
[[block]]
|
||||||
|
block = "custom"
|
||||||
|
command = ''' i3status-custom-pim -k '''
|
||||||
|
json = true
|
||||||
|
|
||||||
|
[[block]]
|
||||||
|
block = "custom"
|
||||||
|
command = ''' i3status-custom-pim -t -i tasks -w 20160 -c 7200'''
|
||||||
|
json = true
|
||||||
|
```
|
||||||
|
|
||||||
|
Thresholds for *warning* or *critical* state can be given via commandline switches. In *warning* state the widget will change the background colour to orange, in *critical* state to red.
|
||||||
|
|
||||||
|
Please note: A due date has to be set for each task, otherwise the block will run into an error. This bug is addressed in issue #2.
|
||||||
|
|
||||||
|
Please run `i3status-custom-pim --help` for available options.
|
||||||
|
```
|
||||||
|
i3status-custom-pim 0.1.0
|
||||||
|
Martin Bley <dev@mb-oss.de>
|
||||||
|
Generates JSON output for use with custom block of i3status-rust.
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
i3status-custom-pim [FLAGS] [OPTIONS]
|
||||||
|
|
||||||
|
FLAGS:
|
||||||
|
-h, --help Prints help information
|
||||||
|
-k, --khal output khal events
|
||||||
|
-t, --todo output todos
|
||||||
|
-V, --version Prints version information
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-i, --icon <icon> the icon used (only names valid in i3status-rust) [default: calendar]
|
||||||
|
-c <threshold-crit> threshold for critical status in minutes [default: 15]
|
||||||
|
-w <threshold-warn> threshold for warning status in minutes [default: 60]
|
||||||
|
```
|
||||||
|
|||||||
BIN
img/example_bar.png
Normal file
BIN
img/example_bar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
79
src/main.rs
79
src/main.rs
@@ -1,4 +1,4 @@
|
|||||||
use chrono::{Local, NaiveTime};
|
use chrono::{Local, NaiveDateTime, NaiveTime};
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
@@ -38,34 +38,27 @@ struct Cli {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Status {
|
enum Status {
|
||||||
Idle,
|
Idle,
|
||||||
Warn,
|
Warning,
|
||||||
Crit,
|
Critical,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_status(events: Vec<String>, w: i64, c: i64) -> Result<Status, String> {
|
fn get_status(events: Vec<NaiveDateTime>, w: i64, c: i64) -> Result<Status, String> {
|
||||||
let now = Local::now().time();
|
let now = Local::now();
|
||||||
let mut event_remaining: i64 = 24 * 60;
|
let mut event_remaining: i64 = 365 * 24 * 60;
|
||||||
let mut state = Status::Idle;
|
let mut state = Status::Idle;
|
||||||
|
|
||||||
for e in events.iter() {
|
for e in events.iter() {
|
||||||
let e_start = match NaiveTime::parse_from_str(e, "%H:%M") {
|
let diff = *e - now.naive_local();
|
||||||
Ok(s) => s,
|
|
||||||
Err(f) => {
|
|
||||||
let message = format!("error parsing time value: {}", f);
|
|
||||||
return Err(message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let diff = e_start - now;
|
|
||||||
if (diff.num_minutes() < event_remaining) && (diff.num_minutes() >= 0) {
|
if (diff.num_minutes() < event_remaining) && (diff.num_minutes() >= 0) {
|
||||||
event_remaining = diff.num_minutes()
|
event_remaining = diff.num_minutes()
|
||||||
}
|
}
|
||||||
|
|
||||||
if event_remaining >= 0 {
|
if event_remaining >= 0 {
|
||||||
if event_remaining <= w {
|
if event_remaining <= w {
|
||||||
state = Status::Warn;
|
state = Status::Warning;
|
||||||
}
|
}
|
||||||
if event_remaining <= c {
|
if event_remaining <= c {
|
||||||
state = Status::Crit;
|
state = Status::Critical;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +70,7 @@ fn main() {
|
|||||||
|
|
||||||
if (!args.khal && !args.todo) || (args.khal && args.todo) {
|
if (!args.khal && !args.todo) || (args.khal && args.todo) {
|
||||||
eprintln!("Please provide either khal or todo flag.");
|
eprintln!("Please provide either khal or todo flag.");
|
||||||
Cli::clap().print_help();
|
Cli::clap().print_help().unwrap();
|
||||||
println!();
|
println!();
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
@@ -117,16 +110,20 @@ fn main() {
|
|||||||
|
|
||||||
let dayline = match out_iter.nth(0) {
|
let dayline = match out_iter.nth(0) {
|
||||||
Some(d) => d,
|
Some(d) => d,
|
||||||
None => {
|
None => { "None" }
|
||||||
eprintln!("Output seems empty. Exiting");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut events: Vec<String> = Vec::new();
|
let today = Local::today();
|
||||||
|
let mut events: Vec<NaiveDateTime> = Vec::new();
|
||||||
if dayline.trim() == "Today" {
|
if dayline.trim() == "Today" {
|
||||||
for e in out_iter {
|
for e in out_iter {
|
||||||
events.push(e.to_string());
|
let event_start = match NaiveTime::parse_from_str(e, "%H:%M") {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_f) => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
events.push(today.and_time(event_start).unwrap().naive_local());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let count = events.len();
|
let count = events.len();
|
||||||
@@ -143,9 +140,7 @@ fn main() {
|
|||||||
args.icon, state, count
|
args.icon, state, count
|
||||||
);
|
);
|
||||||
} else if args.todo {
|
} else if args.todo {
|
||||||
let cmd = Command::new("todo")
|
let cmd = Command::new("todo").arg("--porcelain").output();
|
||||||
.arg("--porcelain")
|
|
||||||
.output();
|
|
||||||
|
|
||||||
let stdout = match cmd {
|
let stdout = match cmd {
|
||||||
Ok(o) => o.stdout,
|
Ok(o) => o.stdout,
|
||||||
@@ -163,28 +158,34 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parsed = match json::parse(&output){
|
let parsed = match json::parse(&output) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("parsing JSON failed: {}", e);
|
eprintln!("parsing JSON failed: {}", e);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let count = parsed.len();
|
let count = parsed.len();
|
||||||
println!("{:#?}", count);
|
//println!("{:#?}", count);
|
||||||
|
|
||||||
let mut tasks: Vec<String> = Vec::new();
|
let mut tasks: Vec<NaiveDateTime> = Vec::new();
|
||||||
for due in parsed.members() {
|
for due in parsed.members() {
|
||||||
tasks.push(due.as_str().unwrap().to_string());
|
tasks.push(NaiveDateTime::from_timestamp(
|
||||||
|
due["due"].as_i64().unwrap(),
|
||||||
|
0,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
/*
|
let state = match get_status(tasks, args.threshold_warn, args.threshold_crit) {
|
||||||
for i in parsed {
|
Ok(s) => s,
|
||||||
i.foo();
|
Err(e) => {
|
||||||
}
|
eprintln!("{}", e);
|
||||||
*/
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
println!(
|
||||||
|
"{{ \"icon\": \"{}\", \"state\": \"{:?}\", \"text\": \"{}\" }}",
|
||||||
|
args.icon, state, count
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user