diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/client.rs | 107 | ||||
| -rw-r--r-- | src/config.rs | 5 | ||||
| -rw-r--r-- | src/login.rs | 14 |
3 files changed, 94 insertions, 32 deletions
diff --git a/src/client.rs b/src/client.rs index 1fdc3d8..17e98b0 100644 --- a/src/client.rs +++ b/src/client.rs | |||
| @@ -349,7 +349,13 @@ impl Connect for Client { | |||
| 349 | proposals: HashSet::new(), | 349 | proposals: HashSet::new(), |
| 350 | missing_contributor_profiles: request | 350 | missing_contributor_profiles: request |
| 351 | .missing_contributor_profiles | 351 | .missing_contributor_profiles |
| 352 | .union(&request.profiles_to_fetch_from_user_relays) | 352 | .union( |
| 353 | &request | ||
| 354 | .profiles_to_fetch_from_user_relays | ||
| 355 | .clone() | ||
| 356 | .into_keys() | ||
| 357 | .collect(), | ||
| 358 | ) | ||
| 353 | .copied() | 359 | .copied() |
| 354 | .collect(), | 360 | .collect(), |
| 355 | ..request.clone() | 361 | ..request.clone() |
| @@ -431,7 +437,12 @@ impl Connect for Client { | |||
| 431 | 437 | ||
| 432 | request.user_relays_for_profiles = { | 438 | request.user_relays_for_profiles = { |
| 433 | let mut set = HashSet::new(); | 439 | let mut set = HashSet::new(); |
| 434 | for user in &request.profiles_to_fetch_from_user_relays { | 440 | for user in &request |
| 441 | .profiles_to_fetch_from_user_relays | ||
| 442 | .clone() | ||
| 443 | .into_keys() | ||
| 444 | .collect::<Vec<PublicKey>>() | ||
| 445 | { | ||
| 435 | if let Ok(user_ref) = get_user_ref_from_cache(git_repo_path, user).await { | 446 | if let Ok(user_ref) = get_user_ref_from_cache(git_repo_path, user).await { |
| 436 | for r in user_ref.relays.write() { | 447 | for r in user_ref.relays.write() { |
| 437 | if let Ok(url) = Url::parse(&r) { | 448 | if let Ok(url) = Url::parse(&r) { |
| @@ -457,9 +468,15 @@ impl Connect for Client { | |||
| 457 | fresh_coordinates.insert(c); | 468 | fresh_coordinates.insert(c); |
| 458 | } | 469 | } |
| 459 | let mut fresh_proposal_roots = request.proposals.clone(); | 470 | let mut fresh_proposal_roots = request.proposals.clone(); |
| 460 | let mut fresh_contributors = request | 471 | let mut fresh_profiles = request |
| 461 | .missing_contributor_profiles | 472 | .missing_contributor_profiles |
| 462 | .union(&request.profiles_to_fetch_from_user_relays) | 473 | .union( |
| 474 | &request | ||
| 475 | .profiles_to_fetch_from_user_relays | ||
| 476 | .clone() | ||
| 477 | .into_keys() | ||
| 478 | .collect(), | ||
| 479 | ) | ||
| 463 | .copied() | 480 | .copied() |
| 464 | .collect(); | 481 | .collect(); |
| 465 | 482 | ||
| @@ -477,11 +494,8 @@ impl Connect for Client { | |||
| 477 | let dim = Style::new().color256(247); | 494 | let dim = Style::new().color256(247); |
| 478 | 495 | ||
| 479 | loop { | 496 | loop { |
| 480 | let filters = get_fetch_filters( | 497 | let filters = |
| 481 | &fresh_coordinates, | 498 | get_fetch_filters(&fresh_coordinates, &fresh_proposal_roots, &fresh_profiles); |
| 482 | &fresh_proposal_roots, | ||
| 483 | &fresh_contributors, | ||
| 484 | ); | ||
| 485 | 499 | ||
| 486 | if let Some(pb) = &pb { | 500 | if let Some(pb) = &pb { |
| 487 | pb.set_prefix( | 501 | pb.set_prefix( |
| @@ -500,7 +514,7 @@ impl Connect for Client { | |||
| 500 | 514 | ||
| 501 | fresh_coordinates = HashSet::new(); | 515 | fresh_coordinates = HashSet::new(); |
| 502 | fresh_proposal_roots = HashSet::new(); | 516 | fresh_proposal_roots = HashSet::new(); |
| 503 | fresh_contributors = HashSet::new(); | 517 | fresh_profiles = HashSet::new(); |
| 504 | 518 | ||
| 505 | let relay = self.client.relay(&relay_url).await?; | 519 | let relay = self.client.relay(&relay_url).await?; |
| 506 | let events: Vec<nostr::Event> = get_events_of(&relay, filters, &None).await?; | 520 | let events: Vec<nostr::Event> = get_events_of(&relay, filters, &None).await?; |
| @@ -512,7 +526,7 @@ impl Connect for Client { | |||
| 512 | git_repo_path, | 526 | git_repo_path, |
| 513 | &mut fresh_coordinates, | 527 | &mut fresh_coordinates, |
| 514 | &mut fresh_proposal_roots, | 528 | &mut fresh_proposal_roots, |
| 515 | &mut fresh_contributors, | 529 | &mut fresh_profiles, |
| 516 | &mut report, | 530 | &mut report, |
| 517 | ) | 531 | ) |
| 518 | .await?; | 532 | .await?; |
| @@ -885,16 +899,28 @@ async fn create_relays_request( | |||
| 885 | } | 899 | } |
| 886 | 900 | ||
| 887 | let profiles_to_fetch_from_user_relays = { | 901 | let profiles_to_fetch_from_user_relays = { |
| 888 | let mut set = user_profiles.clone(); | 902 | let mut user_profiles = user_profiles.clone(); |
| 889 | if let Ok(Some(current_user)) = get_logged_in_user(git_repo_path).await { | 903 | if let Ok(Some(current_user)) = get_logged_in_user(git_repo_path).await { |
| 890 | set.insert(current_user); | 904 | user_profiles.insert(current_user); |
| 891 | } | 905 | } |
| 892 | set | 906 | let mut map: HashMap<PublicKey, (Timestamp, Timestamp)> = HashMap::new(); |
| 907 | for public_key in &user_profiles { | ||
| 908 | let user_ref = get_user_ref_from_cache(git_repo_path, public_key).await?; | ||
| 909 | map.insert( | ||
| 910 | public_key.to_owned(), | ||
| 911 | (user_ref.metadata.created_at, user_ref.relays.created_at), | ||
| 912 | ); | ||
| 913 | } | ||
| 914 | map | ||
| 893 | }; | 915 | }; |
| 894 | 916 | ||
| 895 | let user_relays_for_profiles = { | 917 | let user_relays_for_profiles = { |
| 896 | let mut set = HashSet::new(); | 918 | let mut set = HashSet::new(); |
| 897 | for user in &profiles_to_fetch_from_user_relays { | 919 | for user in &profiles_to_fetch_from_user_relays |
| 920 | .clone() | ||
| 921 | .into_keys() | ||
| 922 | .collect::<Vec<PublicKey>>() | ||
| 923 | { | ||
| 898 | if let Ok(user_ref) = get_user_ref_from_cache(git_repo_path, user).await { | 924 | if let Ok(user_ref) = get_user_ref_from_cache(git_repo_path, user).await { |
| 899 | for r in user_ref.relays.write() { | 925 | for r in user_ref.relays.write() { |
| 900 | if let Ok(url) = Url::parse(&r) { | 926 | if let Ok(url) = Url::parse(&r) { |
| @@ -914,7 +940,12 @@ async fn create_relays_request( | |||
| 914 | &repo_coordinates_without_relays, | 940 | &repo_coordinates_without_relays, |
| 915 | &proposals, | 941 | &proposals, |
| 916 | &missing_contributor_profiles | 942 | &missing_contributor_profiles |
| 917 | .union(&profiles_to_fetch_from_user_relays) | 943 | .union( |
| 944 | &profiles_to_fetch_from_user_relays | ||
| 945 | .clone() | ||
| 946 | .into_keys() | ||
| 947 | .collect(), | ||
| 948 | ) | ||
| 918 | .copied() | 949 | .copied() |
| 919 | .collect(), | 950 | .collect(), |
| 920 | ) { | 951 | ) { |
| @@ -994,7 +1025,7 @@ async fn process_fetched_events( | |||
| 994 | git_repo_path: &Path, | 1025 | git_repo_path: &Path, |
| 995 | fresh_coordinates: &mut HashSet<Coordinate>, | 1026 | fresh_coordinates: &mut HashSet<Coordinate>, |
| 996 | fresh_proposal_roots: &mut HashSet<EventId>, | 1027 | fresh_proposal_roots: &mut HashSet<EventId>, |
| 997 | fresh_contributors: &mut HashSet<PublicKey>, | 1028 | fresh_profiles: &mut HashSet<PublicKey>, |
| 998 | report: &mut FetchReport, | 1029 | report: &mut FetchReport, |
| 999 | ) -> Result<()> { | 1030 | ) -> Result<()> { |
| 1000 | for event in &events { | 1031 | for event in &events { |
| @@ -1044,9 +1075,16 @@ async fn process_fetched_events( | |||
| 1044 | identifier: repo_ref.identifier.clone(), | 1075 | identifier: repo_ref.identifier.clone(), |
| 1045 | relays: vec![], | 1076 | relays: vec![], |
| 1046 | }); | 1077 | }); |
| 1047 | if !request.contributors.contains(m) && !fresh_contributors.contains(m) | 1078 | if !request.contributors.contains(m) |
| 1079 | && !request | ||
| 1080 | .profiles_to_fetch_from_user_relays | ||
| 1081 | .clone() | ||
| 1082 | .into_keys() | ||
| 1083 | .collect::<HashSet<PublicKey>>() | ||
| 1084 | .contains(m) | ||
| 1085 | && !fresh_profiles.contains(m) | ||
| 1048 | { | 1086 | { |
| 1049 | fresh_contributors.insert(m.to_owned()); | 1087 | fresh_profiles.insert(m.to_owned()); |
| 1050 | } | 1088 | } |
| 1051 | } | 1089 | } |
| 1052 | } | 1090 | } |
| @@ -1055,13 +1093,21 @@ async fn process_fetched_events( | |||
| 1055 | fresh_proposal_roots.insert(event.id); | 1093 | fresh_proposal_roots.insert(event.id); |
| 1056 | report.proposals.insert(event.id); | 1094 | report.proposals.insert(event.id); |
| 1057 | if !request.contributors.contains(&event.author()) | 1095 | if !request.contributors.contains(&event.author()) |
| 1058 | && !fresh_contributors.contains(&event.author()) | 1096 | && !fresh_profiles.contains(&event.author()) |
| 1059 | { | 1097 | { |
| 1060 | fresh_contributors.insert(event.author()); | 1098 | fresh_profiles.insert(event.author()); |
| 1061 | } | 1099 | } |
| 1062 | } else if [Kind::RelayList, Kind::Metadata].contains(&event.kind()) { | 1100 | } else if [Kind::RelayList, Kind::Metadata].contains(&event.kind()) { |
| 1063 | if Kind::Metadata.eq(&event.kind()) { | 1101 | if Kind::Metadata.eq(&event.kind()) { |
| 1064 | report.contributor_profiles.insert(event.author()); | 1102 | if request |
| 1103 | .missing_contributor_profiles | ||
| 1104 | .contains(event.author_ref()) | ||
| 1105 | { | ||
| 1106 | report.contributor_profiles.insert(event.author()); | ||
| 1107 | } else { | ||
| 1108 | // TODO: how do we know if the recieved profile is new? | ||
| 1109 | report.profile_updates.insert(event.author()); | ||
| 1110 | } | ||
| 1065 | } | 1111 | } |
| 1066 | save_event_in_global_cache(git_repo_path, event).await?; | 1112 | save_event_in_global_cache(git_repo_path, event).await?; |
| 1067 | } | 1113 | } |
| @@ -1115,6 +1161,9 @@ pub fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchRepo | |||
| 1115 | for c in relay_report.contributor_profiles { | 1161 | for c in relay_report.contributor_profiles { |
| 1116 | report.contributor_profiles.insert(c); | 1162 | report.contributor_profiles.insert(c); |
| 1117 | } | 1163 | } |
| 1164 | for c in relay_report.profile_updates { | ||
| 1165 | report.profile_updates.insert(c); | ||
| 1166 | } | ||
| 1118 | } | 1167 | } |
| 1119 | report | 1168 | report |
| 1120 | } | 1169 | } |
| @@ -1194,6 +1243,7 @@ pub struct FetchReport { | |||
| 1194 | commits: HashSet<EventId>, | 1243 | commits: HashSet<EventId>, |
| 1195 | statuses: HashSet<EventId>, | 1244 | statuses: HashSet<EventId>, |
| 1196 | contributor_profiles: HashSet<PublicKey>, | 1245 | contributor_profiles: HashSet<PublicKey>, |
| 1246 | profile_updates: HashSet<PublicKey>, | ||
| 1197 | } | 1247 | } |
| 1198 | 1248 | ||
| 1199 | impl Display for FetchReport { | 1249 | impl Display for FetchReport { |
| @@ -1254,6 +1304,17 @@ impl Display for FetchReport { | |||
| 1254 | }, | 1304 | }, |
| 1255 | )); | 1305 | )); |
| 1256 | } | 1306 | } |
| 1307 | if !self.profile_updates.is_empty() { | ||
| 1308 | display_items.push(format!( | ||
| 1309 | "{} profile update{}", | ||
| 1310 | self.profile_updates.len(), | ||
| 1311 | if self.profile_updates.len() > 1 { | ||
| 1312 | "s" | ||
| 1313 | } else { | ||
| 1314 | "" | ||
| 1315 | }, | ||
| 1316 | )); | ||
| 1317 | } | ||
| 1257 | write!(f, "{}", display_items.join(", ")) | 1318 | write!(f, "{}", display_items.join(", ")) |
| 1258 | } | 1319 | } |
| 1259 | } | 1320 | } |
| @@ -1268,6 +1329,6 @@ pub struct FetchRequest { | |||
| 1268 | contributors: HashSet<PublicKey>, | 1329 | contributors: HashSet<PublicKey>, |
| 1269 | missing_contributor_profiles: HashSet<PublicKey>, | 1330 | missing_contributor_profiles: HashSet<PublicKey>, |
| 1270 | existing_events: HashSet<EventId>, | 1331 | existing_events: HashSet<EventId>, |
| 1271 | profiles_to_fetch_from_user_relays: HashSet<PublicKey>, | 1332 | profiles_to_fetch_from_user_relays: HashMap<PublicKey, (Timestamp, Timestamp)>, |
| 1272 | user_relays_for_profiles: HashSet<Url>, | 1333 | user_relays_for_profiles: HashSet<Url>, |
| 1273 | } | 1334 | } |
diff --git a/src/config.rs b/src/config.rs index 56619b8..f5dba98 100644 --- a/src/config.rs +++ b/src/config.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | use anyhow::{anyhow, Result}; | 1 | use anyhow::{anyhow, Result}; |
| 2 | use directories::ProjectDirs; | 2 | use directories::ProjectDirs; |
| 3 | use nostr::PublicKey; | 3 | use nostr::PublicKey; |
| 4 | use nostr_sdk::Timestamp; | ||
| 4 | use serde::{self, Deserialize, Serialize}; | 5 | use serde::{self, Deserialize, Serialize}; |
| 5 | 6 | ||
| 6 | pub fn get_dirs() -> Result<ProjectDirs> { | 7 | pub fn get_dirs() -> Result<ProjectDirs> { |
| @@ -19,13 +20,13 @@ pub struct UserRef { | |||
| 19 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] | 20 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] |
| 20 | pub struct UserMetadata { | 21 | pub struct UserMetadata { |
| 21 | pub name: String, | 22 | pub name: String, |
| 22 | pub created_at: u64, | 23 | pub created_at: Timestamp, |
| 23 | } | 24 | } |
| 24 | 25 | ||
| 25 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] | 26 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] |
| 26 | pub struct UserRelays { | 27 | pub struct UserRelays { |
| 27 | pub relays: Vec<UserRelayRef>, | 28 | pub relays: Vec<UserRelayRef>, |
| 28 | pub created_at: u64, | 29 | pub created_at: Timestamp, |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | impl UserRelays { | 32 | impl UserRelays { |
diff --git a/src/login.rs b/src/login.rs index aac0141..b746202 100644 --- a/src/login.rs +++ b/src/login.rs | |||
| @@ -6,7 +6,7 @@ use nostr::{ | |||
| 6 | PublicKey, | 6 | PublicKey, |
| 7 | }; | 7 | }; |
| 8 | use nostr_sdk::{ | 8 | use nostr_sdk::{ |
| 9 | Alphabet, FromBech32, JsonUtil, Keys, Kind, NostrSigner, SingleLetterTag, ToBech32, | 9 | Alphabet, FromBech32, JsonUtil, Keys, Kind, NostrSigner, SingleLetterTag, Timestamp, ToBech32, |
| 10 | }; | 10 | }; |
| 11 | use nostr_signer::Nip46Signer; | 11 | use nostr_signer::Nip46Signer; |
| 12 | 12 | ||
| @@ -104,11 +104,11 @@ pub async fn launch( | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | fn print_logged_in_as(user_ref: &UserRef, offline_mode: bool) -> Result<()> { | 106 | fn print_logged_in_as(user_ref: &UserRef, offline_mode: bool) -> Result<()> { |
| 107 | if !offline_mode && user_ref.metadata.created_at.eq(&0) { | 107 | if !offline_mode && user_ref.metadata.created_at.eq(&Timestamp::from(0)) { |
| 108 | println!("cannot find profile..."); | 108 | println!("cannot find profile..."); |
| 109 | } else if !offline_mode && user_ref.metadata.name.eq(&user_ref.public_key.to_bech32()?) { | 109 | } else if !offline_mode && user_ref.metadata.name.eq(&user_ref.public_key.to_bech32()?) { |
| 110 | println!("cannot extract account name from account metadata..."); | 110 | println!("cannot extract account name from account metadata..."); |
| 111 | } else if !offline_mode && user_ref.relays.created_at.eq(&0) { | 111 | } else if !offline_mode && user_ref.relays.created_at.eq(&Timestamp::from(0)) { |
| 112 | println!( | 112 | println!( |
| 113 | "cannot find your relay list. consider using another nostr client to create one to enhance your nostr experience." | 113 | "cannot find your relay list. consider using another nostr client to create one to enhance your nostr experience." |
| 114 | ); | 114 | ); |
| @@ -566,9 +566,9 @@ fn extract_user_metadata( | |||
| 566 | public_key.to_bech32()? | 566 | public_key.to_bech32()? |
| 567 | }, | 567 | }, |
| 568 | created_at: if let Some(event) = event { | 568 | created_at: if let Some(event) = event { |
| 569 | event.created_at.as_u64() | 569 | event.created_at |
| 570 | } else { | 570 | } else { |
| 571 | 0 | 571 | Timestamp::from(0) |
| 572 | }, | 572 | }, |
| 573 | }) | 573 | }) |
| 574 | } | 574 | } |
| @@ -600,9 +600,9 @@ fn extract_user_relays(public_key: &nostr::PublicKey, events: &[nostr::Event]) - | |||
| 600 | vec![] | 600 | vec![] |
| 601 | }, | 601 | }, |
| 602 | created_at: if let Some(event) = event { | 602 | created_at: if let Some(event) = event { |
| 603 | event.created_at.as_u64() | 603 | event.created_at |
| 604 | } else { | 604 | } else { |
| 605 | 0 | 605 | Timestamp::from(0) |
| 606 | }, | 606 | }, |
| 607 | } | 607 | } |
| 608 | } | 608 | } |