103 lines
3 KiB
Rust
103 lines
3 KiB
Rust
use joecalsend::{Config, JoecalService, Listeners, error, models::Device};
|
|
use log::{error, info};
|
|
use ratatui::DefaultTerminal;
|
|
use tokio::{sync::mpsc::unbounded_channel, task::JoinSet};
|
|
use tui_logger::{LevelFilter, init_logger, set_env_filter_from_env};
|
|
|
|
mod app;
|
|
use app::{App, CurrentScreen};
|
|
|
|
fn main() -> error::Result<()> {
|
|
let device = Device::default();
|
|
|
|
if std::env::var("RUST_LOG").is_err() {
|
|
unsafe {
|
|
std::env::set_var("RUST_LOG", "joecalsend");
|
|
}
|
|
}
|
|
init_logger(LevelFilter::Debug).map_err(|e| std::io::Error::other(format!("{e}")))?;
|
|
set_env_filter_from_env(None);
|
|
|
|
let config = Config::default();
|
|
|
|
let mut terminal = ratatui::init();
|
|
let result = start_and_run(&mut terminal, config, device);
|
|
ratatui::restore();
|
|
|
|
result
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn start_and_run(
|
|
terminal: &mut DefaultTerminal,
|
|
config: Config,
|
|
device: Device,
|
|
) -> error::Result<()> {
|
|
let (event_tx, event_listener) = unbounded_channel();
|
|
|
|
let service = JoecalService::new(device, event_tx)
|
|
.await
|
|
.expect("Could not create JoecalService");
|
|
|
|
let mut app = App::new(service, event_listener);
|
|
|
|
let mut handles = JoinSet::new();
|
|
app.service.start(&config, &mut handles).await;
|
|
loop {
|
|
terminal.draw(|frame| app.draw(frame))?;
|
|
app.handle_events().await?;
|
|
|
|
if let Some(&top) = app.screen.last()
|
|
&& top == CurrentScreen::Stopping
|
|
{
|
|
app.service.stop().await;
|
|
break;
|
|
}
|
|
|
|
let peers = app.service.peers.lock().await;
|
|
app.peers.clear();
|
|
peers.iter().for_each(|(fingerprint, (addr, device))| {
|
|
let alias = device.alias.clone();
|
|
app.peers
|
|
.insert(addr.to_owned(), (alias, fingerprint.to_owned()));
|
|
});
|
|
|
|
let mut stale_uploads = Vec::with_capacity(app.uploads.len());
|
|
let now = chrono::Utc::now().timestamp_millis() as u64;
|
|
for (id, request) in app.uploads.iter() {
|
|
if request.tx.is_closed() || (now - id.timestamp()) > 60_000 {
|
|
stale_uploads.push(*id);
|
|
}
|
|
}
|
|
for id in stale_uploads {
|
|
app.uploads.remove(&id);
|
|
}
|
|
}
|
|
|
|
shutdown(&mut handles).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn shutdown(handles: &mut JoinSet<Listeners>) {
|
|
let mut alarm = tokio::time::interval(tokio::time::Duration::from_secs(5));
|
|
alarm.tick().await;
|
|
loop {
|
|
tokio::select! {
|
|
join_result = handles.join_next() => {
|
|
match join_result {
|
|
Some(handle) => match handle {
|
|
Ok(h) => info!("Stopped {h:?}"),
|
|
Err(e) => error!("Got error {e:?}"),
|
|
}
|
|
None => break,
|
|
}
|
|
}
|
|
_ = alarm.tick() => {
|
|
info!("Exit timeout reached, aborting all unjoined tasks");
|
|
handles.abort_all();
|
|
break;
|
|
},
|
|
}
|
|
}
|
|
}
|