diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-02-14 10:51:00 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-02-14 10:51:00 +0000 |
| commit | fed60687b2438b6bd19ee8f5c854ddc53cad0c9b (patch) | |
| tree | 99d990e77de400432f2d2ae3235400b94b2bcdfa /src | |
| parent | 62d7f2fb26f2843fa8f7ff8b988bac14e5f756e2 (diff) | |
feat: improve fetch events reporting
Improve how progress is reported in the UI when fetching events
Diffstat (limited to 'src')
| -rw-r--r-- | src/client.rs | 79 |
1 files changed, 67 insertions, 12 deletions
diff --git a/src/client.rs b/src/client.rs index 1b42e8c..97cb856 100644 --- a/src/client.rs +++ b/src/client.rs | |||
| @@ -10,9 +10,12 @@ | |||
| 10 | // which is currently in nightly. alternatively we can use nightly as it looks | 10 | // which is currently in nightly. alternatively we can use nightly as it looks |
| 11 | // certain that the implementation is going to make it to stable but we don't | 11 | // certain that the implementation is going to make it to stable but we don't |
| 12 | // want to inadvertlty use other features of nightly that might be removed. | 12 | // want to inadvertlty use other features of nightly that might be removed. |
| 13 | use std::time::Duration; | ||
| 14 | |||
| 13 | use anyhow::{Context, Result}; | 15 | use anyhow::{Context, Result}; |
| 14 | use async_trait::async_trait; | 16 | use async_trait::async_trait; |
| 15 | use futures::stream::{self, StreamExt}; | 17 | use futures::stream::{self, StreamExt}; |
| 18 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; | ||
| 16 | #[cfg(test)] | 19 | #[cfg(test)] |
| 17 | use mockall::*; | 20 | use mockall::*; |
| 18 | use nostr::Event; | 21 | use nostr::Event; |
| @@ -126,6 +129,29 @@ impl Connect for Client { | |||
| 126 | .context("cannot add relay")?; | 129 | .context("cannot add relay")?; |
| 127 | } | 130 | } |
| 128 | 131 | ||
| 132 | let m = MultiProgress::new(); | ||
| 133 | let pb_style = ProgressStyle::with_template(" {spinner} {prefix} {msg}")?; | ||
| 134 | let pb_after_style = |succeed| { | ||
| 135 | ProgressStyle::with_template( | ||
| 136 | format!( | ||
| 137 | " {} {}", | ||
| 138 | if succeed { | ||
| 139 | console::style("✔".to_string()) | ||
| 140 | .for_stderr() | ||
| 141 | .green() | ||
| 142 | .to_string() | ||
| 143 | } else { | ||
| 144 | console::style("✘".to_string()) | ||
| 145 | .for_stderr() | ||
| 146 | .red() | ||
| 147 | .to_string() | ||
| 148 | }, | ||
| 149 | "{prefix} {msg}", | ||
| 150 | ) | ||
| 151 | .as_str(), | ||
| 152 | ) | ||
| 153 | }; | ||
| 154 | |||
| 129 | let relays_map = self.client.relays().await; | 155 | let relays_map = self.client.relays().await; |
| 130 | 156 | ||
| 131 | let futures: Vec<_> = relays | 157 | let futures: Vec<_> = relays |
| @@ -140,14 +166,45 @@ impl Connect for Client { | |||
| 140 | ) | 166 | ) |
| 141 | }) | 167 | }) |
| 142 | .map(|(relay, filters)| async { | 168 | .map(|(relay, filters)| async { |
| 143 | match get_events_of(relay, filters).await { | 169 | let pb = if std::env::var("NGITTEST").is_err() { |
| 170 | let pb = m.add( | ||
| 171 | ProgressBar::new(1) | ||
| 172 | .with_prefix(format!("{: <11}{}", "connecting", relay.url())) | ||
| 173 | .with_style(pb_style.clone()), | ||
| 174 | ); | ||
| 175 | pb.enable_steady_tick(Duration::from_millis(300)); | ||
| 176 | Some(pb) | ||
| 177 | } else { | ||
| 178 | None | ||
| 179 | }; | ||
| 180 | match get_events_of(relay, filters, &pb).await { | ||
| 144 | Err(error) => { | 181 | Err(error) => { |
| 145 | if std::env::var("NGITTEST").is_err() { | 182 | if let Some(pb) = pb { |
| 146 | println!("{} {}", error, relay.url()); | 183 | pb.set_style(pb_after_style(false)?); |
| 184 | pb.set_prefix(format!("{: <11}{}", "error", relay.url())); | ||
| 185 | pb.finish_with_message( | ||
| 186 | console::style( | ||
| 187 | error.to_string().replace("relay pool error:", "error:"), | ||
| 188 | ) | ||
| 189 | .for_stderr() | ||
| 190 | .red() | ||
| 191 | .to_string(), | ||
| 192 | ); | ||
| 147 | } | 193 | } |
| 148 | Err(error) | 194 | Err(error) |
| 149 | } | 195 | } |
| 150 | res => res, | 196 | Ok(res) => { |
| 197 | if let Some(pb) = pb { | ||
| 198 | pb.set_style(pb_after_style(true)?); | ||
| 199 | pb.set_prefix(format!( | ||
| 200 | "{: <11}{}", | ||
| 201 | format!("{} events", res.len()), | ||
| 202 | relay.url() | ||
| 203 | )); | ||
| 204 | pb.finish_with_message(""); | ||
| 205 | } | ||
| 206 | Ok(res) | ||
| 207 | } | ||
| 151 | } | 208 | } |
| 152 | }) | 209 | }) |
| 153 | .collect(); | 210 | .collect(); |
| @@ -161,13 +218,15 @@ impl Connect for Client { | |||
| 161 | async fn get_events_of( | 218 | async fn get_events_of( |
| 162 | relay: &nostr_sdk::Relay, | 219 | relay: &nostr_sdk::Relay, |
| 163 | filters: Vec<nostr::Filter>, | 220 | filters: Vec<nostr::Filter>, |
| 221 | pb: &Option<ProgressBar>, | ||
| 164 | ) -> Result<Vec<Event>> { | 222 | ) -> Result<Vec<Event>> { |
| 165 | if std::env::var("NGITTEST").is_err() { | ||
| 166 | println!("fetching from {}", relay.url()); | ||
| 167 | } | ||
| 168 | if !relay.is_connected().await { | 223 | if !relay.is_connected().await { |
| 169 | relay.connect(None).await; | 224 | relay.connect(None).await; |
| 170 | } | 225 | } |
| 226 | |||
| 227 | if let Some(pb) = pb { | ||
| 228 | pb.set_prefix(format!("connected {}", relay.url())); | ||
| 229 | } | ||
| 171 | let events = relay | 230 | let events = relay |
| 172 | .get_events_of( | 231 | .get_events_of( |
| 173 | filters, | 232 | filters, |
| @@ -175,11 +234,7 @@ async fn get_events_of( | |||
| 175 | std::time::Duration::from_secs(10), | 234 | std::time::Duration::from_secs(10), |
| 176 | nostr_sdk::FilterOptions::ExitOnEOSE, | 235 | nostr_sdk::FilterOptions::ExitOnEOSE, |
| 177 | ) | 236 | ) |
| 178 | .await | 237 | .await?; |
| 179 | .context("failed to get events from relay")?; | ||
| 180 | if std::env::var("NGITTEST").is_err() { | ||
| 181 | println!("fetched {} events from {}", events.len(), relay.url()); | ||
| 182 | } | ||
| 183 | Ok(events) | 238 | Ok(events) |
| 184 | } | 239 | } |
| 185 | 240 | ||