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 | |
| 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')
| -rw-r--r-- | src/client.rs | 156 | ||||
| -rw-r--r-- | src/git.rs | 8 | ||||
| -rw-r--r-- | src/login.rs | 124 | ||||
| -rw-r--r-- | src/sub_commands/fetch.rs | 11 |
4 files changed, 165 insertions, 134 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 | } |
| @@ -1,6 +1,7 @@ | |||
| 1 | #[cfg(test)] | 1 | use std::{ |
| 2 | use std::path::PathBuf; | 2 | env::current_dir, |
| 3 | use std::{env::current_dir, path::Path}; | 3 | path::{Path, PathBuf}, |
| 4 | }; | ||
| 4 | 5 | ||
| 5 | use anyhow::{bail, Context, Result}; | 6 | use anyhow::{bail, Context, Result}; |
| 6 | use git2::{DiffOptions, Oid, Revwalk}; | 7 | use git2::{DiffOptions, Oid, Revwalk}; |
| @@ -18,7 +19,6 @@ impl Repo { | |||
| 18 | git_repo: git2::Repository::discover(current_dir()?)?, | 19 | git_repo: git2::Repository::discover(current_dir()?)?, |
| 19 | }) | 20 | }) |
| 20 | } | 21 | } |
| 21 | #[cfg(test)] | ||
| 22 | pub fn from_path(path: &PathBuf) -> Result<Self> { | 22 | pub fn from_path(path: &PathBuf) -> Result<Self> { |
| 23 | Ok(Self { | 23 | Ok(Self { |
| 24 | git_repo: git2::Repository::open(path)?, | 24 | git_repo: git2::Repository::open(path)?, |
diff --git a/src/login.rs b/src/login.rs index d580969..0a20a90 100644 --- a/src/login.rs +++ b/src/login.rs | |||
| @@ -1,17 +1,14 @@ | |||
| 1 | use std::{fs::create_dir_all, str::FromStr, time::Duration}; | 1 | use std::{collections::HashSet, path::Path, str::FromStr, time::Duration}; |
| 2 | 2 | ||
| 3 | use anyhow::{bail, Context, Result}; | 3 | use anyhow::{bail, Context, Result}; |
| 4 | use nostr::{ | 4 | use nostr::{ |
| 5 | nips::{nip05::get_nip46, nip46::NostrConnectURI}, | 5 | nips::{nip05::get_nip46, nip46::NostrConnectURI}, |
| 6 | PublicKey, | 6 | PublicKey, |
| 7 | }; | 7 | }; |
| 8 | use nostr_database::Order; | ||
| 9 | use nostr_sdk::{ | 8 | use nostr_sdk::{ |
| 10 | Alphabet, FromBech32, JsonUtil, Keys, Kind, NostrDatabase, NostrSigner, SingleLetterTag, | 9 | Alphabet, FromBech32, JsonUtil, Keys, Kind, NostrSigner, SingleLetterTag, ToBech32, Url, |
| 11 | ToBech32, | ||
| 12 | }; | 10 | }; |
| 13 | use nostr_signer::Nip46Signer; | 11 | use nostr_signer::Nip46Signer; |
| 14 | use nostr_sqlite::SQLiteDatabase; | ||
| 15 | 12 | ||
| 16 | #[cfg(not(test))] | 13 | #[cfg(not(test))] |
| 17 | use crate::client::Client; | 14 | use crate::client::Client; |
| @@ -21,8 +18,8 @@ use crate::{ | |||
| 21 | cli_interactor::{ | 18 | cli_interactor::{ |
| 22 | Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms, PromptPasswordParms, | 19 | Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms, PromptPasswordParms, |
| 23 | }, | 20 | }, |
| 24 | client::{fetch_public_key, Connect}, | 21 | client::{fetch_public_key, get_event_from_global_cache, Connect}, |
| 25 | config::{get_dirs, UserMetadata, UserRef, UserRelayRef, UserRelays}, | 22 | config::{UserMetadata, UserRef, UserRelayRef, UserRelays}, |
| 26 | git::{Repo, RepoActions}, | 23 | git::{Repo, RepoActions}, |
| 27 | key_handling::encryption::{decrypt_key, encrypt_key}, | 24 | key_handling::encryption::{decrypt_key, encrypt_key}, |
| 28 | }; | 25 | }; |
| @@ -107,7 +104,7 @@ pub async fn launch( | |||
| 107 | 104 | ||
| 108 | fn print_logged_in_as(user_ref: &UserRef, offline_mode: bool) -> Result<()> { | 105 | fn print_logged_in_as(user_ref: &UserRef, offline_mode: bool) -> Result<()> { |
| 109 | if !offline_mode && user_ref.metadata.created_at.eq(&0) { | 106 | if !offline_mode && user_ref.metadata.created_at.eq(&0) { |
| 110 | println!("cannot find your account metadata (name, etc) on relays"); | 107 | println!("cannot find profile..."); |
| 111 | } else if !offline_mode && user_ref.metadata.name.eq(&user_ref.public_key.to_bech32()?) { | 108 | } else if !offline_mode && user_ref.metadata.name.eq(&user_ref.public_key.to_bech32()?) { |
| 112 | println!("cannot extract account name from account metadata..."); | 109 | println!("cannot extract account name from account metadata..."); |
| 113 | } else if !offline_mode && user_ref.relays.created_at.eq(&0) { | 110 | } else if !offline_mode && user_ref.relays.created_at.eq(&0) { |
| @@ -615,20 +612,6 @@ async fn get_user_details( | |||
| 615 | #[cfg(not(test))] client: Option<&Client>, | 612 | #[cfg(not(test))] client: Option<&Client>, |
| 616 | git_repo: &Repo, | 613 | git_repo: &Repo, |
| 617 | ) -> Result<UserRef> { | 614 | ) -> Result<UserRef> { |
| 618 | if client.is_some() { | ||
| 619 | println!("searching for profile and relay updates..."); | ||
| 620 | } | ||
| 621 | let database = SQLiteDatabase::open(if std::env::var("NGITTEST").is_err() { | ||
| 622 | create_dir_all(get_dirs()?.config_dir()).context(format!( | ||
| 623 | "cannot create cache directory in: {:?}", | ||
| 624 | get_dirs()?.config_dir() | ||
| 625 | ))?; | ||
| 626 | get_dirs()?.config_dir().join("cache.sqlite") | ||
| 627 | } else { | ||
| 628 | git_repo.get_path()?.join(".git/test-global-cache.sqlite") | ||
| 629 | }) | ||
| 630 | .await?; | ||
| 631 | let mut events: Vec<nostr::Event> = vec![]; | ||
| 632 | let filters = vec![ | 615 | let filters = vec![ |
| 633 | nostr::Filter::default() | 616 | nostr::Filter::default() |
| 634 | .author(*public_key) | 617 | .author(*public_key) |
| @@ -637,54 +620,63 @@ async fn get_user_details( | |||
| 637 | .author(*public_key) | 620 | .author(*public_key) |
| 638 | .kind(Kind::RelayList), | 621 | .kind(Kind::RelayList), |
| 639 | ]; | 622 | ]; |
| 640 | if let Ok(cached_events) = database.query(filters.clone(), Order::Asc).await { | ||
| 641 | for event in cached_events { | ||
| 642 | events.push(event); | ||
| 643 | } | ||
| 644 | } | ||
| 645 | let mut relays_to_search = if let Some(client) = client { | ||
| 646 | client.get_fallback_relays().clone() | ||
| 647 | } else { | ||
| 648 | vec![] | ||
| 649 | }; | ||
| 650 | let mut relays_searched = vec![]; | ||
| 651 | let user_ref = loop { | ||
| 652 | if let Some(client) = client { | ||
| 653 | for event in client | ||
| 654 | .get_events(relays_to_search.clone(), filters.clone()) | ||
| 655 | .await | ||
| 656 | .unwrap_or(vec![]) | ||
| 657 | { | ||
| 658 | let _ = database.save_event(&event).await; | ||
| 659 | events.push(event); | ||
| 660 | } | ||
| 661 | } | ||
| 662 | 623 | ||
| 663 | #[allow(clippy::clone_on_copy)] | 624 | let mut events = get_event_from_global_cache(git_repo.get_path()?, filters.clone()).await?; |
| 664 | let user_ref = UserRef { | ||
| 665 | public_key: public_key.clone(), | ||
| 666 | metadata: extract_user_metadata(public_key, &events)?, | ||
| 667 | relays: extract_user_relays(public_key, &events), | ||
| 668 | }; | ||
| 669 | 625 | ||
| 670 | if client.is_none() { | 626 | if let Some(client) = client { |
| 671 | break user_ref; | 627 | if events.is_empty() { |
| 672 | } | 628 | let term = console::Term::stderr(); |
| 673 | for r in &relays_to_search { | 629 | term.write_line("searching for profile...")?; |
| 674 | relays_searched.push(r.clone()); | 630 | let (_, progress_reporter) = client |
| 631 | .fetch_all(git_repo.get_path()?, &HashSet::new()) | ||
| 632 | .await?; | ||
| 633 | events = get_event_from_global_cache(git_repo.get_path()?, filters).await?; | ||
| 634 | if !events.is_empty() { | ||
| 635 | progress_reporter.clear()?; | ||
| 636 | // term.clear_last_lines(1)?; | ||
| 637 | } | ||
| 675 | } | 638 | } |
| 639 | } | ||
| 676 | 640 | ||
| 677 | relays_to_search = user_ref | 641 | Ok(UserRef { |
| 678 | .relays | 642 | public_key: public_key.to_owned(), |
| 679 | .write() | 643 | metadata: extract_user_metadata(public_key, &events)?, |
| 680 | .iter() | 644 | relays: extract_user_relays(public_key, &events), |
| 681 | .filter(|r| !relays_searched.iter().any(|or| r.eq(&or))) | 645 | }) |
| 682 | .map(std::clone::Clone::clone) | 646 | } |
| 683 | .collect(); | 647 | |
| 684 | if !relays_to_search.is_empty() { | 648 | pub async fn get_logged_in_user_and_relays_from_cache( |
| 685 | continue; | 649 | git_repo_path: &Path, |
| 650 | ) -> Result<(Option<PublicKey>, HashSet<Url>)> { | ||
| 651 | let git_repo = Repo::from_path(&git_repo_path.to_path_buf())?; | ||
| 652 | let current_user = if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? { | ||
| 653 | if let Ok(pubic_key) = PublicKey::parse(npub) { | ||
| 654 | Some(pubic_key) | ||
| 655 | } else { | ||
| 656 | None | ||
| 686 | } | 657 | } |
| 687 | break user_ref; | 658 | } else { |
| 659 | None | ||
| 660 | }; | ||
| 661 | let relays = if let Some(current_user) = current_user { | ||
| 662 | extract_user_relays( | ||
| 663 | ¤t_user, | ||
| 664 | &get_event_from_global_cache( | ||
| 665 | git_repo.get_path()?, | ||
| 666 | vec![ | ||
| 667 | nostr::Filter::default() | ||
| 668 | .author((*current_user).into()) | ||
| 669 | .kind(Kind::RelayList), | ||
| 670 | ], | ||
| 671 | ) | ||
| 672 | .await?, | ||
| 673 | ) | ||
| 674 | .write() | ||
| 675 | .iter() | ||
| 676 | .filter_map(|r| Url::parse(r).ok()) | ||
| 677 | .collect::<HashSet<Url>>() | ||
| 678 | } else { | ||
| 679 | HashSet::new() | ||
| 688 | }; | 680 | }; |
| 689 | Ok(user_ref) | 681 | Ok((current_user, relays)) |
| 690 | } | 682 | } |
diff --git a/src/sub_commands/fetch.rs b/src/sub_commands/fetch.rs index 07fd6f9..5a6850c 100644 --- a/src/sub_commands/fetch.rs +++ b/src/sub_commands/fetch.rs | |||
| @@ -9,7 +9,7 @@ use crate::client::Client; | |||
| 9 | #[cfg(test)] | 9 | #[cfg(test)] |
| 10 | use crate::client::MockConnect; | 10 | use crate::client::MockConnect; |
| 11 | use crate::{ | 11 | use crate::{ |
| 12 | client::Connect, | 12 | client::{consolidate_fetch_reports, Connect}, |
| 13 | git::{Repo, RepoActions}, | 13 | git::{Repo, RepoActions}, |
| 14 | repo_ref::get_repo_coordinates, | 14 | repo_ref::get_repo_coordinates, |
| 15 | Cli, | 15 | Cli, |
| @@ -38,9 +38,16 @@ pub async fn launch(args: &Cli, command_args: &SubCommandArgs) -> Result<()> { | |||
| 38 | } | 38 | } |
| 39 | repo_coordinates | 39 | repo_coordinates |
| 40 | }; | 40 | }; |
| 41 | client | 41 | println!("fetching updates..."); |
| 42 | let (relay_reports, _) = client | ||
| 42 | .fetch_all(git_repo.get_path()?, &repo_coordinates) | 43 | .fetch_all(git_repo.get_path()?, &repo_coordinates) |
| 43 | .await?; | 44 | .await?; |
| 45 | let report = consolidate_fetch_reports(relay_reports); | ||
| 46 | if report.to_string().is_empty() { | ||
| 47 | println!("no updates"); | ||
| 48 | } else { | ||
| 49 | println!("updates: {report}"); | ||
| 50 | } | ||
| 44 | client.disconnect().await?; | 51 | client.disconnect().await?; |
| 45 | Ok(()) | 52 | Ok(()) |
| 46 | } | 53 | } |