This commit is contained in:
JMARyA 2024-06-06 10:41:07 +02:00
parent 25f4d19ca7
commit 50c76560c0
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
6 changed files with 105 additions and 17 deletions

View file

@ -9,7 +9,7 @@ chrono = "0.4.38"
clap = { version = "4.5.4", features = ["cargo"] }
crossterm = "0.27.0"
moka = { version = "0.12.7", features = ["sync"] }
reqwest = { version = "0.12.4", features = ["blocking"] }
reqwest = { version = "0.12.4", features = ["blocking", "json"] }
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"
toml = "0.8.14"

View file

@ -98,6 +98,32 @@ impl VikunjaAPI {
}
}
fn put_request(&self, path: &str, data: serde_json::Value) -> String {
let client = reqwest::blocking::Client::new();
client
.put(&format!("{}/api/v1{}", self.host, path))
.header("Authorization", format!("Bearer {}", self.token))
.json(&data)
.send()
.unwrap()
.text()
.unwrap()
}
fn post_request(&self, path: &str, data: serde_json::Value) -> String {
let client = reqwest::blocking::Client::new();
client
.post(&format!("{}/api/v1{}", self.host, path))
.header("Authorization", format!("Bearer {}", self.token))
.json(&data)
.send()
.unwrap()
.text()
.unwrap()
}
// projects
pub fn get_project_name_from_id(&self, id: isize) -> String {
@ -127,4 +153,32 @@ impl VikunjaAPI {
let resp = self.get_request(&format!("/tasks/{id}"));
serde_json::from_str(&resp).unwrap()
}
pub fn new_task(&self, title: &str, project: ProjectID) -> Task {
let id = project.0;
let data = serde_json::json!({
"title": title
});
// description
// due_date
// end_date
// is_favorite
// labels
// priority
let resp = self.put_request(&format!("/projects/{id}/tasks"), data);
serde_json::from_str(&resp).unwrap()
}
pub fn done_task(&self, task_id: isize) -> Task {
let resp = self.post_request(
&format!("/tasks/{task_id}"),
serde_json::json!({
"done": true
}),
);
serde_json::from_str(&resp).unwrap()
}
}

View file

@ -4,7 +4,7 @@ use super::{Label, User};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Task {
pub id: usize,
pub id: isize,
pub title: String,
pub description: String,
pub done: bool,

View file

@ -18,5 +18,22 @@ pub fn get_args() -> clap::ArgMatches {
.about("Commands about projects")
.subcommand(command!().name("ls").about("List projects")),
)
.subcommand(
command!()
.name("new")
.about("Create a new task")
.arg(arg!([title] "Task title").required(true))
.arg(
arg!(-p --project <project> "Project to add task to")
.required(false)
.default_value("Inbox"),
),
)
.subcommand(
command!()
.name("done")
.about("Mark task as done")
.arg(arg!([task_id] "Task ID").required(true)),
)
.get_matches()
}

View file

@ -3,7 +3,7 @@ mod args;
mod config;
mod ui;
use api::VikunjaAPI;
use api::{ProjectID, VikunjaAPI};
fn main() {
let config: config::Config =
@ -24,6 +24,17 @@ fn main() {
ui::project::list_projects(&api);
}
},
Some(("new", new_task_arg)) => {
let title: &String = new_task_arg.get_one("title").unwrap();
let project: &String = new_task_arg.get_one("project").unwrap();
let project = ProjectID::parse(&api, project).unwrap();
let task = api.new_task(title.as_str(), project);
ui::task::print_task_info(task.id, &api);
}
Some(("done", done_args)) => {
let task_id: &String = done_args.get_one("task_id").unwrap();
api.done_task(task_id.parse().unwrap());
}
_ => {
let done = arg.get_flag("done");
let fav = arg.get_flag("favorite");

View file

@ -57,24 +57,29 @@ pub fn print_current_tasks(api: &VikunjaAPI, done: bool, fav: bool, project: Opt
pub fn print_task_info(task_id: isize, api: &VikunjaAPI) {
let task = api.get_task(task_id);
let done_indicator = if task.done {
format!("{}", parse_datetime(&task.done_at).unwrap())
} else {
String::new()
};
let fav_indicator = if task.is_favorite { "" } else { "" };
println!(
"{}{}'{}' [{}] [{}]",
done_indicator,
fav_indicator,
task.title,
task.id,
api.get_project_name_from_id(task.project_id)
if task.done {
print_color(
crossterm::style::Color::Green,
&format!("{}", time_since(parse_datetime(&task.done_at).unwrap())),
);
}
if task.is_favorite {
print!("");
}
print_color(crossterm::style::Color::Blue, &task.title);
print_color(crossterm::style::Color::Yellow, &format!(" ({})", task.id));
print_color(
crossterm::style::Color::DarkRed,
&format!(" [{}]\n", api.get_project_name_from_id(task.project_id)),
);
println!("Created by {}", task.created_by.username);
if let Some(due_date) = parse_datetime(&task.due_date) {
// todo : color if overdue
println!("Due at {due_date}");
}
@ -90,6 +95,7 @@ pub fn print_task_info(task_id: isize, api: &VikunjaAPI) {
}
if let Some(labels) = task.labels {
// todo : labels and color
println!("Labels: {}", labels.first().unwrap().title);
}
@ -99,7 +105,7 @@ pub fn print_task_info(task_id: isize, api: &VikunjaAPI) {
time_since(parse_datetime(&task.updated).unwrap())
);
if task.description != "<p></p>" {
if task.description != "<p></p>" && !task.description.is_empty() {
println!("---\n{}", task.description);
}