diff options
Diffstat (limited to 'src/client.rs')
| -rw-r--r-- | src/client.rs | 156 |
1 files changed, 94 insertions, 62 deletions
diff --git a/src/client.rs b/src/client.rs index 835d69e..b6e93d6 100644 --- a/src/client.rs +++ b/src/client.rs | |||
| @@ -35,6 +35,7 @@ use nostr_sqlite::SQLiteDatabase; | |||
| 35 | 35 | ||
| 36 | use crate::{ | 36 | use crate::{ |
| 37 | config::get_dirs, | 37 | config::get_dirs, |
| 38 | login::get_logged_in_user_and_relays_from_cache, | ||
| 38 | repo_ref::{RepoRef, REPO_REF_KIND}, | 39 | repo_ref::{RepoRef, REPO_REF_KIND}, |
| 39 | sub_commands::{ | 40 | sub_commands::{ |
| 40 | list::status_kinds, | 41 | list::status_kinds, |
| @@ -77,7 +78,7 @@ pub trait Connect { | |||
| 77 | &self, | 78 | &self, |
| 78 | git_repo_path: &Path, | 79 | git_repo_path: &Path, |
| 79 | repo_coordinates: &HashSet<Coordinate>, | 80 | repo_coordinates: &HashSet<Coordinate>, |
| 80 | ) -> Result<FetchReport>; | 81 | ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)>; |
| 81 | async fn fetch_all_from_relay( | 82 | async fn fetch_all_from_relay( |
| 82 | &self, | 83 | &self, |
| 83 | git_repo_path: &Path, | 84 | git_repo_path: &Path, |
| @@ -287,8 +288,7 @@ impl Connect for Client { | |||
| 287 | &self, | 288 | &self, |
| 288 | git_repo_path: &Path, | 289 | git_repo_path: &Path, |
| 289 | repo_coordinates: &HashSet<Coordinate>, | 290 | repo_coordinates: &HashSet<Coordinate>, |
| 290 | ) -> Result<FetchReport> { | 291 | ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)> { |
| 291 | println!("fetching updates..."); | ||
| 292 | let fallback_relays = &self | 292 | let fallback_relays = &self |
| 293 | .fallback_relays | 293 | .fallback_relays |
| 294 | .iter() | 294 | .iter() |
| @@ -305,6 +305,23 @@ impl Connect for Client { | |||
| 305 | let mut relay_reports: Vec<Result<FetchReport>> = vec![]; | 305 | let mut relay_reports: Vec<Result<FetchReport>> = vec![]; |
| 306 | 306 | ||
| 307 | loop { | 307 | loop { |
| 308 | let relays = request | ||
| 309 | .relays | ||
| 310 | .union(&request.current_user_write_relays) | ||
| 311 | // don't look for events on blaster | ||
| 312 | .filter(|&r| !r.as_str().contains("nostr.mutinywallet.com")) | ||
| 313 | .cloned() | ||
| 314 | .collect::<HashSet<Url>>() | ||
| 315 | .difference(&processed_relays) | ||
| 316 | .cloned() | ||
| 317 | .collect::<HashSet<Url>>(); | ||
| 318 | if relays.is_empty() { | ||
| 319 | break; | ||
| 320 | } | ||
| 321 | let only_user_relays = request | ||
| 322 | .current_user_write_relays | ||
| 323 | .difference(&request.relays) | ||
| 324 | .collect::<HashSet<&Url>>(); | ||
| 308 | for relay in &request.relays { | 325 | for relay in &request.relays { |
| 309 | self.client | 326 | self.client |
| 310 | .add_relay(relay.as_str()) | 327 | .add_relay(relay.as_str()) |
| @@ -314,14 +331,26 @@ impl Connect for Client { | |||
| 314 | 331 | ||
| 315 | let dim = Style::new().color256(247); | 332 | let dim = Style::new().color256(247); |
| 316 | 333 | ||
| 317 | let futures: Vec<_> = request | 334 | let futures: Vec<_> = relays |
| 318 | .relays | ||
| 319 | .iter() | 335 | .iter() |
| 320 | // don't look for events on blaster | 336 | .map(|r| { |
| 321 | .filter(|r| !r.as_str().contains("nostr.mutinywallet.com")) | 337 | if only_user_relays.contains(r) { |
| 322 | .map(|r| FetchRequest { | 338 | // if user write relay isn't a repo relay, just filter for user profile |
| 323 | selected_relay: Some(r.clone()), | 339 | FetchRequest { |
| 324 | ..request.clone() | 340 | selected_relay: Some(r.to_owned()), |
| 341 | repo_coordinates: vec![], | ||
| 342 | proposals: HashSet::new(), | ||
| 343 | missing_contributor_profiles: HashSet::from_iter(vec![ | ||
| 344 | request.current_user.unwrap(), | ||
| 345 | ]), | ||
| 346 | ..request.clone() | ||
| 347 | } | ||
| 348 | } else { | ||
| 349 | FetchRequest { | ||
| 350 | selected_relay: Some(r.to_owned()), | ||
| 351 | ..request.clone() | ||
| 352 | } | ||
| 353 | } | ||
| 325 | }) | 354 | }) |
| 326 | .map(|request| async { | 355 | .map(|request| async { |
| 327 | let relay_column_width = request.relay_column_width; | 356 | let relay_column_width = request.relay_column_width; |
| @@ -381,31 +410,20 @@ impl Connect for Client { | |||
| 381 | { | 410 | { |
| 382 | relay_reports.push(report); | 411 | relay_reports.push(report); |
| 383 | } | 412 | } |
| 384 | 413 | processed_relays.extend(relays.clone()); | |
| 385 | for relay in &request.relays { | ||
| 386 | processed_relays.insert(relay.clone()); | ||
| 387 | } | ||
| 388 | 414 | ||
| 389 | if let Ok(repo_ref) = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await { | 415 | if let Ok(repo_ref) = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await { |
| 390 | request.relays = repo_ref | 416 | request.relays = repo_ref |
| 391 | .relays | 417 | .relays |
| 392 | .iter() | 418 | .iter() |
| 393 | .filter_map(|r| Url::parse(r).ok()) | 419 | .filter_map(|r| Url::parse(r).ok()) |
| 394 | .filter(|r| !processed_relays.contains(r)) | ||
| 395 | .collect(); | 420 | .collect(); |
| 396 | if request.relays.is_empty() { | ||
| 397 | break; | ||
| 398 | } | ||
| 399 | } | 421 | } |
| 422 | let (_, current_user_write_relays) = | ||
| 423 | get_logged_in_user_and_relays_from_cache(git_repo_path).await?; | ||
| 424 | request.current_user_write_relays = current_user_write_relays; | ||
| 400 | } | 425 | } |
| 401 | let report = consolidate_fetch_reports(relay_reports); | 426 | Ok((relay_reports, progress_reporter)) |
| 402 | |||
| 403 | if report.to_string().is_empty() { | ||
| 404 | println!("no updates"); | ||
| 405 | } else { | ||
| 406 | println!("updates: {report}"); | ||
| 407 | } | ||
| 408 | Ok(report) | ||
| 409 | } | 427 | } |
| 410 | 428 | ||
| 411 | async fn fetch_all_from_relay( | 429 | async fn fetch_all_from_relay( |
| @@ -420,6 +438,9 @@ impl Connect for Client { | |||
| 420 | } | 438 | } |
| 421 | let mut fresh_proposal_roots = request.proposals.clone(); | 439 | let mut fresh_proposal_roots = request.proposals.clone(); |
| 422 | let mut fresh_contributors = request.missing_contributor_profiles.clone(); | 440 | let mut fresh_contributors = request.missing_contributor_profiles.clone(); |
| 441 | if let Some(user) = request.current_user { | ||
| 442 | fresh_contributors.insert(user); | ||
| 443 | } | ||
| 423 | 444 | ||
| 424 | let mut report = FetchReport::default(); | 445 | let mut report = FetchReport::default(); |
| 425 | 446 | ||
| @@ -486,9 +507,9 @@ impl Connect for Client { | |||
| 486 | "{: <relay_column_width$} {}", | 507 | "{: <relay_column_width$} {}", |
| 487 | relay_url, | 508 | relay_url, |
| 488 | if report.to_string().is_empty() { | 509 | if report.to_string().is_empty() { |
| 489 | "no updates".to_string() | 510 | "no new events".to_string() |
| 490 | } else { | 511 | } else { |
| 491 | format!("updates: {report}") | 512 | format!("new events: {report}") |
| 492 | }, | 513 | }, |
| 493 | )) | 514 | )) |
| 494 | .to_string(), | 515 | .to_string(), |
| @@ -761,37 +782,6 @@ async fn create_relays_request( | |||
| 761 | ) -> Result<FetchRequest> { | 782 | ) -> Result<FetchRequest> { |
| 762 | let repo_ref = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await; | 783 | let repo_ref = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await; |
| 763 | 784 | ||
| 764 | let relays = { | ||
| 765 | let mut relays = fallback_relays; | ||
| 766 | if let Ok(repo_ref) = &repo_ref { | ||
| 767 | for r in &repo_ref.relays { | ||
| 768 | if let Ok(url) = Url::parse(r) { | ||
| 769 | relays.insert(url); | ||
| 770 | } | ||
| 771 | } | ||
| 772 | } | ||
| 773 | relays | ||
| 774 | }; | ||
| 775 | |||
| 776 | let relay_column_width = relays | ||
| 777 | .iter() | ||
| 778 | .reduce(|a, r| { | ||
| 779 | if r.to_string() | ||
| 780 | .chars() | ||
| 781 | .count() | ||
| 782 | .gt(&a.to_string().chars().count()) | ||
| 783 | { | ||
| 784 | r | ||
| 785 | } else { | ||
| 786 | a | ||
| 787 | } | ||
| 788 | }) | ||
| 789 | .unwrap() | ||
| 790 | .to_string() | ||
| 791 | .chars() | ||
| 792 | .count() | ||
| 793 | + 2; | ||
| 794 | |||
| 795 | let repo_coordinates = if let Ok(repo_ref) = &repo_ref { | 785 | let repo_coordinates = if let Ok(repo_ref) = &repo_ref { |
| 796 | repo_ref.coordinates() | 786 | repo_ref.coordinates() |
| 797 | } else { | 787 | } else { |
| @@ -802,7 +792,7 @@ async fn create_relays_request( | |||
| 802 | let mut missing_contributor_profiles: HashSet<PublicKey> = HashSet::new(); | 792 | let mut missing_contributor_profiles: HashSet<PublicKey> = HashSet::new(); |
| 803 | let mut contributors: HashSet<PublicKey> = HashSet::new(); | 793 | let mut contributors: HashSet<PublicKey> = HashSet::new(); |
| 804 | 794 | ||
| 805 | { | 795 | if !repo_coordinates.is_empty() { |
| 806 | if let Ok(repo_ref) = &repo_ref { | 796 | if let Ok(repo_ref) = &repo_ref { |
| 807 | for m in &repo_ref.maintainers { | 797 | for m in &repo_ref.maintainers { |
| 808 | contributors.insert(m.to_owned()); | 798 | contributors.insert(m.to_owned()); |
| @@ -848,6 +838,12 @@ async fn create_relays_request( | |||
| 848 | } | 838 | } |
| 849 | } | 839 | } |
| 850 | 840 | ||
| 841 | let (current_user, current_user_write_relays) = | ||
| 842 | get_logged_in_user_and_relays_from_cache(git_repo_path).await?; | ||
| 843 | if let Some(current_user) = current_user { | ||
| 844 | missing_contributor_profiles.insert(current_user); | ||
| 845 | } | ||
| 846 | |||
| 851 | let existing_events: HashSet<EventId> = { | 847 | let existing_events: HashSet<EventId> = { |
| 852 | let mut existing_events: HashSet<EventId> = HashSet::new(); | 848 | let mut existing_events: HashSet<EventId> = HashSet::new(); |
| 853 | for filter in | 849 | for filter in |
| @@ -863,6 +859,38 @@ async fn create_relays_request( | |||
| 863 | } | 859 | } |
| 864 | existing_events | 860 | existing_events |
| 865 | }; | 861 | }; |
| 862 | |||
| 863 | let relays = { | ||
| 864 | let mut relays = fallback_relays; | ||
| 865 | if let Ok(repo_ref) = &repo_ref { | ||
| 866 | for r in &repo_ref.relays { | ||
| 867 | if let Ok(url) = Url::parse(r) { | ||
| 868 | relays.insert(url); | ||
| 869 | } | ||
| 870 | } | ||
| 871 | } | ||
| 872 | relays | ||
| 873 | }; | ||
| 874 | |||
| 875 | let relay_column_width = relays | ||
| 876 | .union(¤t_user_write_relays) | ||
| 877 | .reduce(|a, r| { | ||
| 878 | if r.to_string() | ||
| 879 | .chars() | ||
| 880 | .count() | ||
| 881 | .gt(&a.to_string().chars().count()) | ||
| 882 | { | ||
| 883 | r | ||
| 884 | } else { | ||
| 885 | a | ||
| 886 | } | ||
| 887 | }) | ||
| 888 | .unwrap() | ||
| 889 | .to_string() | ||
| 890 | .chars() | ||
| 891 | .count() | ||
| 892 | + 2; | ||
| 893 | |||
| 866 | Ok(FetchRequest { | 894 | Ok(FetchRequest { |
| 867 | selected_relay: None, | 895 | selected_relay: None, |
| 868 | relays, | 896 | relays, |
| @@ -876,6 +904,8 @@ async fn create_relays_request( | |||
| 876 | contributors, | 904 | contributors, |
| 877 | missing_contributor_profiles, | 905 | missing_contributor_profiles, |
| 878 | existing_events, | 906 | existing_events, |
| 907 | current_user, | ||
| 908 | current_user_write_relays, | ||
| 879 | }) | 909 | }) |
| 880 | } | 910 | } |
| 881 | 911 | ||
| @@ -972,7 +1002,7 @@ async fn process_fetched_events( | |||
| 972 | Ok(()) | 1002 | Ok(()) |
| 973 | } | 1003 | } |
| 974 | 1004 | ||
| 975 | fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchReport { | 1005 | pub fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchReport { |
| 976 | let mut report = FetchReport::default(); | 1006 | let mut report = FetchReport::default(); |
| 977 | for relay_report in reports.into_iter().flatten() { | 1007 | for relay_report in reports.into_iter().flatten() { |
| 978 | for c in relay_report.repo_coordinates { | 1008 | for c in relay_report.repo_coordinates { |
| @@ -1136,7 +1166,7 @@ impl Display for FetchReport { | |||
| 1136 | } | 1166 | } |
| 1137 | if !self.contributor_profiles.is_empty() { | 1167 | if !self.contributor_profiles.is_empty() { |
| 1138 | display_items.push(format!( | 1168 | display_items.push(format!( |
| 1139 | "{} contributor profile{}", | 1169 | "{} user profile{}", |
| 1140 | self.contributor_profiles.len(), | 1170 | self.contributor_profiles.len(), |
| 1141 | if self.contributor_profiles.len() > 1 { | 1171 | if self.contributor_profiles.len() > 1 { |
| 1142 | "s" | 1172 | "s" |
| @@ -1159,4 +1189,6 @@ pub struct FetchRequest { | |||
| 1159 | contributors: HashSet<PublicKey>, | 1189 | contributors: HashSet<PublicKey>, |
| 1160 | missing_contributor_profiles: HashSet<PublicKey>, | 1190 | missing_contributor_profiles: HashSet<PublicKey>, |
| 1161 | existing_events: HashSet<EventId>, | 1191 | existing_events: HashSet<EventId>, |
| 1192 | current_user: Option<PublicKey>, | ||
| 1193 | current_user_write_relays: HashSet<Url>, | ||
| 1162 | } | 1194 | } |