aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <yvchraiqi@protonmail.com>2022-06-10 17:02:31 +0200
committermetamuffin <yvchraiqi@protonmail.com>2022-06-10 17:02:31 +0200
commitd65b915f3dfda28aad6f2806df38c8ad77135d8b (patch)
tree46c57595ec7d64156b909e515a65f20fc6c0c7ff
parentee1116ffb12887d1ad985b67887c910f58202c1f (diff)
downloadkarlender-d65b915f3dfda28aad6f2806df38c8ad77135d8b.tar
karlender-d65b915f3dfda28aad6f2806df38c8ad77135d8b.tar.bz2
karlender-d65b915f3dfda28aad6f2806df38c8ad77135d8b.tar.zst
more code
-rw-r--r--Cargo.lock2
-rw-r--r--karlc/Cargo.toml1
-rw-r--r--karlc/src/main.rs54
-rw-r--r--karlc/src/pretty.rs39
-rw-r--r--karlcommon/src/protocol.rs25
-rw-r--r--karld/src/condition.rs2
-rw-r--r--karld/src/main.rs43
7 files changed, 107 insertions, 59 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 93095be..13acdf5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -55,6 +55,7 @@ dependencies = [
"libc",
"num-integer",
"num-traits",
+ "serde",
"time",
"winapi",
]
@@ -178,6 +179,7 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
name = "karlc"
version = "0.1.0"
dependencies = [
+ "chrono",
"clap",
"crossbeam-channel",
"env_logger",
diff --git a/karlc/Cargo.toml b/karlc/Cargo.toml
index c49ecfe..f95dee0 100644
--- a/karlc/Cargo.toml
+++ b/karlc/Cargo.toml
@@ -12,3 +12,4 @@ serde_json = "1.0.81"
env_logger = "0.9.0"
log = "0.4.17"
crossbeam-channel = "0.5.4"
+chrono = { version = "0.4.19", features = ["serde"] }
diff --git a/karlc/src/main.rs b/karlc/src/main.rs
index c69f1b2..9a89de9 100644
--- a/karlc/src/main.rs
+++ b/karlc/src/main.rs
@@ -1,14 +1,11 @@
pub mod client;
-pub mod pretty;
-
-use std::{os::unix::net::UnixStream, process::exit};
+use chrono::{NaiveDateTime, Utc};
use clap::{Parser, Subcommand};
use client::Client;
use karlcommon::{socket_path, version, ClientboundPacket, ServerboundPacket};
use log::{error, info};
-
-use crate::pretty::Pretty;
+use std::{os::unix::net::UnixStream, process::exit};
/// CLI interface for karld
#[derive(Parser)]
@@ -22,8 +19,8 @@ struct Args {
pub enum Action {
/// Show version of the client and daemon
Version,
- /// List all taskss
- ListTasks,
+ /// List all tasks
+ List,
}
fn main() {
@@ -54,11 +51,46 @@ fn main() {
error!("handshake is not the first packet")
}
}
- Action::ListTasks => {
- client.send(ServerboundPacket::Download);
- if let ClientboundPacket::DownloadResponse(tasks) = client.receiver.recv().unwrap() {
+ Action::List => {
+ client.send(ServerboundPacket::ListTasks);
+ if let ClientboundPacket::TaskList(tasks) = client.receiver.recv().unwrap() {
for t in tasks {
- println!("{}", Pretty(t))
+ print!(
+ "
+- \x1b[4m\x1b[1mTASK {}\x1b[0m
+ \x1b[38;2;100;255;100mName:\x1b[0m {}
+ \x1b[38;2;100;255;100mDescription:\x1b[0m {}
+ \x1b[38;2;100;255;100mOccurence:\x1b[0m {:?}
+ \x1b[38;2;100;255;100mNext instances: \x1b[0m",
+ t.id, t.name, t.description, t.occurence
+ );
+ client.send(ServerboundPacket::ListInstances {
+ task: t.id,
+ limit: 5,
+ range: Some(Utc::now().naive_local().timestamp())..None,
+ });
+ if let ClientboundPacket::InstanceList(instances) =
+ client.receiver.recv().unwrap()
+ {
+ for i in instances {
+ println!(
+ "\x1b[19G{} - {}",
+ i.at.start
+ .map(|e| format!(
+ "{}",
+ NaiveDateTime::from_timestamp(e as i64, 0)
+ ))
+ .unwrap_or("...".to_string()),
+ i.at.end
+ .map(|e| format!(
+ "{}",
+ NaiveDateTime::from_timestamp(e as i64, 0)
+ ))
+ .unwrap_or("...".to_string()),
+ );
+ }
+ }
+ println!();
}
}
}
diff --git a/karlc/src/pretty.rs b/karlc/src/pretty.rs
deleted file mode 100644
index ceb1bde..0000000
--- a/karlc/src/pretty.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use std::fmt::Display;
-
-use karlcommon::{Condition, Task};
-
-pub struct Pretty<T>(pub T);
-
-impl Display for Pretty<Task> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.write_fmt(format_args!(
- "- \x1b[4m\x1b[1mTASK {}\x1b[0m
- \x1b[38;2;100;255;100mName:\x1b[0m {}
- \x1b[38;2;100;255;100mDescription:\x1b[0m {}
- \x1b[38;2;100;255;100mOccurence:\x1b[0m {}",
- self.0.id,
- self.0.name,
- self.0.description,
- Pretty(self.0.occurence.clone())
- ))
- }
-}
-
-impl<T> Display for Pretty<Option<T>>
-where
- T: Clone,
- Pretty<T>: Display,
-{
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match &self.0 {
- Some(v) => Pretty(v.clone()).fmt(f),
- None => Ok(()),
- }
- }
-}
-
-impl Display for Pretty<Condition> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.write_fmt(format_args!("{:?}", self.0))
- }
-}
diff --git a/karlcommon/src/protocol.rs b/karlcommon/src/protocol.rs
index 55dda06..e5bb9f0 100644
--- a/karlcommon/src/protocol.rs
+++ b/karlcommon/src/protocol.rs
@@ -1,3 +1,4 @@
+use std::ops::Range;
use serde::{Deserialize, Serialize};
@@ -6,14 +7,22 @@ use serde::{Deserialize, Serialize};
pub enum ClientboundPacket {
Handshake { version: String },
Error(String),
- DownloadResponse(Vec<Task>),
+ TaskList(Vec<Task>),
+ InstanceList(Vec<Instance>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "data", rename_all = "snake_case")]
pub enum ServerboundPacket {
- Handshake { version: String },
- Download,
+ Handshake {
+ version: String,
+ },
+ ListTasks,
+ ListInstances {
+ task: u64,
+ range: Range<Option<i64>>,
+ limit: usize,
+ },
UpdateTask(Task),
RemoveTask(u64),
}
@@ -27,14 +36,20 @@ pub struct Task {
pub tags: Vec<String>,
pub priority: f64,
- pub completed: Option<u64>,
- pub scheduled: Option<u64>,
+ pub completed: Option<i64>,
+ pub scheduled: Option<i64>,
pub occurence: Option<Condition>,
pub deadline: Option<Condition>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct Instance {
+ pub of: u64,
+ pub at: Range<Option<i64>>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Condition {
From(Box<Condition>),
diff --git a/karld/src/condition.rs b/karld/src/condition.rs
index 5874e7b..a989a25 100644
--- a/karld/src/condition.rs
+++ b/karld/src/condition.rs
@@ -24,7 +24,7 @@ pub enum Direction {
Backward,
}
-trait ConditionFind {
+pub trait ConditionFind {
fn find(&self, edge: Edge, dir: Direction, from: NaiveDateTime) -> Option<NaiveDateTime>;
}
diff --git a/karld/src/main.rs b/karld/src/main.rs
index f70b7e7..1bc5798 100644
--- a/karld/src/main.rs
+++ b/karld/src/main.rs
@@ -1,9 +1,11 @@
pub mod condition;
pub mod interface;
+use chrono::NaiveDateTime;
+use condition::ConditionFind;
use crossbeam_channel::Sender;
use interface::network_loop;
-use karlcommon::{ClientboundPacket, Condition, Property, ServerboundPacket, Task};
+use karlcommon::{ClientboundPacket, Condition, Instance, Property, ServerboundPacket, Task};
use log::{debug, info};
use std::{collections::HashMap, sync::RwLock};
@@ -44,8 +46,8 @@ lazy_static::lazy_static! {
pub fn handle_packet(client: u32, packet: ServerboundPacket, responder: Sender<ClientboundPacket>) {
match packet {
- ServerboundPacket::Download => {
- let _ = responder.send(ClientboundPacket::DownloadResponse(
+ ServerboundPacket::ListTasks => {
+ let _ = responder.send(ClientboundPacket::TaskList(
TASKS.read().unwrap().values().map(|e| e.clone()).collect(),
));
}
@@ -58,5 +60,40 @@ pub fn handle_packet(client: u32, packet: ServerboundPacket, responder: Sender<C
ServerboundPacket::Handshake { version } => {
debug!("{client}: version {version}");
}
+ ServerboundPacket::ListInstances { range, task, limit } => {
+ let t = match TASKS.read().unwrap().get(&task).cloned() {
+ Some(t) => t,
+ None => {
+ let _ =
+ responder.send(ClientboundPacket::Error("task does not exist".to_string()));
+ return;
+ }
+ };
+
+ let mut ocs = vec![];
+ if let Some(o) = &t.occurence {
+ let mut time = NaiveDateTime::from_timestamp(range.start.unwrap_or(0), 0);
+ let end_time = range.end.map(|e| NaiveDateTime::from_timestamp(e, 0));
+ for _ in 0..limit {
+ let start = o.find(condition::Edge::Start, condition::Direction::Forward, time);
+ let end = o.find(condition::Edge::End, condition::Direction::Forward, time);
+ ocs.push(Instance {
+ of: t.id,
+ at: start.map(|e| e.timestamp())..end.map(|e| e.timestamp()),
+ });
+ if let Some(s) = end {
+ if let Some(e) = end_time {
+ if s > e {
+ break;
+ }
+ }
+ time = s;
+ } else {
+ break;
+ }
+ }
+ }
+ let _ = responder.send(ClientboundPacket::InstanceList(ocs));
+ }
}
}