Skip to content

Commit 0564859

Browse files
committed
Add owners and list crates by owners
1 parent 596d75a commit 0564859

File tree

4 files changed

+116
-40
lines changed

4 files changed

+116
-40
lines changed

src/web/crate_details.rs

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct CrateDetails {
2424
version: String,
2525
description: Option<String>,
2626
authors: Vec<(String, String)>,
27+
owners: Vec<(String, String)>,
2728
authors_json: Option<Json>,
2829
dependencies: Option<Json>,
2930
readme: Option<String>,
@@ -53,6 +54,7 @@ impl ToJson for CrateDetails {
5354
m.insert("version".to_string(), self.version.to_json());
5455
m.insert("description".to_string(), self.description.to_json());
5556
m.insert("authors".to_string(), self.authors.to_json());
57+
m.insert("owners".to_string(), self.owners.to_json());
5658
m.insert("authors_json".to_string(), self.authors_json.to_json());
5759
m.insert("dependencies".to_string(), self.dependencies.to_json());
5860
if let Some(ref readme) = self.readme {
@@ -86,7 +88,9 @@ impl CrateDetails {
8688
fn new(conn: &Connection, name: &str, version: &str) -> Option<CrateDetails> {
8789

8890
// get all stuff, I love you rustfmt
89-
let query = "SELECT crates.name, \
91+
let query = "SELECT crates.id, \
92+
releases.id, \
93+
crates.name, \
9094
releases.version, \
9195
releases.description, \
9296
releases.authors, \
@@ -102,16 +106,12 @@ impl CrateDetails {
102106
releases.have_examples, \
103107
releases.target_name, \
104108
crates.versions, \
105-
authors.name, \
106-
authors.slug, \
107109
crates.github_stars, \
108110
crates.github_forks, \
109111
crates.github_issues, \
110112
releases.is_library \
111-
FROM author_rels \
112-
LEFT OUTER JOIN authors ON authors.id = author_rels.aid \
113-
LEFT OUTER JOIN releases ON releases.id = author_rels.rid \
114-
LEFT OUTER JOIN crates ON crates.id = releases.crate_id \
113+
FROM releases \
114+
INNER JOIN crates ON releases.crate_id = crates.id \
115115
WHERE crates.name = $1 AND releases.version = $2;";
116116

117117
let rows = conn.query(query, &[&name, &version]).unwrap();
@@ -120,10 +120,13 @@ impl CrateDetails {
120120
return None;
121121
}
122122

123+
let crate_id: i32 = rows.get(0).get(0);
124+
let release_id: i32 = rows.get(0).get(1);
125+
123126
// sort versions with semver
124127
let versions = {
125128
let mut versions: Vec<semver::Version> = Vec::new();
126-
let versions_from_db: Json = rows.get(0).get(15);
129+
let versions_from_db: Json = rows.get(0).get(17);
127130

128131
versions_from_db.as_array().map(|vers| {
129132
for version in vers {
@@ -141,30 +144,31 @@ impl CrateDetails {
141144
};
142145

143146
let metadata = MetaData {
144-
name: rows.get(0).get(0),
145-
version: rows.get(0).get(1),
146-
description: rows.get(0).get(2),
147-
rustdoc_status: rows.get(0).get(9),
148-
target_name: rows.get(0).get(14),
147+
name: rows.get(0).get(2),
148+
version: rows.get(0).get(3),
149+
description: rows.get(0).get(4),
150+
rustdoc_status: rows.get(0).get(11),
151+
target_name: rows.get(0).get(16),
149152
};
150153

151154
let mut crate_details = CrateDetails {
152-
name: rows.get(0).get(0),
153-
version: rows.get(0).get(1),
154-
description: rows.get(0).get(2),
155+
name: rows.get(0).get(2),
156+
version: rows.get(0).get(3),
157+
description: rows.get(0).get(4),
155158
authors: Vec::new(),
156-
authors_json: rows.get(0).get(3),
157-
dependencies: rows.get(0).get(4),
158-
readme: rows.get(0).get(5),
159-
rustdoc: rows.get(0).get(6),
160-
release_time: rows.get(0).get(7),
161-
build_status: rows.get(0).get(8),
162-
rustdoc_status: rows.get(0).get(9),
163-
repository_url: rows.get(0).get(10),
164-
homepage_url: rows.get(0).get(11),
165-
keywords: rows.get(0).get(12),
166-
have_examples: rows.get(0).get(13),
167-
target_name: rows.get(0).get(14),
159+
owners: Vec::new(),
160+
authors_json: rows.get(0).get(5),
161+
dependencies: rows.get(0).get(6),
162+
readme: rows.get(0).get(7),
163+
rustdoc: rows.get(0).get(8),
164+
release_time: rows.get(0).get(9),
165+
build_status: rows.get(0).get(10),
166+
rustdoc_status: rows.get(0).get(11),
167+
repository_url: rows.get(0).get(12),
168+
homepage_url: rows.get(0).get(13),
169+
keywords: rows.get(0).get(14),
170+
have_examples: rows.get(0).get(15),
171+
target_name: rows.get(0).get(16),
168172
versions: versions,
169173
github: false,
170174
github_stars: rows.get(0).get(18),
@@ -179,9 +183,20 @@ impl CrateDetails {
179183
repository_url.starts_with("https://github.com");
180184
}
181185

182-
// Insert authors with name and slug
183-
for row in &rows {
184-
crate_details.authors.push((row.get(16), row.get(17)));
186+
// get authors
187+
for row in &conn.query("SELECT name, slug
188+
FROM authors
189+
INNER JOIN author_rels ON author_rels.aid = authors.id
190+
WHERE rid = $1", &[&release_id]).unwrap() {
191+
crate_details.authors.push((row.get(0), row.get(1)));
192+
}
193+
194+
// get owners
195+
for row in &conn.query("SELECT login, avatar
196+
FROM owners
197+
INNER JOIN owner_rels ON owner_rels.oid = owners.id
198+
WHERE cid = $1", &[&crate_id]).unwrap() {
199+
crate_details.owners.push((row.get(0), row.get(1)));
185200
}
186201

187202
Some(crate_details)

src/web/releases.rs

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,52 @@ fn get_releases_by_author(conn: &Connection,
169169

170170

171171

172+
fn get_releases_by_owner(conn: &Connection,
173+
page: i64,
174+
limit: i64,
175+
author: &str)
176+
-> (String, Vec<Release>) {
177+
178+
let offset = (page - 1) * limit;
179+
180+
let query = "SELECT crates.name,
181+
releases.version,
182+
releases.description,
183+
releases.target_name,
184+
releases.release_time,
185+
releases.rustdoc_status,
186+
crates.github_stars,
187+
owners.login
188+
FROM crates
189+
INNER JOIN releases ON releases.id = crates.latest_version_id
190+
INNER JOIN owner_rels ON owner_rels.cid = crates.id
191+
INNER JOIN owners ON owners.id = owner_rels.oid
192+
WHERE owners.login = $1
193+
ORDER BY crates.github_stars DESC
194+
LIMIT $2 OFFSET $3";
195+
196+
let mut author_name = String::new();
197+
let mut packages = Vec::new();
198+
for row in &conn.query(&query, &[&author, &limit, &offset]).unwrap() {
199+
let package = Release {
200+
name: row.get(0),
201+
version: row.get(1),
202+
description: row.get(2),
203+
target_name: row.get(3),
204+
release_time: row.get(4),
205+
rustdoc_status: row.get(5),
206+
stars: row.get(6),
207+
};
208+
209+
author_name = row.get(7);
210+
packages.push(package);
211+
}
212+
213+
(author_name, packages)
214+
}
215+
216+
217+
172218
fn get_search_results(conn: &Connection,
173219
query: &str,
174220
page: i64,
@@ -315,14 +361,18 @@ pub fn author_handler(req: &mut Request) -> IronResult<Response> {
315361
.unwrap_or(1);
316362

317363
let conn = req.extensions.get::<Pool>().unwrap();
318-
let author = req.extensions.get::<Router>().unwrap().find("author");
319-
320-
if author.is_none() {
321-
return Err(IronError::new(Nope::CrateNotFound, status::NotFound));
322-
}
364+
let author = try!(req.extensions
365+
.get::<Router>()
366+
.unwrap()
367+
.find("author")
368+
.ok_or(IronError::new(Nope::CrateNotFound, status::NotFound)));
323369

324-
let (author_name, packages) =
325-
get_releases_by_author(conn, page_number, RELEASES_IN_RELEASES, author.unwrap());
370+
let (author_name, packages) = if author.starts_with("@") {
371+
let mut author = author.clone().split("@");
372+
get_releases_by_owner(conn, page_number, RELEASES_IN_RELEASES, author.nth(1).unwrap())
373+
} else {
374+
get_releases_by_author(conn, page_number, RELEASES_IN_RELEASES, author)
375+
};
326376

327377
if packages.is_empty() {
328378
return Err(IronError::new(Nope::CrateNotFound, status::NotFound));
@@ -332,12 +382,11 @@ pub fn author_handler(req: &mut Request) -> IronResult<Response> {
332382
// This is a temporary solution to avoid expensive COUNT(*)
333383
let (show_next_page, show_previous_page) = (packages.len() == RELEASES_IN_RELEASES as usize,
334384
page_number != 1);
335-
336385
Page::new(packages)
337386
.title("Releases")
338387
.set("description", &format!("Crates from {}", author_name))
339388
.set("author", &author_name)
340-
.set("release_type", &author.unwrap())
389+
.set("release_type", author)
341390
.set_true("show_releases_navigation")
342391
.set_true("show_stars")
343392
.set_bool("show_next_page_button", show_next_page)

templates/crate_details.hbs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@
4040
</ul>
4141
</div>
4242
</li>
43+
<li class="pure-menu-heading">Owners</li>
44+
<li class="pure-menu-item">
45+
{{#each owners}}
46+
<a href="/releases/@{{this.[0]}}"><img src="{{this.[1]}}" alt="{{this.[0]}}" class="owner"></a>
47+
{{/each}}
48+
</li>
4349
</ul>
4450
</div>
4551
</div>

templates/style.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,12 @@ div.package-page-container {
349349
border-bottom: none;
350350
}
351351
}
352+
353+
img.owner {
354+
max-width: 32px;
355+
max-height: 32px;
356+
border-radius: 2px;
357+
}
352358
}
353359

354360
div.package-details {

0 commit comments

Comments
 (0)