diff --git a/src/cli/commands/issue/new.rs b/src/cli/commands/issue/new.rs index 205b3a8..ce69856 100644 --- a/src/cli/commands/issue/new.rs +++ b/src/cli/commands/issue/new.rs @@ -16,7 +16,6 @@ use clap::{ArgGroup, Args}; -use futures::future; use nostr::event::{EventBuilder, Tag}; use crate::{ @@ -103,10 +102,11 @@ impl CommandRunner for NewArgs { let relays = options.relays.clone().flat_relays(&options.config.sets)?; let client = NostrClient::init(&options, &relays).await; let user_pubk = options.pubkey().await?; - let mut naddrs_iter = naddrs.clone().into_iter(); - + let coordinates = naddrs.clone().into_coordinates(); client.add_relays(&naddrs.extract_relays()).await; - + let repos = client.fetch_repos(coordinates.as_slice()).await?; + let maintainers = repos.extract_maintainers(); + client.add_relays(&repos.extract_relays()).await; let relays_list = client.user_relays_list(user_pubk).await?; client .add_relays(&utils::add_read_relays(relays_list.as_ref())) @@ -115,24 +115,13 @@ impl CommandRunner for NewArgs { let (subject, content) = self.issue_content()?; let content_details = client.parse_content(&content).await; - let event = EventBuilder::new_git_issue( - naddrs_iter - .next() - .expect("There is at least one address") - .coordinate - .clone(), - content, - subject, - self.label, - )? - .dedup_tags() - .pow(options.pow.unwrap_or_default()) - .tags(content_details.clone().into_tags()) - // p-tag the reset of the reposotoies owners - .tags(naddrs_iter.clone().map(|n| Tag::public_key(n.public_key))) - // a-tag the reset of the reposotoies - .tags(naddrs_iter.clone().map(|n| Tag::coordinate(n.coordinate, n.relays.first().cloned()))) - .build(user_pubk); + let event = + EventBuilder::new_git_issue(coordinates.as_slice(), content, subject, self.label)? + .dedup_tags() + .pow(options.pow.unwrap_or_default()) + .tags(maintainers.iter().map(|p| Tag::public_key(*p))) + .tags(content_details.clone().into_tags()) + .build(user_pubk); let event_id = event.id.expect("There is an id"); let write_relays = [ @@ -143,12 +132,8 @@ impl CommandRunner for NewArgs { .fetch_repos(&naddrs.into_coordinates()) .await? .extract_relays(), - // Include read relays for each repository owner (if found) - future::join_all(naddrs_iter.map(|c| client.read_relays_from_user(c.public_key))) - .await - .into_iter() - .flatten() - .collect(), + // Include read relays for each maintainer (if found) + client.read_relays_from_users(&maintainers).await, content_details.write_relays.clone().into_iter().collect(), ] .concat(); diff --git a/src/cli/commands/patch/send.rs b/src/cli/commands/patch/send.rs index 20b5953..015a8e4 100644 --- a/src/cli/commands/patch/send.rs +++ b/src/cli/commands/patch/send.rs @@ -88,17 +88,15 @@ impl CommandRunner for SendArgs { client .add_relays(&utils::add_read_relays(relays_list.as_ref())) .await; - let repos_relays = client - .fetch_repos(&repo_coordinates) - .await? - .extract_relays(); - client.add_relays(&repos_relays).await; + let repos = client.fetch_repos(&repo_coordinates).await?; + let maintainers = repos.extract_maintainers(); + client.add_relays(&repos.extract_relays()).await; let (events, events_write_relays) = make_patch_series( &client, self.patches, self.original_patch.as_ref().map(|e| e.event_id), - repos_relays.first().cloned(), + repos.extract_relays().first().cloned(), repo_coordinates, &self.euc, user_pubk, @@ -107,20 +105,12 @@ impl CommandRunner for SendArgs { let write_relays = [ relays, - repos_relays, + repos.extract_relays(), events_write_relays, naddrs.extract_relays(), self.original_patch.map(|e| e.relays).unwrap_or_default(), utils::add_write_relays(relays_list.as_ref()), - future::join_all( - naddrs - .iter() - .map(|c| client.read_relays_from_user(c.public_key)), - ) - .await - .into_iter() - .flatten() - .collect(), + client.read_relays_from_users(&maintainers).await, ] .concat(); diff --git a/src/cli/commands/reply.rs b/src/cli/commands/reply.rs index 6e9deab..1c56641 100644 --- a/src/cli/commands/reply.rs +++ b/src/cli/commands/reply.rs @@ -113,6 +113,7 @@ impl CommandRunner for ReplyArgs { }; let repos = client.fetch_repos(&repos_coordinate).await?; + let maintainers = repos.extract_maintainers(); let quoted_content = if self.quote_to { Some(quote_reply_to_content(&client, &reply_to).await) @@ -140,16 +141,8 @@ impl CommandRunner for ReplyArgs { utils::add_write_relays(relays_list.as_ref()), // Merge repository announcement relays into write relays repos.extract_relays(), - // Include read relays for each repository owner (if found) - future::join_all( - repos_coordinate - .iter() - .map(|c| client.read_relays_from_user(c.public_key)), - ) - .await - .into_iter() - .flatten() - .collect(), + // Include read relays for each repository maintainer (if found) + client.read_relays_from_users(&maintainers).await, // read relays of the root event and the reply to event { let (r1, r2) = future::join( diff --git a/src/cli/common_commands.rs b/src/cli/common_commands.rs index 689b09a..b64ae92 100644 --- a/src/cli/common_commands.rs +++ b/src/cli/common_commands.rs @@ -56,7 +56,7 @@ pub async fn issue_status_command( let coordinates = naddrs.clone().into_coordinates(); let repos = client.fetch_repos(&coordinates).await?; - let maintainers = utils::dedup(repos.iter().flat_map(|r| r.maintainers.clone())); + let maintainers = repos.extract_maintainers(); let relay_hint = repos.extract_relays().first().cloned(); client.add_relays(&repos.extract_relays()).await; @@ -99,17 +99,7 @@ pub async fn issue_status_command( repos.extract_relays(), utils::add_write_relays(user_relays_list.as_ref()), client.read_relays_from_user(issue_event.pubkey).await, - // TODO: Make this a function and use it elsewhere. - client - .fetch_events( - Filter::new() - .kind(nostr::event::Kind::RelayList) - .authors(maintainers), - ) - .await? - .into_iter() - .flat_map(|e| utils::add_read_relays(Some(&e))) - .collect(), + client.read_relays_from_users(&maintainers).await, ] .concat(); diff --git a/src/error.rs b/src/error.rs index 25fa6f6..0a884ab 100644 --- a/src/error.rs +++ b/src/error.rs @@ -99,6 +99,8 @@ pub enum N34Error { RevisionRootNotFound, #[error("Invalid status for the issue/patch: {0}")] InvalidStatus(String), + #[error("One naddr is required for this command")] + EmptyNaddrs, } impl N34Error { diff --git a/src/nostr_utils/mod.rs b/src/nostr_utils/mod.rs index 54d3b65..8f060a1 100644 --- a/src/nostr_utils/mod.rs +++ b/src/nostr_utils/mod.rs @@ -342,6 +342,21 @@ impl NostrClient { utils::add_read_relays(self.user_relays_list(user).await.ok().flatten().as_ref()) } + /// Returns the read relays of the given users if found, otherwise empty + /// vector + pub async fn read_relays_from_users(&self, users: &[PublicKey]) -> Vec { + self.fetch_events( + Filter::new() + .kind(nostr::event::Kind::RelayList) + .authors(utils::dedup(users.iter().copied())), + ) + .await + .unwrap_or_default() + .into_iter() + .flat_map(|e| utils::add_read_relays(Some(&e))) + .collect() + } + /// Parse the given content and returns the details that inside it pub async fn parse_content(&self, content: &str) -> ContentDetails { let mut write_relays = Vec::new(); diff --git a/src/nostr_utils/traits.rs b/src/nostr_utils/traits.rs index 777dcd3..e80bb03 100644 --- a/src/nostr_utils/traits.rs +++ b/src/nostr_utils/traits.rs @@ -111,18 +111,27 @@ impl EventBuilder { /// Creates a new [`GitIssue`] event builder with the given /// issue details. pub fn new_git_issue( - repository: Coordinate, + coordinates: &[Coordinate], content: String, subject: Option, labels: Vec, ) -> N34Result { + let mut coordinates = coordinates.iter(); + let first_coordinate = coordinates.next().ok_or(N34Error::EmptyNaddrs)?; + let mut event_builder = EventBuilder::git_issue(GitIssue { - repository, + repository: first_coordinate.clone(), content, subject: subject.clone(), labels: labels.into_iter().map(|l| l.trim().to_owned()).collect(), }) - .map_err(N34Error::from)?; + .map_err(N34Error::from)? + .tags( + coordinates + .clone() + .map(|c| Tag::coordinate(c.clone(), None)), + ) + .tags(coordinates.map(|c| Tag::public_key(c.public_key))); if let Some(issue_subject) = subject { event_builder = @@ -196,4 +205,10 @@ impl Vec { pub fn extract_relays(&self) -> Vec { self.iter().flat_map(|n| n.relays.clone()).collect() } + + /// Extract all the maintainers from these repositories + pub fn extract_maintainers(&self) -> Vec { + self.iter().flat_map(|r| r.maintainers.clone()).collect() + } +} }