upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.rs107
-rw-r--r--src/config.rs5
-rw-r--r--src/login.rs14
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
1199impl Display for FetchReport { 1249impl 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 @@
1use anyhow::{anyhow, Result}; 1use anyhow::{anyhow, Result};
2use directories::ProjectDirs; 2use directories::ProjectDirs;
3use nostr::PublicKey; 3use nostr::PublicKey;
4use nostr_sdk::Timestamp;
4use serde::{self, Deserialize, Serialize}; 5use serde::{self, Deserialize, Serialize};
5 6
6pub fn get_dirs() -> Result<ProjectDirs> { 7pub 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)]
20pub struct UserMetadata { 21pub 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)]
26pub struct UserRelays { 27pub 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
31impl UserRelays { 32impl 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};
8use nostr_sdk::{ 8use nostr_sdk::{
9 Alphabet, FromBech32, JsonUtil, Keys, Kind, NostrSigner, SingleLetterTag, ToBech32, 9 Alphabet, FromBech32, JsonUtil, Keys, Kind, NostrSigner, SingleLetterTag, Timestamp, ToBech32,
10}; 10};
11use nostr_signer::Nip46Signer; 11use nostr_signer::Nip46Signer;
12 12
@@ -104,11 +104,11 @@ pub async fn launch(
104} 104}
105 105
106fn print_logged_in_as(user_ref: &UserRef, offline_mode: bool) -> Result<()> { 106fn 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}