-
Notifications
You must be signed in to change notification settings - Fork 478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 1703 timewarrior block #1878
base: master
Are you sure you want to change the base?
Conversation
I can fix the things clippy is complaining about and the typo but what can I do with cspell? timew is the name of the program. |
d83df1e
to
707a961
Compare
Please add it to https://github.com/greshake/i3status-rust/blob/master/cspell.yaml |
@notramo would you like to test this? |
working prototype pad minutes Add some basic doc for functions wip stop_continue Redirect timew output to nulll states changes based on minutes Fix state change when stop Fix for new set_widget API
Co-authored-by: Max Verevkin <[email protected]>
62a7d49
to
5a4e842
Compare
This thing got stuck in pending. I've implemented your suggestion and updated the code for the new api. |
Wait, I've noticed there is an error when "continuing" a task |
There |
Looks like there's 2 small formatting issues (missing Diff in /home/runner/work/i3status-rust/i3status-rust/src/blocks/timewarrior.rs at line 141:
annotation: item.annotation,
start: chrono::TimeZone::from_utc_datetime(
&chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&item.start, "%Y%m%dT%H%M%SZ").unwrap()
+ &chrono::NaiveDateTime::parse_from_str(&item.start, "%Y%m%dT%H%M%SZ").unwrap(),
),
end: item.end.map(|v| {
chrono::TimeZone::from_utc_datetime(
Diff in /home/runner/work/i3status-rust/i3status-rust/src/blocks/timewarrior.rs at line 148:
&chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&v, "%Y%m%dT%H%M%SZ").unwrap()
+ &chrono::NaiveDateTime::parse_from_str(&v, "%Y%m%dT%H%M%SZ").unwrap(),
)
}),
} |
This comment was marked as outdated.
This comment was marked as outdated.
interval: Seconds, | ||
format: FormatConfig, | ||
|
||
info: Option<u64>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not make these i64
to avoid casting (elapsed.num_minutes() as u64)
?
] { | ||
if let Some(value) = level { | ||
if (elapsed.num_minutes() as u64) >= *value { | ||
state = st; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of keeping a state
variable and then later setting the widget state you can just set the widget's state directly.
Any maybe this is a stupid question, but as someone who's never used taskwarrior can you have multiple tasks at the same time? |
Here's a version without using the RAW intermediate stuct: diff --git a/src/blocks/timewarrior.rs b/src/blocks/timewarrior.rs
index 26d4a67c..2da0f92b 100644
--- a/src/blocks/timewarrior.rs
+++ b/src/blocks/timewarrior.rs
@@ -35,7 +35,9 @@
//! - `tasks`
use super::prelude::*;
-use chrono::DateTime;
+
+use chrono::{offset::Utc, DateTime};
+use serde::de::{self, Deserialize, Deserializer};
use tokio::process::Command;
#[derive(Deserialize, Debug, SmartDefault)]
@@ -68,7 +70,7 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
if let Some(tw) = data {
if tw.end.is_none() {
// only show active tasks
- let elapsed = chrono::Utc::now() - tw.start;
+ let elapsed = chrono::Utc::now() - tw.start.0;
// calculate state
for (level, st) in [
@@ -112,51 +114,31 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
}
}
-/// Raw output from timew
-#[derive(Deserialize, Debug)]
-struct TimewarriorRAW {
- pub id: u32,
- pub start: String,
- pub tags: Vec<String>,
- pub annotation: Option<String>,
- pub end: Option<String>,
-}
-
/// TimeWarrior entry
#[derive(Debug, PartialEq, Deserialize)]
-#[serde(from = "TimewarriorRAW")]
struct TimewarriorData {
pub id: u32,
- pub start: DateTime<chrono::offset::Utc>,
+ pub start: SerdeDateTime,
pub tags: Vec<String>,
pub annotation: Option<String>,
- pub end: Option<DateTime<chrono::offset::Utc>>,
+ pub end: Option<SerdeDateTime>,
}
-impl From<TimewarriorRAW> for TimewarriorData {
- fn from(item: TimewarriorRAW) -> Self {
- Self {
- id: item.id,
- tags: item.tags,
- annotation: item.annotation,
- start: chrono::TimeZone::from_utc_datetime(
- &chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&item.start, "%Y%m%dT%H%M%SZ").unwrap()
- ),
- end: item.end.map(|v| {
- chrono::TimeZone::from_utc_datetime(
- &chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&v, "%Y%m%dT%H%M%SZ").unwrap()
- )
- }),
- }
- }
-}
+#[derive(Debug, PartialEq)]
+struct SerdeDateTime(DateTime<Utc>);
-/// Format a DateTime given a format string
-#[allow(dead_code)]
-fn format_datetime(date: &DateTime<chrono::Utc>, format: &str) -> String {
- date.format(format).to_string()
+impl<'de> Deserialize<'de> for SerdeDateTime {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ use chrono::NaiveDateTime;
+ use de::Error;
+
+ let s = String::deserialize(deserializer)?;
+ let dt = NaiveDateTime::parse_from_str(&s, "%Y%m%dT%H%M%SZ").map_err(D::Error::custom)?;
+ Ok(Self(DateTime::<Utc>::from_naive_utc_and_offset(dt, Utc)))
+ }
}
/// Execute "timew export now" and return the current task (if any) |
Timewarrior and Taskwarrior are 2 different programs. This PR is about Timewarrior. In Timewarrior, one period can have multiple tags, but they must be started at the same time and ended at the same time (as they are attached to one interval). If someone wants to finish one tag and continue the other, they can stop the current period then start new with only one tag. |
Adds a block that displays the time of the current active task in timewarrior.
Closes #1703