main.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. use std::process::exit;
  2. use clap::{Parser, Subcommand};
  3. use log::error;
  4. use simplelog::{ColorChoice, TermLogger, TerminalMode};
  5. use url::Url;
  6. use darkfi::{
  7. rpc::client::RpcClient,
  8. util::cli::{get_log_config, get_log_level},
  9. Error, Result,
  10. };
  11. mod filter;
  12. mod primitives;
  13. mod rpc;
  14. mod util;
  15. mod view;
  16. use primitives::{task_from_cli, TaskEvent};
  17. use util::{desc_in_editor, due_as_timestamp};
  18. use view::{comments_as_string, print_task_info, print_task_list};
  19. #[derive(Parser)]
  20. #[clap(name = "tau", version)]
  21. struct Args {
  22. #[clap(short, parse(from_occurrences))]
  23. /// Increase verbosity (-vvv supported)
  24. verbose: u8,
  25. #[clap(short, long, default_value = "tcp://127.0.0.1:11055")]
  26. /// taud JSON-RPC endpoint
  27. endpoint: Url,
  28. /// Search filters (zero or more)
  29. filters: Vec<String>,
  30. #[clap(subcommand)]
  31. command: Option<TauSubcommand>,
  32. }
  33. #[derive(Subcommand)]
  34. enum TauSubcommand {
  35. /// Add a new task
  36. Add { values: Vec<String> },
  37. /// Update/Edit an existing task by ID
  38. Update {
  39. /// Task ID
  40. task_id: u64,
  41. /// Values (ex: project:blockchain)
  42. values: Vec<String>,
  43. },
  44. /// Set or Get task state
  45. State {
  46. /// Task ID
  47. task_id: u64,
  48. /// Set task state
  49. state: Option<String>,
  50. },
  51. /// Set or Get comment for a task
  52. Comment {
  53. /// Task ID
  54. task_id: u64,
  55. /// Comment content
  56. content: Option<String>,
  57. },
  58. /// Get task info by ID
  59. Info { task_id: u64 },
  60. }
  61. pub struct Tau {
  62. pub rpc_client: RpcClient,
  63. }
  64. #[async_std::main]
  65. async fn main() -> Result<()> {
  66. let args = Args::parse();
  67. let log_level = get_log_level(args.verbose.into());
  68. let log_config = get_log_config();
  69. TermLogger::init(log_level, log_config, TerminalMode::Mixed, ColorChoice::Auto)?;
  70. let rpc_client = RpcClient::new(args.endpoint).await?;
  71. let tau = Tau { rpc_client };
  72. // Allowed states for a task
  73. let states = ["stop", "open", "pause"];
  74. // Parse subcommands
  75. match args.command {
  76. Some(sc) => match sc {
  77. TauSubcommand::Add { values } => {
  78. let mut task = task_from_cli(values)?;
  79. if task.title.is_empty() {
  80. error!("Please provide a title for the task.");
  81. exit(1);
  82. };
  83. if task.desc.is_none() {
  84. task.desc = desc_in_editor()?;
  85. };
  86. return tau.add(task).await
  87. }
  88. TauSubcommand::Update { task_id, values } => {
  89. let task = task_from_cli(values)?;
  90. tau.update(task_id, task).await
  91. }
  92. TauSubcommand::State { task_id, state } => match state {
  93. Some(state) => {
  94. let state = state.trim().to_lowercase();
  95. if states.contains(&state.as_str()) {
  96. tau.set_state(task_id, &state).await
  97. } else {
  98. error!(
  99. "Task state can only be one of the following {}: {:?}",
  100. states.len(),
  101. states
  102. );
  103. return Err(Error::OperationFailed)
  104. }
  105. }
  106. None => {
  107. let task = tau.get_task_by_id(task_id).await?;
  108. let state = &task.events.last().unwrap_or(&TaskEvent::default()).action.clone();
  109. println!("Task {}: {}", task_id, state);
  110. Ok(())
  111. }
  112. },
  113. TauSubcommand::Comment { task_id, content } => match content {
  114. Some(content) => tau.set_comment(task_id, content.trim()).await,
  115. None => {
  116. let task = tau.get_task_by_id(task_id).await?;
  117. let comments = comments_as_string(task.comments);
  118. println!("Comments {}:\n{}", task_id, comments);
  119. Ok(())
  120. }
  121. },
  122. TauSubcommand::Info { task_id } => {
  123. let task = tau.get_task_by_id(task_id).await?;
  124. print_task_info(task)
  125. }
  126. },
  127. None => {
  128. let task_ids = tau.get_ids().await?;
  129. let mut tasks = vec![];
  130. for id in task_ids {
  131. tasks.push(tau.get_task_by_id(id).await?);
  132. }
  133. print_task_list(tasks, args.filters)?;
  134. Ok(())
  135. }
  136. }?;
  137. tau.close_connection().await
  138. }