Compare commits

...

11 Commits

Author SHA1 Message Date
theamma
4d6ada502d WIth new khal version output changed
Some checks failed
Rust / build (push) Has been cancelled
Fixed empty output bug for khal
2024-12-12 22:02:04 +01:00
Martin Bley
c624a111dc Updated README 2022-01-02 18:12:13 +01:00
da5d80a1c8 bugfix, when khal event is a birthday 2020-11-28 12:18:50 +01:00
e35a1eeda1 Changes email adrress of author 2020-11-26 13:05:48 +01:00
dc18aaaf03 wrote documentation 2020-11-26 12:59:13 +01:00
6b6919fed2 bugfix on enum for status 2020-11-25 22:59:41 +01:00
085973963a fixed formating 2020-11-25 22:46:39 +01:00
6664709189 bugfix for calculation of remaining time until due time reached 2020-11-25 22:40:28 +01:00
11cbf9687e Merge branch 'master' of github.com:theamma/i3status-custom-pim 2020-11-25 22:12:49 +01:00
466d2807e6 impemented todo 2020-11-25 22:10:35 +01:00
theamma
b2c4547842 Create rust.yml 2020-11-20 14:13:17 +01:00
5 changed files with 127 additions and 41 deletions

22
.github/workflows/rust.yml vendored Normal file
View 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

View File

@@ -2,7 +2,7 @@
name = "i3status-custom-pim"
description = "Generates JSON output for use with custom block of i3status-rust."
version = "0.1.0"
authors = ["Martin Bley <martin@mb-oss.de>"]
authors = ["Martin Bley <dev@mb-oss.de>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@@ -1,3 +1,66 @@
# i3status-custom-pim
Generates JSON output for use with _custom_ block of [i3status-rust](https://github.com/greshake/i3status-rust)
![example bar](img/example_bar.png)
`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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -1,4 +1,4 @@
use chrono::{Local, NaiveTime};
use chrono::{Local, NaiveDateTime, NaiveTime};
use std::process;
use std::process::Command;
use structopt::StructOpt;
@@ -38,34 +38,27 @@ struct Cli {
#[derive(Debug)]
enum Status {
Idle,
Warn,
Crit,
Warning,
Critical,
}
fn get_status(events: Vec<String>, w: i64, c: i64) -> Result<Status, String> {
let now = Local::now().time();
let mut event_remaining: i64 = 24 * 60;
fn get_status(events: Vec<NaiveDateTime>, w: i64, c: i64) -> Result<Status, String> {
let now = Local::now();
let mut event_remaining: i64 = 365 * 24 * 60;
let mut state = Status::Idle;
for e in events.iter() {
let e_start = match NaiveTime::parse_from_str(e, "%H:%M") {
Ok(s) => s,
Err(f) => {
let message = format!("error parsing time value: {}", f);
return Err(message);
}
};
let diff = e_start - now;
let diff = *e - now.naive_local();
if (diff.num_minutes() < event_remaining) && (diff.num_minutes() >= 0) {
event_remaining = diff.num_minutes()
}
if event_remaining >= 0 {
if event_remaining <= w {
state = Status::Warn;
state = Status::Warning;
}
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) {
eprintln!("Please provide either khal or todo flag.");
Cli::clap().print_help();
Cli::clap().print_help().unwrap();
println!();
process::exit(1);
}
@@ -117,16 +110,20 @@ fn main() {
let dayline = match out_iter.nth(0) {
Some(d) => d,
None => {
eprintln!("Output seems empty. Exiting");
process::exit(1);
}
None => { "None" }
};
let mut events: Vec<String> = Vec::new();
let today = Local::today();
let mut events: Vec<NaiveDateTime> = Vec::new();
if dayline.trim() == "Today" {
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();
@@ -143,9 +140,7 @@ fn main() {
args.icon, state, count
);
} else if args.todo {
let cmd = Command::new("todo")
.arg("--porcelain")
.output();
let cmd = Command::new("todo").arg("--porcelain").output();
let stdout = match cmd {
Ok(o) => o.stdout,
@@ -163,7 +158,7 @@ fn main() {
}
};
let mut parsed = match json::parse(&output){
let parsed = match json::parse(&output) {
Ok(p) => p,
Err(e) => {
eprintln!("parsing JSON failed: {}", e);
@@ -172,19 +167,25 @@ fn main() {
};
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() {
tasks.push(due.as_str().unwrap().to_string());
tasks.push(NaiveDateTime::from_timestamp(
due["due"].as_i64().unwrap(),
0,
));
}
/*
for i in parsed {
i.foo();
}
*/
let state = match get_status(tasks, args.threshold_warn, args.threshold_crit) {
Ok(s) => s,
Err(e) => {
eprintln!("{}", e);
process::exit(1);
}
};
println!(
"{{ \"icon\": \"{}\", \"state\": \"{:?}\", \"text\": \"{}\" }}",
args.icon, state, count
);
}
}