diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-07-17 10:53:20 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-07-17 10:53:20 +0100 |
| commit | 43a445963968dac7da190b56f7c89ac0ff1f6abd (patch) | |
| tree | 3c58f17c53de3f6ccc888323d677da12402a7891 /src/client.rs | |
| parent | 65d5daf6e42683ef116369b4f6a0f99d6971667b (diff) | |
feat(login): use fetch to get user profile
fetch automatically gets updates to logged in user profile / relays
fetching without specifying repo pointers will just fetch user
profiles so that can be used during login, if user profile isn't
in cache
login now uses fetch
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 | } |