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.rs78
1 files changed, 74 insertions, 4 deletions
diff --git a/src/client.rs b/src/client.rs
index 5603014..6fce7a5 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -788,11 +788,11 @@ pub async fn get_repo_ref_from_cache(
788 let mut repo_events = vec![]; 788 let mut repo_events = vec![];
789 loop { 789 loop {
790 new_coordinate = false; 790 new_coordinate = false;
791 let filter = get_filter_repo_events(repo_coordinates); 791 let repo_events_filter = get_filter_repo_events(repo_coordinates);
792 792
793 let events = [ 793 let events = [
794 get_event_from_global_cache(git_repo_path, vec![filter.clone()]).await?, 794 get_event_from_global_cache(git_repo_path, vec![repo_events_filter.clone()]).await?,
795 get_events_from_cache(git_repo_path, vec![filter]).await?, 795 get_events_from_cache(git_repo_path, vec![repo_events_filter]).await?,
796 ] 796 ]
797 .concat(); 797 .concat();
798 for e in events { 798 for e in events {
@@ -841,6 +841,19 @@ pub async fn get_repo_ref_from_cache(
841 }) 841 })
842} 842}
843 843
844pub async fn get_state_from_cache(
845 git_repo_path: &Path,
846 repo_ref: &RepoRef,
847) -> Result<Option<nostr::Event>> {
848 let mut state_events = get_events_from_cache(
849 git_repo_path,
850 vec![get_filter_state_events(&repo_ref.coordinates())],
851 )
852 .await?;
853 state_events.sort_by_key(|e| e.created_at);
854 Ok(state_events.first().map(std::borrow::ToOwned::to_owned))
855}
856
844#[allow(clippy::too_many_lines)] 857#[allow(clippy::too_many_lines)]
845async fn create_relays_request( 858async fn create_relays_request(
846 git_repo_path: &Path, 859 git_repo_path: &Path,
@@ -1040,7 +1053,7 @@ async fn create_relays_request(
1040 selected_relay: None, 1053 selected_relay: None,
1041 repo_relays: relays, 1054 repo_relays: relays,
1042 relay_column_width, 1055 relay_column_width,
1043 repo_coordinates_without_relays: if let Ok(repo_ref) = repo_ref { 1056 repo_coordinates_without_relays: if let Ok(repo_ref) = &repo_ref {
1044 repo_ref.coordinates_with_timestamps() 1057 repo_ref.coordinates_with_timestamps()
1045 } else { 1058 } else {
1046 repo_coordinates_without_relays 1059 repo_coordinates_without_relays
@@ -1048,6 +1061,15 @@ async fn create_relays_request(
1048 .map(|c| (c.clone(), None)) 1061 .map(|c| (c.clone(), None))
1049 .collect() 1062 .collect()
1050 }, 1063 },
1064 state: if let Ok(repo_ref) = &repo_ref {
1065 if let Ok(Some(existing_state)) = get_state_from_cache(git_repo_path, repo_ref).await {
1066 Some((existing_state.created_at, existing_state.id))
1067 } else {
1068 None
1069 }
1070 } else {
1071 None
1072 },
1051 proposals, 1073 proposals,
1052 contributors, 1074 contributors,
1053 missing_contributor_profiles, 1075 missing_contributor_profiles,
@@ -1138,6 +1160,19 @@ async fn process_fetched_events(
1138 } 1160 }
1139 } 1161 }
1140 } 1162 }
1163 } else if event.kind().eq(&STATE_KIND) {
1164 let existing_state = if report.updated_state.is_some() {
1165 report.updated_state
1166 } else {
1167 request.state
1168 };
1169 if let Some((timestamp, id)) = existing_state {
1170 if event.created_at.gt(&timestamp)
1171 || (event.created_at.eq(&timestamp) && event.id.gt(&id))
1172 {
1173 report.updated_state = Some((event.created_at, event.id));
1174 }
1175 }
1141 } else if event_is_patch_set_root(event) { 1176 } else if event_is_patch_set_root(event) {
1142 fresh_proposal_roots.insert(event.id); 1177 fresh_proposal_roots.insert(event.id);
1143 report.proposals.insert(event.id); 1178 report.proposals.insert(event.id);
@@ -1208,6 +1243,17 @@ pub fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchRepo
1208 report.updated_repo_announcements.push((r, t)); 1243 report.updated_repo_announcements.push((r, t));
1209 } 1244 }
1210 } 1245 }
1246 if let Some((timestamp, id)) = relay_report.updated_state {
1247 if let Some((existing_timestamp, existing_id)) = report.updated_state {
1248 if timestamp.gt(&existing_timestamp)
1249 || (timestamp.eq(&existing_timestamp) && id.gt(&existing_id))
1250 {
1251 report.updated_state = Some((timestamp, id));
1252 }
1253 } else {
1254 report.updated_state = Some((timestamp, id));
1255 }
1256 }
1211 for c in relay_report.proposals { 1257 for c in relay_report.proposals {
1212 report.proposals.insert(c); 1258 report.proposals.insert(c);
1213 } 1259 }
@@ -1236,6 +1282,7 @@ pub fn get_fetch_filters(
1236 vec![] 1282 vec![]
1237 } else { 1283 } else {
1238 vec![ 1284 vec![
1285 get_filter_state_events(repo_coordinates),
1239 get_filter_repo_events(repo_coordinates), 1286 get_filter_repo_events(repo_coordinates),
1240 nostr::Filter::default() 1287 nostr::Filter::default()
1241 .kinds(vec![Kind::GitPatch, Kind::EventDeletion]) 1288 .kinds(vec![Kind::GitPatch, Kind::EventDeletion])
@@ -1283,6 +1330,24 @@ pub fn get_filter_repo_events(repo_coordinates: &HashSet<Coordinate>) -> nostr::
1283 ) 1330 )
1284} 1331}
1285 1332
1333pub static STATE_KIND: nostr::Kind = Kind::Custom(30618);
1334pub fn get_filter_state_events(repo_coordinates: &HashSet<Coordinate>) -> nostr::Filter {
1335 nostr::Filter::default()
1336 .kind(STATE_KIND)
1337 .identifiers(
1338 repo_coordinates
1339 .iter()
1340 .map(|c| c.identifier.clone())
1341 .collect::<Vec<String>>(),
1342 )
1343 .authors(
1344 repo_coordinates
1345 .iter()
1346 .map(|c| c.public_key)
1347 .collect::<Vec<PublicKey>>(),
1348 )
1349}
1350
1286pub fn get_filter_contributor_profiles(contributors: HashSet<PublicKey>) -> nostr::Filter { 1351pub fn get_filter_contributor_profiles(contributors: HashSet<PublicKey>) -> nostr::Filter {
1287 nostr::Filter::default() 1352 nostr::Filter::default()
1288 .kinds(vec![Kind::Metadata, Kind::RelayList]) 1353 .kinds(vec![Kind::Metadata, Kind::RelayList])
@@ -1293,6 +1358,7 @@ pub fn get_filter_contributor_profiles(contributors: HashSet<PublicKey>) -> nost
1293pub struct FetchReport { 1358pub struct FetchReport {
1294 repo_coordinates_without_relays: HashSet<Coordinate>, 1359 repo_coordinates_without_relays: HashSet<Coordinate>,
1295 updated_repo_announcements: Vec<(Coordinate, Timestamp)>, 1360 updated_repo_announcements: Vec<(Coordinate, Timestamp)>,
1361 updated_state: Option<(Timestamp, EventId)>,
1296 proposals: HashSet<EventId>, 1362 proposals: HashSet<EventId>,
1297 /// commits against existing propoals 1363 /// commits against existing propoals
1298 commits: HashSet<EventId>, 1364 commits: HashSet<EventId>,
@@ -1327,6 +1393,9 @@ impl Display for FetchReport {
1327 }, 1393 },
1328 )); 1394 ));
1329 } 1395 }
1396 if self.updated_state.is_some() {
1397 display_items.push("new state".to_string());
1398 }
1330 if !self.proposals.is_empty() { 1399 if !self.proposals.is_empty() {
1331 display_items.push(format!( 1400 display_items.push(format!(
1332 "{} proposal{}", 1401 "{} proposal{}",
@@ -1380,6 +1449,7 @@ pub struct FetchRequest {
1380 selected_relay: Option<Url>, 1449 selected_relay: Option<Url>,
1381 relay_column_width: usize, 1450 relay_column_width: usize,
1382 repo_coordinates_without_relays: Vec<(Coordinate, Option<Timestamp>)>, 1451 repo_coordinates_without_relays: Vec<(Coordinate, Option<Timestamp>)>,
1452 state: Option<(Timestamp, EventId)>,
1383 proposals: HashSet<EventId>, 1453 proposals: HashSet<EventId>,
1384 contributors: HashSet<PublicKey>, 1454 contributors: HashSet<PublicKey>,
1385 missing_contributor_profiles: HashSet<PublicKey>, 1455 missing_contributor_profiles: HashSet<PublicKey>,