Skip to content

Commit 1608869

Browse files
committed
Auto merge of #1947 - markcatley:version-owner-actions-view, r=carols10cents
Add Verions Owner Actions to the API Contributes to Issue #1548
2 parents 1c0ee97 + 88f8aaf commit 1608869

File tree

8 files changed

+172
-86
lines changed

8 files changed

+172
-86
lines changed

src/controllers/krate/metadata.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use crate::controllers::frontend_prelude::*;
88
use crate::models::{
99
Category, Crate, CrateCategory, CrateKeyword, CrateVersions, Keyword, RecentCrateDownloads,
10-
User, Version,
10+
User, Version, VersionOwnerAction,
1111
};
1212
use crate::schema::*;
1313
use crate::views::{
@@ -105,13 +105,26 @@ pub fn show(req: &mut dyn Request) -> AppResult<Response> {
105105
let conn = req.db_conn()?;
106106
let krate = Crate::by_name(name).first::<Crate>(&*conn)?;
107107

108-
let mut versions_and_publishers: Vec<(Version, Option<User>)> = krate
108+
let mut versions_and_publishers = krate
109109
.all_versions()
110110
.left_outer_join(users::table)
111111
.select((versions::all_columns, users::all_columns.nullable()))
112-
.load(&*conn)?;
112+
.load::<(Version, Option<User>)>(&*conn)?;
113113
versions_and_publishers.sort_by(|a, b| b.0.num.cmp(&a.0.num));
114-
let ids = versions_and_publishers.iter().map(|v| v.0.id).collect();
114+
let versions = versions_and_publishers
115+
.iter()
116+
.map(|(v, _)| v)
117+
.cloned()
118+
.collect::<Vec<_>>();
119+
let versions_publishers_and_audit_actions = versions_and_publishers
120+
.into_iter()
121+
.zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
122+
.map(|((v, pb), aas)| (v, pb, aas))
123+
.collect::<Vec<_>>();
124+
let ids = versions_publishers_and_audit_actions
125+
.iter()
126+
.map(|v| v.0.id)
127+
.collect();
115128

116129
let kws = CrateKeyword::belonging_to(&krate)
117130
.inner_join(keywords::table)
@@ -149,9 +162,9 @@ pub fn show(req: &mut dyn Request) -> AppResult<Response> {
149162
false,
150163
recent_downloads,
151164
),
152-
versions: versions_and_publishers
165+
versions: versions_publishers_and_audit_actions
153166
.into_iter()
154-
.map(|(v, pb)| v.encodable(&krate.name, pb))
167+
.map(|(v, pb, aas)| v.encodable(&krate.name, pb, aas))
155168
.collect(),
156169
keywords: kws.into_iter().map(Keyword::encodable).collect(),
157170
categories: cats.into_iter().map(Category::encodable).collect(),
@@ -193,9 +206,15 @@ pub fn versions(req: &mut dyn Request) -> AppResult<Response> {
193206
.select((versions::all_columns, users::all_columns.nullable()))
194207
.load(&*conn)?;
195208
versions_and_publishers.sort_by(|a, b| b.0.num.cmp(&a.0.num));
209+
let versions = versions_and_publishers
210+
.iter()
211+
.map(|(v, _)| v)
212+
.cloned()
213+
.collect::<Vec<_>>();
196214
let versions = versions_and_publishers
197215
.into_iter()
198-
.map(|(v, pb)| v.encodable(crate_name, pb))
216+
.zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
217+
.map(|((v, pb), aas)| v.encodable(crate_name, pb, aas))
199218
.collect();
200219

201220
#[derive(Serialize)]
@@ -220,7 +239,7 @@ pub fn reverse_dependencies(req: &mut dyn Request) -> AppResult<Response> {
220239

221240
let version_ids: Vec<i32> = rev_deps.iter().map(|dep| dep.version_id).collect();
222241

223-
let versions = versions::table
242+
let versions_and_publishers = versions::table
224243
.filter(versions::id.eq(any(version_ids)))
225244
.inner_join(crates::table)
226245
.left_outer_join(users::table)
@@ -229,9 +248,18 @@ pub fn reverse_dependencies(req: &mut dyn Request) -> AppResult<Response> {
229248
crates::name,
230249
users::all_columns.nullable(),
231250
))
232-
.load::<(Version, String, Option<User>)>(&*conn)?
251+
.load::<(Version, String, Option<User>)>(&*conn)?;
252+
let versions = versions_and_publishers
253+
.iter()
254+
.map(|(v, _, _)| v)
255+
.cloned()
256+
.collect::<Vec<_>>();
257+
let versions = versions_and_publishers
233258
.into_iter()
234-
.map(|(version, krate_name, user)| version.encodable(&krate_name, user))
259+
.zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
260+
.map(|((version, krate_name, published_by), actions)| {
261+
version.encodable(&krate_name, published_by, actions)
262+
})
235263
.collect();
236264

237265
#[derive(Serialize)]

src/controllers/user/me.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use crate::controllers::helpers::*;
66
use crate::email;
77
use crate::util::errors::AppError;
88

9-
use crate::models::{CrateOwner, Email, Follow, NewEmail, OwnerKind, User, Version};
9+
use crate::models::{
10+
CrateOwner, Email, Follow, NewEmail, OwnerKind, User, Version, VersionOwnerAction,
11+
};
1012
use crate::schema::{crate_owners, crates, emails, follows, users, versions};
1113
use crate::views::{EncodableMe, EncodableVersion, OwnedCrate};
1214

@@ -79,12 +81,19 @@ pub fn updates(req: &mut dyn Request) -> AppResult<Response> {
7981
))
8082
.paginate(&req.query())?
8183
.load::<(Version, String, Option<User>)>(&*conn)?;
82-
8384
let more = data.next_page_params().is_some();
85+
let versions = data.iter().map(|(v, _, _)| v).cloned().collect::<Vec<_>>();
86+
let data = data
87+
.into_iter()
88+
.zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
89+
.map(|((v, cn, pb), voas)| (v, cn, pb, voas))
90+
.collect::<Vec<_>>();
8491

8592
let versions = data
8693
.into_iter()
87-
.map(|(version, crate_name, published_by)| version.encodable(&crate_name, published_by))
94+
.map(|(version, crate_name, published_by, actions)| {
95+
version.encodable(&crate_name, published_by, actions)
96+
})
8897
.collect();
8998

9099
#[derive(Serialize)]
@@ -233,7 +242,7 @@ pub fn update_email_notifications(req: &mut dyn Request) -> AppResult<Response>
233242
let user = req.user()?;
234243
let conn = req.db_conn()?;
235244

236-
// Build inserts from existing crates beloning to the current user
245+
// Build inserts from existing crates belonging to the current user
237246
let to_insert = CrateOwner::by_owner_kind(OwnerKind::User)
238247
.filter(owner_id.eq(user.id))
239248
.select((crate_id, owner_id, owner_kind, email_notifications))

src/controllers/version/deprecated.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
88
use crate::controllers::frontend_prelude::*;
99

10-
use crate::models::{Crate, User, Version};
10+
use crate::models::{Crate, User, Version, VersionOwnerAction};
1111
use crate::schema::*;
1212
use crate::views::EncodableVersion;
1313

@@ -22,7 +22,7 @@ pub fn index(req: &mut dyn Request) -> AppResult<Response> {
2222
.filter_map(|(ref a, ref b)| if *a == "ids[]" { b.parse().ok() } else { None })
2323
.collect::<Vec<i32>>();
2424

25-
let versions = versions::table
25+
let versions_and_publishers = versions::table
2626
.inner_join(crates::table)
2727
.left_outer_join(users::table)
2828
.select((
@@ -31,9 +31,18 @@ pub fn index(req: &mut dyn Request) -> AppResult<Response> {
3131
users::all_columns.nullable(),
3232
))
3333
.filter(versions::id.eq(any(ids)))
34-
.load::<(Version, String, Option<User>)>(&*conn)?
34+
.load::<(Version, String, Option<User>)>(&*conn)?;
35+
let versions = versions_and_publishers
36+
.iter()
37+
.map(|(v, _, _)| v)
38+
.cloned()
39+
.collect::<Vec<_>>();
40+
let versions = versions_and_publishers
3541
.into_iter()
36-
.map(|(version, crate_name, published_by)| version.encodable(&crate_name, published_by))
42+
.zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
43+
.map(|((version, crate_name, published_by), actions)| {
44+
version.encodable(&crate_name, published_by, actions)
45+
})
3746
.collect();
3847

3948
#[derive(Serialize)]
@@ -60,12 +69,13 @@ pub fn show_by_id(req: &mut dyn Request) -> AppResult<Response> {
6069
users::all_columns.nullable(),
6170
))
6271
.first(&*conn)?;
72+
let audit_actions = VersionOwnerAction::by_version(&conn, &version)?;
6373

6474
#[derive(Serialize)]
6575
struct R {
6676
version: EncodableVersion,
6777
}
6878
Ok(req.json(&R {
69-
version: version.encodable(&krate.name, published_by),
79+
version: version.encodable(&krate.name, published_by, audit_actions),
7080
}))
7181
}

src/controllers/version/metadata.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
use crate::controllers::frontend_prelude::*;
88

9+
use crate::models::VersionOwnerAction;
910
use crate::schema::*;
1011
use crate::views::{EncodableDependency, EncodablePublicUser, EncodableVersion};
1112

@@ -70,12 +71,13 @@ pub fn show(req: &mut dyn Request) -> AppResult<Response> {
7071
let (version, krate) = version_and_crate(req)?;
7172
let conn = req.db_conn()?;
7273
let published_by = version.published_by(&conn);
74+
let actions = VersionOwnerAction::by_version(&conn, &version)?;
7375

7476
#[derive(Serialize)]
7577
struct R {
7678
version: EncodableVersion,
7779
}
7880
Ok(req.json(&R {
79-
version: version.encodable(&krate.name, published_by),
81+
version: version.encodable(&krate.name, published_by, actions),
8082
}))
8183
}

src/models/action.rs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,24 @@ pub enum VersionAction {
2020
Unyank = 2,
2121
}
2222

23+
impl Into<&'static str> for VersionAction {
24+
fn into(self) -> &'static str {
25+
match self {
26+
VersionAction::Publish => "publish",
27+
VersionAction::Yank => "yank",
28+
VersionAction::Unyank => "unyank",
29+
}
30+
}
31+
}
32+
33+
impl Into<String> for VersionAction {
34+
fn into(self) -> String {
35+
let string: &'static str = self.into();
36+
37+
string.into()
38+
}
39+
}
40+
2341
impl FromSql<Integer, Pg> for VersionAction {
2442
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
2543
match <i32 as FromSql<Integer, Pg>>::from_sql(bytes)? {
@@ -52,22 +70,30 @@ pub struct VersionOwnerAction {
5270
}
5371

5472
impl VersionOwnerAction {
55-
pub fn all(conn: &PgConnection) -> QueryResult<Vec<VersionOwnerAction>> {
73+
pub fn all(conn: &PgConnection) -> QueryResult<Vec<Self>> {
5674
version_owner_actions::table.load(conn)
5775
}
5876

59-
pub fn by_version_id_and_action(
60-
conn: &PgConnection,
61-
version_id_: i32,
62-
action_: VersionAction,
63-
) -> QueryResult<Vec<VersionOwnerAction>> {
64-
use version_owner_actions::dsl::{action, version_id};
77+
pub fn by_version(conn: &PgConnection, version: &Version) -> QueryResult<Vec<(Self, User)>> {
78+
use version_owner_actions::dsl::version_id;
6579

6680
version_owner_actions::table
67-
.filter(version_id.eq(version_id_))
68-
.filter(action.eq(action_))
81+
.filter(version_id.eq(version.id))
82+
.inner_join(users::table)
83+
.order(version_owner_actions::dsl::id)
6984
.load(conn)
7085
}
86+
87+
pub fn for_versions(
88+
conn: &PgConnection,
89+
versions: &[Version],
90+
) -> QueryResult<Vec<Vec<(Self, User)>>> {
91+
Ok(Self::belonging_to(versions)
92+
.inner_join(users::table)
93+
.order(version_owner_actions::dsl::id)
94+
.load::<(VersionOwnerAction, User)>(conn)?
95+
.grouped_by(versions))
96+
}
7197
}
7298

7399
pub fn insert_version_owner_action(

src/models/version.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use diesel::prelude::*;
55

66
use crate::util::{cargo_err, AppResult};
77

8-
use crate::models::{Crate, Dependency, User};
8+
use crate::models::{Crate, Dependency, User, VersionOwnerAction};
99
use crate::schema::*;
10-
use crate::views::{EncodableVersion, EncodableVersionLinks};
10+
use crate::views::{EncodableAuditAction, EncodableVersion, EncodableVersionLinks};
1111

1212
// Queryable has a custom implementation below
1313
#[derive(Clone, Identifiable, Associations, Debug, Queryable, Deserialize, Serialize)]
@@ -38,7 +38,12 @@ pub struct NewVersion {
3838
}
3939

4040
impl Version {
41-
pub fn encodable(self, crate_name: &str, published_by: Option<User>) -> EncodableVersion {
41+
pub fn encodable(
42+
self,
43+
crate_name: &str,
44+
published_by: Option<User>,
45+
audit_actions: Vec<(VersionOwnerAction, User)>,
46+
) -> EncodableVersion {
4247
let Version {
4348
id,
4449
num,
@@ -71,6 +76,14 @@ impl Version {
7176
},
7277
crate_size,
7378
published_by: published_by.map(User::encodable_public),
79+
audit_actions: audit_actions
80+
.into_iter()
81+
.map(|(audit_action, user)| EncodableAuditAction {
82+
action: audit_action.action.into(),
83+
user: User::encodable_public(user),
84+
time: audit_action.time,
85+
})
86+
.collect(),
7487
}
7588
}
7689

0 commit comments

Comments
 (0)