upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/client.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.rs')
-rw-r--r--src/client.rs156
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
36use crate::{ 36use 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(&current_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
975fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchReport { 1005pub 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}