Skip to content

Commit a4877fd

Browse files
committed
fix: get contributors from organization
1 parent 5772e0d commit a4877fd

File tree

1 file changed

+57
-82
lines changed

1 file changed

+57
-82
lines changed

src/pages/contributors.rs

Lines changed: 57 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
use leptos::{component, view, Fragment, IntoView};
2-
#[cfg(not(debug_assertions))]
3-
use leptos::{create_local_resource, error::Result, serde_json::json, SignalGet};
1+
use std::collections::HashMap;
2+
3+
use leptos::{
4+
component, create_local_resource, error::Result, island, serde_json::json, view, Fragment,
5+
IntoView, SignalGet,
6+
};
47
use serde::{Deserialize, Serialize};
58

69
use crate::components::ContributorCard;
710

8-
#[cfg(not(debug_assertions))]
911
const GRAPH_QUERY: &str = r#"
1012
query OrganizationContributors {
1113
organization(login: "RustLangES") {
1214
repositories(first: 100) {
1315
nodes {
16+
name
1417
collaborators(first: 100) {
1518
nodes {
1619
login
@@ -19,8 +22,11 @@ query OrganizationContributors {
1922
bio
2023
twitterUsername
2124
location
22-
contributionsCollection {
25+
contributionsCollection(organizationID: "O_kgDOBHON2w") {
2326
totalCommitContributions
27+
totalPullRequestContributions
28+
totalIssueContributions
29+
totalRepositoryContributions
2430
}
2531
}
2632
}
@@ -31,23 +37,31 @@ query OrganizationContributors {
3137
"#;
3238

3339
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
40+
#[serde(rename_all = "camelCase")]
3441
pub struct Contributor {
3542
login: String,
3643
avatar_url: String,
3744
url: String,
3845
bio: Option<String>,
3946
twitter_username: Option<String>,
4047
location: Option<String>,
41-
contributions_collection: ContributionCollection,
48+
contributions_collection: Option<ContributionCollection>,
4249
}
4350

4451
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
52+
#[serde(rename_all = "camelCase")]
4553
pub struct ContributionCollection {
46-
total_commit_contributions: u64,
54+
#[serde(rename = "totalCommitContributions")]
55+
commits: u64,
56+
#[serde(rename = "totalPullRequestContributions")]
57+
pull_request: u64,
58+
#[serde(rename = "totalIssueContributions")]
59+
issues: u64,
60+
#[serde(rename = "totalRepositoryContributions")]
61+
repository: u64,
4762
}
4863

49-
#[cfg(not(debug_assertions))]
50-
async fn fetch_contributors() -> Result<Vec<Contributor>> {
64+
pub async fn fetch_contributors() -> Result<Vec<Contributor>> {
5165
let request_body = json!({
5266
"query": GRAPH_QUERY,
5367
});
@@ -77,84 +91,43 @@ async fn fetch_contributors() -> Result<Vec<Contributor>> {
7791
.as_array()
7892
.unwrap_or(&Vec::new())
7993
.iter()
80-
.flat_map(|repo| repo["contributors"]["nodes"].as_array().unwrap())
81-
.map(|c| leptos::serde_json::from_value::<Contributor>(c.clone()).map_err(|e| e.into()))
82-
.collect::<Result<Vec<Contributor>>>()?;
83-
84-
res.sort_by_key(|a| a.contributions_collection.total_commit_contributions);
94+
.flat_map(|repo| repo["collaborators"]["nodes"].as_array().unwrap())
95+
.filter_map(|c| leptos::serde_json::from_value::<Contributor>(c.clone()).ok())
96+
.fold(HashMap::new(), |prev, c| {
97+
let mut prev = prev;
98+
prev.entry(c.login.clone())
99+
.and_modify(|o: &mut Contributor| {
100+
match (
101+
o.contributions_collection.as_mut(),
102+
c.contributions_collection.as_ref(),
103+
) {
104+
(Some(o), Some(c)) => o.commits += c.commits,
105+
(Some(o), None) => o.commits += 1,
106+
_ => {}
107+
}
108+
})
109+
.or_insert(c);
110+
prev
111+
})
112+
.into_values()
113+
.collect::<Vec<_>>();
114+
115+
res.sort_by_key(|a| {
116+
a.contributions_collection
117+
.as_ref()
118+
.map(|c| c.repository)
119+
.unwrap_or(1)
120+
});
85121

86-
println!("Result of Github Request: {res:#?}");
122+
res.reverse();
87123

88124
Ok(res)
89125
}
90126

91-
#[cfg_attr(not(debug_assertions), component)]
92-
#[cfg(not(debug_assertions))]
127+
#[island]
93128
pub fn Contributors() -> impl IntoView {
94-
let contributors_results = create_local_resource(move || (), |()| fetch_contributors());
95-
let contributorMapper = |item: &Contributor| {
96-
view! {
97-
<ContributorCard
98-
name=item.login.clone()
99-
description=item.bio.clone()
100-
link=item.url.clone()
101-
brand_src=item.avatar_url.clone()
102-
twitter=item.twitter_username.clone()
103-
location=item.location.clone()
104-
contributions=item.contributions_collection.total_commit_contributions
105-
/>
106-
}
107-
};
129+
let contributors = create_local_resource(move || (), |()| fetch_contributors());
108130

109-
let contributors_view = move || {
110-
let contributors = contributors_results.get()?.ok()?;
111-
let result = contributors
112-
.iter()
113-
.map(contributorMapper)
114-
.collect::<Fragment>();
115-
Some(result.into_view())
116-
};
117-
118-
view! {
119-
<section class="bg-orange-300/30 dark:bg-transparent py-16">
120-
<div class="flex flex-col gap-y-6 container mx-auto px-4">
121-
<h2 class="text-3xl text-left mb-6">
122-
<span class="font-work-sans font-light">"Nuestros "</span>
123-
<span class="font-alfa-slab text-orange-500">"Colaboradores"</span>
124-
</h2>
125-
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-5 gap-6">
126-
{contributors_view}
127-
</div>
128-
</div>
129-
</section>
130-
}
131-
}
132-
133-
#[cfg_attr(debug_assertions, component)]
134-
#[cfg(debug_assertions)]
135-
pub fn Contributors() -> impl IntoView {
136-
let contributors = [Contributor {
137-
login: "Phosphorus-M".to_owned(),
138-
avatar_url: "https://avatars.githubusercontent.com/u/19656993?v=4".to_owned(),
139-
url: "https://github.com/Phosphorus-M".to_owned(),
140-
bio: None,
141-
twitter_username: Some("Phosphorus_M".to_owned()),
142-
location: Some("Argentina".to_owned()),
143-
contributions_collection: ContributionCollection {
144-
total_commit_contributions: 499,
145-
},
146-
},
147-
Contributor {
148-
login: "SergioRibera".to_owned(),
149-
avatar_url: "https://avatars.githubusercontent.com/u/56278796?u=9e3dac947b4fd3ca2f1a05024e083c64e4c69cfe&v=4".to_owned(),
150-
url: "https://github.com/SergioRibera".to_owned(),
151-
bio: Some("22yo Rustacean and Open Source lover\r\nI teach, Promote and Give Technical talks of rust with @RustLangES".to_owned()),
152-
twitter_username: Some("sergioribera_rs".to_owned()),
153-
location: Some("Santa Cruz de la Sierra, Bolivia".to_owned()),
154-
contributions_collection: ContributionCollection {
155-
total_commit_contributions: 2015
156-
}
157-
}];
158131
let contributorMapper = |item: &Contributor| {
159132
view! {
160133
<ContributorCard
@@ -164,21 +137,23 @@ pub fn Contributors() -> impl IntoView {
164137
brand_src=item.avatar_url.clone()
165138
twitter=item.twitter_username.clone()
166139
location=item.location.clone()
167-
contributions=item.contributions_collection.total_commit_contributions
140+
contributions=item.contributions_collection.as_ref().map(|c| c.commits).unwrap_or(1)
168141
/>
169142
}
170143
};
171144

172145
let contributors_view = move || {
173146
let result = contributors
147+
.get()?
148+
.ok()?
174149
.iter()
175150
.map(contributorMapper)
176151
.collect::<Fragment>();
177152
Some(result.into_view())
178153
};
179154

180155
view! {
181-
<section class="bg-orange-300/30 dark:bg-transparent py-16">
156+
<section class="bg-orange-300/30 dark:bg-transparent py-16 min-h-[80vh]">
182157
<div class="flex flex-col gap-y-6 container mx-auto px-4">
183158
<h2 class="text-3xl text-left mb-6">
184159
<span class="font-work-sans font-light">"Nuestros "</span>

0 commit comments

Comments
 (0)