main.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. use std::{fs::File, io, io::Read};
  2. use async_std::sync::Arc;
  3. use clap::Parser;
  4. use easy_parallel::Parallel;
  5. use log::info;
  6. use simplelog::*;
  7. use smol::Executor;
  8. use termion::{async_stdin, event::Key, input::TermRead, raw::IntoRawMode};
  9. use tui::{
  10. backend::{Backend, TermionBackend},
  11. Terminal,
  12. };
  13. use darkfi::util::{
  14. async_util,
  15. cli::{get_log_config, get_log_level, spawn_config, Config},
  16. path::{expand_path, get_config_path},
  17. };
  18. pub mod config;
  19. pub mod error;
  20. pub mod model;
  21. pub mod options;
  22. pub mod parser;
  23. pub mod rpc;
  24. pub mod util;
  25. pub mod view;
  26. use crate::{
  27. config::{DnvConfig, CONFIG_FILE, CONFIG_FILE_CONTENTS},
  28. error::{DnetViewError, DnetViewResult},
  29. model::Model,
  30. options::Args,
  31. parser::DataParser,
  32. view::View,
  33. };
  34. struct DnetView {
  35. model: Arc<Model>,
  36. view: View,
  37. }
  38. impl DnetView {
  39. fn new(model: Arc<Model>, view: View) -> Self {
  40. Self { model, view }
  41. }
  42. async fn render_view<B: Backend>(&mut self, terminal: &mut Terminal<B>) -> DnetViewResult<()> {
  43. let mut asi = async_stdin();
  44. terminal.clear()?;
  45. self.view.id_menu.state.select(Some(0));
  46. self.view.msg_list.state.select(Some(0));
  47. loop {
  48. self.view.update(
  49. self.model.msg_map.lock().await.clone(),
  50. self.model.selectables.lock().await.clone(),
  51. //self.model.selectables2.lock().await.clone(),
  52. );
  53. //debug!(target: "dnetview::render_view()", "ID MENU: {:?}", self.view.id_menu.ids);
  54. //debug!(target: "dnetview::render_view()", "SELECTABLES ID LIST: {:?}", self.model.selectables.lock().await.keys());
  55. let mut err: Option<DnetViewError> = None;
  56. terminal.draw(|f| match self.view.render(f) {
  57. Ok(()) => {}
  58. Err(e) => {
  59. err = Some(e);
  60. }
  61. })?;
  62. if let Some(e) = err {
  63. return Err(e)
  64. }
  65. self.view.msg_list.scroll()?;
  66. for k in asi.by_ref().keys() {
  67. match k.unwrap() {
  68. Key::Char('q') => {
  69. terminal.clear()?;
  70. return Ok(())
  71. }
  72. Key::Char('j') => {
  73. self.view.id_menu.next();
  74. }
  75. Key::Char('k') => {
  76. self.view.id_menu.previous();
  77. }
  78. Key::Char('u') => {
  79. // TODO
  80. //view.msg_list.next();
  81. }
  82. Key::Char('d') => {
  83. // TODO
  84. //view.msg_list.previous();
  85. }
  86. _ => (),
  87. }
  88. }
  89. async_util::msleep(100).await;
  90. }
  91. }
  92. }
  93. #[async_std::main]
  94. async fn main() -> DnetViewResult<()> {
  95. //debug!(target: "dnetview", "main() START");
  96. let args = Args::parse();
  97. let log_level = get_log_level(args.verbose.into());
  98. let log_config = get_log_config();
  99. let log_file_path = expand_path(&args.log_path)?;
  100. if let Some(parent) = log_file_path.parent() {
  101. std::fs::create_dir_all(parent)?;
  102. };
  103. let file = File::create(log_file_path)?;
  104. WriteLogger::init(log_level, log_config, file)?;
  105. info!("Log level: {}", log_level);
  106. let config_path = get_config_path(args.config, CONFIG_FILE)?;
  107. spawn_config(&config_path, CONFIG_FILE_CONTENTS)?;
  108. let config = Config::<DnvConfig>::load(config_path)?;
  109. let stdout = io::stdout().into_raw_mode()?;
  110. let backend = TermionBackend::new(stdout);
  111. let mut terminal = Terminal::new(backend)?;
  112. terminal.clear()?;
  113. let model = Model::new();
  114. let view = View::new();
  115. let ex = Arc::new(Executor::new());
  116. let ex2 = ex.clone();
  117. let mut dnetview = DnetView::new(model.clone(), view);
  118. let parser = DataParser::new(model, config);
  119. let nthreads = num_cpus::get();
  120. let (signal, shutdown) = async_channel::unbounded::<()>();
  121. let (_, result) = Parallel::new()
  122. .each(0..nthreads, |_| smol::future::block_on(ex.run(shutdown.recv())))
  123. .finish(|| {
  124. smol::future::block_on(async move {
  125. parser.start_connect_slots(ex2).await?;
  126. dnetview.render_view(&mut terminal).await?;
  127. drop(signal);
  128. Ok(())
  129. })
  130. });
  131. result
  132. }