Skip to content

More MVC Refactoring #1255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,70 +1,10 @@
use chrono::NaiveDateTime;
use conduit::{Request, Response};
use diesel::prelude::*;
use serde_json;

use db::RequestTransaction;
use user::RequestUser;
use util::errors::{human, CargoResult};
use util::RequestUtils;

use models::{CrateOwner, OwnerKind};
use schema::{crate_owner_invitations, crate_owners, crates, users};

/// The model representing a row in the `crate_owner_invitations` database table.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Identifiable, Queryable)]
#[primary_key(invited_user_id, crate_id)]
pub struct CrateOwnerInvitation {
pub invited_user_id: i32,
pub invited_by_user_id: i32,
pub crate_id: i32,
pub created_at: NaiveDateTime,
}

#[derive(Insertable, Clone, Copy, Debug)]
#[table_name = "crate_owner_invitations"]
pub struct NewCrateOwnerInvitation {
pub invited_user_id: i32,
pub invited_by_user_id: i32,
pub crate_id: i32,
}
use super::prelude::*;

impl CrateOwnerInvitation {
pub fn invited_by_username(&self, conn: &PgConnection) -> String {
users::table
.find(self.invited_by_user_id)
.select(users::gh_login)
.first(&*conn)
.unwrap_or_else(|_| String::from("(unknown username)"))
}

pub fn crate_name(&self, conn: &PgConnection) -> String {
crates::table
.find(self.crate_id)
.select(crates::name)
.first(&*conn)
.unwrap_or_else(|_| String::from("(unknown crate name)"))
}

pub fn encodable(self, conn: &PgConnection) -> EncodableCrateOwnerInvitation {
EncodableCrateOwnerInvitation {
invited_by_username: self.invited_by_username(conn),
crate_name: self.crate_name(conn),
crate_id: self.crate_id,
created_at: self.created_at,
}
}
}
use serde_json;

/// The serialization format for the `CrateOwnerInvitation` model.
#[derive(Deserialize, Serialize, Debug)]
pub struct EncodableCrateOwnerInvitation {
pub invited_by_username: String,
pub crate_name: String,
pub crate_id: i32,
#[serde(with = "::util::rfc3339")]
pub created_at: NaiveDateTime,
}
use models::{CrateOwner, CrateOwnerInvitation, OwnerKind};
use schema::{crate_owner_invitations, crate_owners};
use views::{EncodableCrateOwnerInvitation, InvitationResponse};

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut Request) -> CargoResult<Response> {
Expand Down Expand Up @@ -92,12 +32,6 @@ struct OwnerInvitation {
crate_owner_invite: InvitationResponse,
}

#[derive(Deserialize, Serialize, Debug, Copy, Clone)]
pub struct InvitationResponse {
pub crate_id: i32,
pub accepted: bool,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut Request) -> CargoResult<Response> {
let conn = &*req.db_conn()?;
Expand Down Expand Up @@ -175,27 +109,3 @@ fn decline_invite(
crate_owner_invitation: crate_invite,
}))
}

#[cfg(test)]
mod tests {
use super::*;
use chrono::NaiveDate;
use serde_json;

#[test]
fn crate_owner_invitation_serializes_to_rfc3339() {
let inv = EncodableCrateOwnerInvitation {
invited_by_username: "".to_string(),
crate_name: "".to_string(),
crate_id: 123,
created_at: NaiveDate::from_ymd(2017, 1, 6).and_hms(14, 23, 11),
};
let json = serde_json::to_string(&inv).unwrap();
assert!(
json.as_str()
.find(r#""created_at":"2017-01-06T14:23:11+00:00""#)
.is_some()
);
}

}
12 changes: 12 additions & 0 deletions src/controllers/helpers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
use conduit::Response;
use util::{json_response, CargoResult};

pub mod pagination;

pub use self::pagination::Paginate;

pub fn ok_true() -> CargoResult<Response> {
#[derive(Serialize)]
struct R {
ok: bool,
}

Ok(json_response(&R { ok: true }))
}
12 changes: 3 additions & 9 deletions src/krate/downloads.rs → src/controllers/krate/downloads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,13 @@
//! download counts are located in `krate::downloads`.

use std::cmp;

use conduit::{Request, Response};
use conduit_router::RequestParams;
use diesel::prelude::*;

use db::RequestTransaction;
use util::{CargoResult, RequestUtils};
use controllers::prelude::*;

use views::EncodableVersionDownload;
use models::{Crate, Version, VersionDownload};
use schema::*;
use schema::version_downloads;

use super::to_char;
use models::krate::to_char;

/// Handles the `GET /crates/:crate_id/downloads` route.
pub fn downloads(req: &mut Request) -> CargoResult<Response> {
Expand Down
23 changes: 6 additions & 17 deletions src/krate/follow.rs → src/controllers/krate/follow.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
//! Endpoints for managing a per user list of followed crates

use conduit::{Request, Response};
use conduit_router::RequestParams;
use diesel::associations::Identifiable;
use diesel::prelude::*;
use diesel;

use db::RequestTransaction;
use user::RequestUser;
use util::{CargoResult, RequestUtils};

use controllers::prelude::*;
use models::{Crate, Follow};
use schema::*;

Expand All @@ -32,23 +26,17 @@ pub fn follow(req: &mut Request) -> CargoResult<Response> {
.values(&follow)
.on_conflict_do_nothing()
.execute(&*conn)?;
#[derive(Serialize)]
struct R {
ok: bool,
}
Ok(req.json(&R { ok: true }))

ok_true()
}

/// Handles the `DELETE /crates/:crate_id/follow` route.
pub fn unfollow(req: &mut Request) -> CargoResult<Response> {
let follow = follow_target(req)?;
let conn = req.db_conn()?;
diesel::delete(&follow).execute(&*conn)?;
#[derive(Serialize)]
struct R {
ok: bool,
}
Ok(req.json(&R { ok: true }))

ok_true()
}

/// Handles the `GET /crates/:crate_id/following` route.
Expand All @@ -58,6 +46,7 @@ pub fn following(req: &mut Request) -> CargoResult<Response> {
let follow = follow_target(req)?;
let conn = req.db_conn()?;
let following = diesel::select(exists(follows::table.find(follow.id()))).get_result(&*conn)?;

#[derive(Serialize)]
struct R {
following: bool,
Expand Down
9 changes: 2 additions & 7 deletions src/krate/metadata.rs → src/controllers/krate/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,15 @@
//! index or cached metadata which was extracted (client side) from the
//! `Cargo.toml` file.

use conduit::{Request, Response};
use conduit_router::RequestParams;
use diesel::prelude::*;

use app::RequestApp;
use db::RequestTransaction;
use util::{human, CargoResult, RequestUtils};

use controllers::prelude::*;
use views::{EncodableCategory, EncodableCrate, EncodableDependency, EncodableKeyword,
EncodableVersion};
use models::{Category, Crate, CrateCategory, CrateDownload, CrateKeyword, Keyword, Version};
use schema::*;

use super::ALL_COLUMNS;
use models::krate::ALL_COLUMNS;

/// Handles the `GET /summary` route.
pub fn summary(req: &mut Request) -> CargoResult<Response> {
Expand Down
6 changes: 6 additions & 0 deletions src/controllers/krate/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod search;
pub mod publish;
pub mod owners;
pub mod follow;
pub mod downloads;
pub mod metadata;
12 changes: 2 additions & 10 deletions src/krate/owners.rs → src/controllers/krate/owners.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
//! All routes related to managing owners of a crate
use conduit::{Request, Response};
use conduit_router::RequestParams;
use diesel::prelude::*;
use serde_json;

use app::RequestApp;
use db::RequestTransaction;
use owner::rights;
use user::RequestUser;
use util::{human, CargoResult, RequestUtils};

use controllers::prelude::*;
use views::EncodableOwner;
use models::{Crate, Owner, Rights, Team, User};

Expand Down Expand Up @@ -85,7 +77,7 @@ fn modify_owners(req: &mut Request, add: bool) -> CargoResult<Response> {
let krate = Crate::by_name(&req.params()["crate_id"]).first::<Crate>(&*conn)?;
let owners = krate.owners(&conn)?;

match rights(req.app(), &owners, user)? {
match user.rights(req.app(), &owners)? {
Rights::Full => {}
// Yes!
Rights::Publish => {
Expand Down
14 changes: 4 additions & 10 deletions src/krate/publish.rs → src/controllers/krate/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,17 @@ use std::cmp;
use std::collections::HashMap;
use std::sync::Arc;

use conduit::{Request, Response};
use diesel::prelude::*;
use hex::ToHex;
use serde_json;

use app::RequestApp;
use db::RequestTransaction;
use dependency;
use git;
use owner::rights;
use render;
use user::RequestUser;
use util::{read_fill, read_le_u32};
use util::{human, internal, CargoResult, ChainError, RequestUtils};
use util::{internal, ChainError};

use views::EncodableCrate;
use views::EncodableCrateUpload;
use controllers::prelude::*;
use views::{EncodableCrate, EncodableCrateUpload};
use models::{Badge, Category, Keyword, NewCrate, NewVersion, Rights, User};

/// Handles the `PUT /crates/new` route.
Expand Down Expand Up @@ -77,7 +71,7 @@ pub fn publish(req: &mut Request) -> CargoResult<Response> {
let krate = persist.create_or_update(&conn, license_file, user.id)?;

let owners = krate.owners(&conn)?;
if rights(req.app(), &owners, &user)? < Rights::Publish {
if user.rights(req.app(), &owners)? < Rights::Publish {
return Err(human(
"this crate exists but you don't seem to be an owner. \
If you believe this is a mistake, perhaps you need \
Expand Down
9 changes: 2 additions & 7 deletions src/krate/search.rs → src/controllers/krate/search.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
//! Endpoint for searching and discovery functionality
use conduit::{Request, Response};
use diesel::prelude::*;
use diesel_full_text_search::*;

use db::RequestTransaction;
use controllers::helpers::Paginate;
use user::RequestUser;
use util::{CargoResult, RequestUtils};

use controllers::prelude::*;
use views::EncodableCrate;
use models::{Badge, Crate, OwnerKind, Version};
use schema::*;

use super::{canon_crate_name, ALL_COLUMNS};
use models::krate::{canon_crate_name, ALL_COLUMNS};

/// Handles the `GET /crates` route.
/// Returns a list of crates. Called in a variety of scenarios in the
Expand Down
7 changes: 6 additions & 1 deletion src/controllers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@

mod prelude {
pub use diesel::prelude::*;
pub use super::helpers::ok_true;

pub use app::RequestApp;
pub use conduit::{Request, Response};
pub use conduit_router::RequestParams;
pub use db::RequestTransaction;
pub use util::{CargoResult, RequestUtils};
pub use user::RequestUser;
pub use util::{human, CargoResult, RequestUtils};
}

pub mod helpers;

pub mod category;
pub mod crate_owner_invitation;
pub mod keyword;
pub mod krate;
9 changes: 9 additions & 0 deletions src/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,12 @@ pub fn token(token: String) -> Token {
token_type: String::new(),
}
}

pub fn team_url(login: &str) -> String {
let mut login_pieces = login.split(':');
login_pieces.next();
format!(
"https://github.com/{}",
login_pieces.next().expect("org failed"),
)
}
Loading