main.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. use clap::{Parser, Subcommand};
  2. use log::info;
  3. use serde_json::json;
  4. use simplelog::{ColorChoice, TermLogger, TerminalMode};
  5. use url::Url;
  6. use darkfi::{
  7. cli_desc,
  8. rpc::{client::RpcClient, jsonrpc::JsonRequest},
  9. util::cli::{get_log_config, get_log_level},
  10. Result,
  11. };
  12. #[derive(Parser)]
  13. #[clap(name = "fu", about = cli_desc!(), version)]
  14. #[clap(arg_required_else_help(true))]
  15. struct Args {
  16. #[clap(short, parse(from_occurrences))]
  17. /// Increase verbosity (-vvv supported)
  18. verbose: u8,
  19. #[clap(short, long, default_value = "tcp://127.0.0.1:13336")]
  20. /// fud JSON-RPC endpoint
  21. endpoint: Url,
  22. #[clap(subcommand)]
  23. command: Subcmd,
  24. }
  25. #[derive(Subcommand)]
  26. enum Subcmd {
  27. /// List fud folder contents
  28. List,
  29. /// Sync fud folder contents and signal network for record changes
  30. Sync,
  31. /// Retrieve provided file name from the fud network
  32. Get {
  33. #[clap(short, long)]
  34. /// File name
  35. file: String,
  36. },
  37. }
  38. struct Fu {
  39. pub rpc_client: RpcClient,
  40. }
  41. impl Fu {
  42. async fn close_connection(&self) -> Result<()> {
  43. self.rpc_client.close().await
  44. }
  45. async fn list(&self) -> Result<()> {
  46. let req = JsonRequest::new("list", json!([]));
  47. let rep = self.rpc_client.request(req).await?;
  48. // Extract response
  49. let content = rep[0].as_array().unwrap();
  50. let new = rep[1].as_array().unwrap();
  51. let deleted = rep[2].as_array().unwrap();
  52. // Print info
  53. info!("----------Content-------------");
  54. if content.is_empty() {
  55. info!("No file records exists in DHT.");
  56. } else {
  57. for name in content {
  58. info!("\t{}", name.as_str().unwrap());
  59. }
  60. }
  61. info!("------------------------------");
  62. info!("----------New files-----------");
  63. if new.is_empty() {
  64. info!("No new files to import.");
  65. } else {
  66. for name in new {
  67. info!("\t{}", name.as_str().unwrap());
  68. }
  69. }
  70. info!("------------------------------");
  71. info!("----------Removed keys--------");
  72. if deleted.is_empty() {
  73. info!("No keys were removed.");
  74. } else {
  75. for key in deleted {
  76. info!("\t{}", key.as_str().unwrap());
  77. }
  78. }
  79. info!("------------------------------");
  80. Ok(())
  81. }
  82. async fn sync(&self) -> Result<()> {
  83. let req = JsonRequest::new("sync", json!([]));
  84. self.rpc_client.request(req).await?;
  85. info!("Daemon synced successfully!");
  86. Ok(())
  87. }
  88. async fn get(&self, file: String) -> Result<()> {
  89. let req = JsonRequest::new("get", json!([file]));
  90. let rep = self.rpc_client.request(req).await?;
  91. let path = rep.as_str().unwrap();
  92. info!("File waits you at: {}", path);
  93. Ok(())
  94. }
  95. }
  96. #[async_std::main]
  97. async fn main() -> Result<()> {
  98. let args = Args::parse();
  99. let log_level = get_log_level(args.verbose.into());
  100. let log_config = get_log_config();
  101. TermLogger::init(log_level, log_config, TerminalMode::Mixed, ColorChoice::Auto)?;
  102. let rpc_client = RpcClient::new(args.endpoint).await?;
  103. let fu = Fu { rpc_client };
  104. match args.command {
  105. Subcmd::List => fu.list().await,
  106. Subcmd::Sync => fu.sync().await,
  107. Subcmd::Get { file } => fu.get(file).await,
  108. }?;
  109. fu.close_connection().await
  110. }