From 68c7aad1794f72de15acd015b651ee1cca3892a2 Mon Sep 17 00:00:00 2001 From: Bat Date: Sat, 23 Jun 2018 17:36:11 +0100 Subject: [PATCH] Big repository reorganization The code is divided in three crates: - plume-common, for the ActivityPub module, and some common utils - plume-models, for the models and database-related code - plume, the app itself This new organization will allow to test it more easily, but also to create other tools that only reuse a little part of the code (for instance a Wordpress import tool, that would just use the plume-models crate) --- Cargo.lock | 57 +++++++++++++---- Cargo.toml | 31 +++------ plume-common/Cargo.toml | 61 ++++++++++++++++++ plume-common/src/activity_pub/inbox.rs | 41 ++++++++++++ {src => plume-common/src}/activity_pub/mod.rs | 0 .../src}/activity_pub/request.rs | 0 .../src}/activity_pub/sign.rs | 0 plume-common/src/lib.rs | 28 ++++++++ {src => plume-common/src}/utils.rs | 0 plume-models/Cargo.toml | 64 +++++++++++++++++++ .../src}/blog_authors.rs | 0 {src/models => plume-models/src}/blogs.rs | 4 +- {src/models => plume-models/src}/comments.rs | 22 +++---- {src => plume-models/src}/db_conn.rs | 4 +- {src/models => plume-models/src}/follows.rs | 14 ++-- {src/models => plume-models/src}/instance.rs | 6 +- src/models/mod.rs => plume-models/src/lib.rs | 34 ++++++++++ {src/models => plume-models/src}/likes.rs | 16 ++--- {src/models => plume-models/src}/mentions.rs | 14 ++-- .../src}/notifications.rs | 2 +- .../src}/post_authors.rs | 6 +- {src/models => plume-models/src}/posts.rs | 20 +++--- {src/models => plume-models/src}/reshares.rs | 12 ++-- {src => plume-models/src}/safe_string.rs | 0 {src => plume-models/src}/schema.rs | 0 {src/models => plume-models/src}/users.rs | 32 ++++------ src/{activity_pub => }/inbox.rs | 58 +++-------------- src/main.rs | 52 +++------------ src/routes/blogs.rs | 8 +-- src/routes/comments.rs | 7 +- src/routes/errors.rs | 2 +- src/routes/instance.rs | 6 +- src/routes/likes.rs | 9 ++- src/routes/notifications.rs | 6 +- src/routes/posts.rs | 10 +-- src/routes/reshares.rs | 9 ++- src/routes/session.rs | 6 +- src/routes/user.rs | 11 ++-- src/routes/well_known.rs | 6 +- src/setup.rs | 12 ++-- 40 files changed, 411 insertions(+), 259 deletions(-) create mode 100644 plume-common/Cargo.toml create mode 100644 plume-common/src/activity_pub/inbox.rs rename {src => plume-common/src}/activity_pub/mod.rs (100%) rename {src => plume-common/src}/activity_pub/request.rs (100%) rename {src => plume-common/src}/activity_pub/sign.rs (100%) create mode 100644 plume-common/src/lib.rs rename {src => plume-common/src}/utils.rs (100%) create mode 100644 plume-models/Cargo.toml rename {src/models => plume-models/src}/blog_authors.rs (100%) rename {src/models => plume-models/src}/blogs.rs (99%) rename {src/models => plume-models/src}/comments.rs (96%) rename {src => plume-models/src}/db_conn.rs (91%) rename {src/models => plume-models/src}/follows.rs (91%) rename {src/models => plume-models/src}/instance.rs (95%) rename src/models/mod.rs => plume-models/src/lib.rs (73%) rename {src/models => plume-models/src}/likes.rs (94%) rename {src/models => plume-models/src}/mentions.rs (96%) rename {src/models => plume-models/src}/notifications.rs (97%) rename {src/models => plume-models/src}/post_authors.rs (91%) rename {src/models => plume-models/src}/posts.rs (97%) rename {src/models => plume-models/src}/reshares.rs (93%) rename {src => plume-models/src}/safe_string.rs (100%) rename {src => plume-models/src}/schema.rs (100%) rename {src/models => plume-models/src}/users.rs (98%) rename src/{activity_pub => }/inbox.rs (67%) diff --git a/Cargo.lock b/Cargo.lock index 50c8e560..1ab9542b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -949,35 +949,66 @@ name = "plume" version = "0.1.0" dependencies = [ "activitypub 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gettext-rs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plume-common 0.1.0", + "plume-models 0.1.0", + "rocket 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)", + "rocket_codegen 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)", + "rocket_contrib 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)", + "rocket_i18n 0.1.1 (git+https://github.com/BaptisteGelez/rocket_i18n?rev=5b4225d5bed5769482dc926a7e6d6b79f1217be6)", + "rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "webfinger 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "plume-common" +version = "0.1.0" +dependencies = [ + "activitypub 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "gettext-rs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "rocket 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)", - "rocket_codegen 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)", - "rocket_contrib 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)", - "rocket_i18n 0.1.1 (git+https://github.com/BaptisteGelez/rocket_i18n?rev=5b4225d5bed5769482dc926a7e6d6b79f1217be6)", - "rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tera 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "plume-models" +version = "0.1.0" +dependencies = [ + "activitypub 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "plume-common 0.1.0", + "reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.4.0-dev (git+https://github.com/SergioBenitez/Rocket?rev=df7111143e466c18d1f56377a8d9530a5a306aba)", + "serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "webfinger 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index 12a68255..a904a2da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,42 +4,24 @@ name = "plume" version = "0.1.0" [dependencies] activitypub = "0.1.1" -activitystreams-derive = "0.1.0" -activitystreams-traits = "0.1.0" -ammonia = "1.1.0" -array_tool = "1.0" -base64 = "0.9" -bcrypt = "0.2" colored = "1.6" dotenv = "*" failure = "0.1" -failure_derive = "0.1" gettext-rs = "0.4" heck = "0.3.0" -hex = "0.3" -hyper = "*" -lazy_static = "*" -openssl = "0.10.6" -reqwest = "0.8" rpassword = "2.0" -serde = "*" -serde_derive = "1.0" serde_json = "1.0" -tera = "0.11" -url = "1.7" webfinger = "0.1" -[dependencies.chrono] -features = ["serde"] -version = "0.4" - [dependencies.diesel] features = ["postgres", "r2d2", "chrono"] version = "*" -[dependencies.pulldown-cmark] -default-features = false -version = "0.1.2" +[dependencies.plume-models] +path = "plume-models" + +[dependencies.plume-common] +path = "plume-common" [dependencies.rocket] git = "https://github.com/SergioBenitez/Rocket" @@ -57,3 +39,6 @@ rev = "df7111143e466c18d1f56377a8d9530a5a306aba" [dependencies.rocket_i18n] git = "https://github.com/BaptisteGelez/rocket_i18n" rev = "5b4225d5bed5769482dc926a7e6d6b79f1217be6" + +[workspace] +members = ['plume-models', 'plume-common'] diff --git a/plume-common/Cargo.toml b/plume-common/Cargo.toml new file mode 100644 index 00000000..8af5fe6f --- /dev/null +++ b/plume-common/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "plume-common" +version = "0.1.0" +authors = ["Bat' "] + +[dependencies] +activitypub = "0.1.1" +activitystreams-derive = "0.1.0" +activitystreams-traits = "0.1.0" +# ammonia = "1.1.0" +array_tool = "1.0" +base64 = "0.9" +# bcrypt = "0.2" +# colored = "1.6" +# dotenv = "*" +failure = "0.1" +failure_derive = "0.1" +gettext-rs = "0.4" +heck = "0.3.0" +hex = "0.3" +hyper = "*" +# lazy_static = "*" +openssl = "0.10.6" +reqwest = "0.8" +# rpassword = "2.0" +serde = "*" +serde_derive = "1.0" +serde_json = "1.0" +# tera = "0.11" +# url = "1.7" +# webfinger = "0.1" +# +[dependencies.chrono] +features = ["serde"] +version = "0.4" +# +# [dependencies.diesel] +# features = ["postgres", "r2d2", "chrono"] +# version = "*" + +[dependencies.pulldown-cmark] +default-features = false +version = "0.1.2" + +[dependencies.rocket] +git = "https://github.com/SergioBenitez/Rocket" +rev = "df7111143e466c18d1f56377a8d9530a5a306aba" +# +# [dependencies.rocket_codegen] +# git = "https://github.com/SergioBenitez/Rocket" +# rev = "df7111143e466c18d1f56377a8d9530a5a306aba" +# +# [dependencies.rocket_contrib] +# features = ["tera_templates", "json"] +# git = "https://github.com/SergioBenitez/Rocket" +# rev = "df7111143e466c18d1f56377a8d9530a5a306aba" +# +# [dependencies.rocket_i18n] +# git = "https://github.com/BaptisteGelez/rocket_i18n" +# rev = "5b4225d5bed5769482dc926a7e6d6b79f1217be6" +# diff --git a/plume-common/src/activity_pub/inbox.rs b/plume-common/src/activity_pub/inbox.rs new file mode 100644 index 00000000..66855ff5 --- /dev/null +++ b/plume-common/src/activity_pub/inbox.rs @@ -0,0 +1,41 @@ +use activitypub::{Object, activity::Create}; + +use activity_pub::Id; + +#[derive(Fail, Debug)] +pub enum InboxError { + #[fail(display = "The `type` property is required, but was not present")] + NoType, + #[fail(display = "Invalid activity type")] + InvalidType, + #[fail(display = "Couldn't undo activity")] + CantUndo +} + +pub trait FromActivity: Sized { + fn from_activity(conn: &C, obj: T, actor: Id) -> Self; + + fn try_from_activity(conn: &C, act: Create) -> bool { + if let Ok(obj) = act.create_props.object_object() { + Self::from_activity(conn, obj, act.create_props.actor_link::().unwrap()); + true + } else { + false + } + } +} + +pub trait Notify { + fn notify(&self, conn: &C); +} + +pub trait Deletable { + /// true if success + fn delete_activity(conn: &C, id: Id) -> bool; +} + +pub trait WithInbox { + fn get_inbox_url(&self) -> String; + + fn get_shared_inbox_url(&self) -> Option; +} diff --git a/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs similarity index 100% rename from src/activity_pub/mod.rs rename to plume-common/src/activity_pub/mod.rs diff --git a/src/activity_pub/request.rs b/plume-common/src/activity_pub/request.rs similarity index 100% rename from src/activity_pub/request.rs rename to plume-common/src/activity_pub/request.rs diff --git a/src/activity_pub/sign.rs b/plume-common/src/activity_pub/sign.rs similarity index 100% rename from src/activity_pub/sign.rs rename to plume-common/src/activity_pub/sign.rs diff --git a/plume-common/src/lib.rs b/plume-common/src/lib.rs new file mode 100644 index 00000000..edf731ae --- /dev/null +++ b/plume-common/src/lib.rs @@ -0,0 +1,28 @@ +#![feature(custom_attribute, iterator_flatten)] + +extern crate activitypub; +#[macro_use] +extern crate activitystreams_derive; +extern crate activitystreams_traits; +extern crate array_tool; +extern crate base64; +extern crate chrono; +extern crate failure; +#[macro_use] +extern crate failure_derive; +extern crate gettextrs; +extern crate hex; +extern crate heck; +#[macro_use] +extern crate hyper; +extern crate openssl; +extern crate pulldown_cmark; +extern crate reqwest; +extern crate rocket; +#[macro_use] +extern crate serde_derive; +#[macro_use] +extern crate serde_json; + +pub mod activity_pub; +pub mod utils; diff --git a/src/utils.rs b/plume-common/src/utils.rs similarity index 100% rename from src/utils.rs rename to plume-common/src/utils.rs diff --git a/plume-models/Cargo.toml b/plume-models/Cargo.toml new file mode 100644 index 00000000..8e1e9f02 --- /dev/null +++ b/plume-models/Cargo.toml @@ -0,0 +1,64 @@ +[package] +name = "plume-models" +version = "0.1.0" +authors = ["Baptiste Gelez "] + +[dependencies] +activitypub = "0.1.1" +# activitystreams-derive = "0.1.0" +# activitystreams-traits = "0.1.0" +ammonia = "1.1.0" +# array_tool = "1.0" +# base64 = "0.9" +bcrypt = "0.2" +# colored = "1.6" +# dotenv = "*" +# failure = "0.1" +# failure_derive = "0.1" +# gettext-rs = "0.4" +heck = "0.3.0" +# hex = "0.3" +# hyper = "*" +lazy_static = "*" +openssl = "0.10.6" +reqwest = "0.8" +# rpassword = "2.0" +serde = "*" +serde_derive = "1.0" +serde_json = "1.0" +# tera = "0.11" +url = "1.7" +webfinger = "0.1" +# +[dependencies.chrono] +features = ["serde"] +version = "0.4" + +[dependencies.diesel] +features = ["postgres", "r2d2", "chrono"] +version = "*" + +[dependencies.plume-common] +path = "../plume-common" + +# [dependencies.pulldown-cmark] +# default-features = false +# version = "0.1.2" +# +[dependencies.rocket] +git = "https://github.com/SergioBenitez/Rocket" +rev = "df7111143e466c18d1f56377a8d9530a5a306aba" +# +# [dependencies.rocket_codegen] +# git = "https://github.com/SergioBenitez/Rocket" +# rev = "df7111143e466c18d1f56377a8d9530a5a306aba" +# +# [dependencies.rocket_contrib] +# features = ["tera_templates", "json"] +# git = "https://github.com/SergioBenitez/Rocket" +# rev = "df7111143e466c18d1f56377a8d9530a5a306aba" +# +# [dependencies.rocket_i18n] +# git = "https://github.com/BaptisteGelez/rocket_i18n" +# rev = "5b4225d5bed5769482dc926a7e6d6b79f1217be6" +# diff --git a/src/models/blog_authors.rs b/plume-models/src/blog_authors.rs similarity index 100% rename from src/models/blog_authors.rs rename to plume-models/src/blog_authors.rs diff --git a/src/models/blogs.rs b/plume-models/src/blogs.rs similarity index 99% rename from src/models/blogs.rs rename to plume-models/src/blogs.rs index 4c61882b..0e63f6dd 100644 --- a/src/models/blogs.rs +++ b/plume-models/src/blogs.rs @@ -17,12 +17,12 @@ use openssl::{ use webfinger::*; use BASE_URL; -use activity_pub::{ +use plume_common::activity_pub::{ ApSignature, ActivityStream, Id, IntoId, PublicKey, inbox::WithInbox, sign }; -use models::instance::*; +use instance::*; use schema::blogs; pub type CustomGroup = CustomObject; diff --git a/src/models/comments.rs b/plume-models/src/comments.rs similarity index 96% rename from src/models/comments.rs rename to plume-models/src/comments.rs index 599ec465..1500006c 100644 --- a/src/models/comments.rs +++ b/plume-models/src/comments.rs @@ -7,21 +7,19 @@ use chrono; use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, dsl::any}; use serde_json; -use activity_pub::{ +use plume_common::activity_pub::{ ap_url, Id, IntoId, PUBLIC_VISIBILTY, inbox::{FromActivity, Notify} }; -use models::{ - get_next_id, - instance::Instance, - mentions::Mention, - notifications::*, - posts::Post, - users::User -}; +use plume_common::utils; +use get_next_id; +use instance::Instance; +use mentions::Mention; +use notifications::*; +use posts::Post; +use users::User; use schema::comments; use safe_string::SafeString; -use utils; #[derive(Queryable, Identifiable, Serialize, Clone)] pub struct Comment { @@ -87,7 +85,7 @@ impl Comment { } } -impl FromActivity for Comment { +impl FromActivity for Comment { fn from_activity(conn: &PgConnection, note: Note, actor: Id) -> Comment { let previous_url = note.object_props.in_reply_to.clone().unwrap().as_str().unwrap().to_string(); let previous_comment = Comment::find_by_ap_url(conn, previous_url.clone()); @@ -118,7 +116,7 @@ impl FromActivity for Comment { } } -impl Notify for Comment { +impl Notify for Comment { fn notify(&self, conn: &PgConnection) { for author in self.get_post(conn).get_authors(conn) { Notification::insert(conn, NewNotification { diff --git a/src/db_conn.rs b/plume-models/src/db_conn.rs similarity index 91% rename from src/db_conn.rs rename to plume-models/src/db_conn.rs index 7f75f359..797496b2 100644 --- a/src/db_conn.rs +++ b/plume-models/src/db_conn.rs @@ -1,11 +1,11 @@ use diesel::{ pg::PgConnection, - r2d2::{ConnectionManager, PooledConnection} + r2d2::{ConnectionManager, Pool, PooledConnection} }; use rocket::{Request, State, Outcome, http::Status, request::{self, FromRequest}}; use std::ops::Deref; -use setup::PgPool; +pub type PgPool = Pool>; // From rocket documentation diff --git a/src/models/follows.rs b/plume-models/src/follows.rs similarity index 91% rename from src/models/follows.rs rename to plume-models/src/follows.rs index 90f52c51..af3412f8 100644 --- a/src/models/follows.rs +++ b/plume-models/src/follows.rs @@ -1,12 +1,10 @@ use activitypub::{Actor, activity::{Accept, Follow as FollowAct}}; use diesel::{self, PgConnection, ExpressionMethods, QueryDsl, RunQueryDsl}; -use activity_pub::{broadcast, Id, IntoId, inbox::{FromActivity, Notify, WithInbox}, sign::Signer}; -use models::{ - blogs::Blog, - notifications::*, - users::User -}; +use plume_common::activity_pub::{broadcast, Id, IntoId, inbox::{FromActivity, Notify, WithInbox}, sign::Signer}; +use blogs::Blog; +use notifications::*; +use users::User; use schema::follows; #[derive(Queryable, Identifiable, Associations)] @@ -55,7 +53,7 @@ impl Follow { } } -impl FromActivity for Follow { +impl FromActivity for Follow { fn from_activity(conn: &PgConnection, follow: FollowAct, _actor: Id) -> Follow { let from = User::from_url(conn, follow.follow_props.actor.as_str().unwrap().to_string()).unwrap(); match User::from_url(conn, follow.follow_props.object.as_str().unwrap().to_string()) { @@ -68,7 +66,7 @@ impl FromActivity for Follow { } } -impl Notify for Follow { +impl Notify for Follow { fn notify(&self, conn: &PgConnection) { let follower = User::get(conn, self.follower_id).unwrap(); Notification::insert(conn, NewNotification { diff --git a/src/models/instance.rs b/plume-models/src/instance.rs similarity index 95% rename from src/models/instance.rs rename to plume-models/src/instance.rs index b93a92ab..7ac5b2ec 100644 --- a/src/models/instance.rs +++ b/plume-models/src/instance.rs @@ -2,8 +2,8 @@ use chrono::NaiveDateTime; use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection}; use std::iter::Iterator; -use activity_pub::{ap_url, inbox::Inbox}; -use models::users::User; +use plume_common::activity_pub::ap_url; +use users::User; use schema::{instances, users}; #[derive(Identifiable, Queryable, Serialize)] @@ -69,5 +69,3 @@ impl Instance { )) } } - -impl Inbox for Instance {} diff --git a/src/models/mod.rs b/plume-models/src/lib.rs similarity index 73% rename from src/models/mod.rs rename to plume-models/src/lib.rs index 170e29a2..3caaaeaf 100644 --- a/src/models/mod.rs +++ b/plume-models/src/lib.rs @@ -1,4 +1,26 @@ +extern crate activitypub; +extern crate ammonia; +extern crate bcrypt; +extern crate chrono; +#[macro_use] +extern crate diesel; +extern crate heck; +#[macro_use] +extern crate lazy_static; +extern crate openssl; +extern crate plume_common; +extern crate reqwest; +extern crate rocket; +extern crate serde; +#[macro_use] +extern crate serde_derive; +#[macro_use] +extern crate serde_json; +extern crate url; +extern crate webfinger; + use diesel::{PgConnection, RunQueryDsl, select}; +use std::env; macro_rules! find_by { ($table:ident, $fn:ident, $($col:ident as $type:ident),+) => { @@ -59,9 +81,19 @@ fn get_next_id(conn: &PgConnection, seq: &str) -> i32 { next as i32 } + +lazy_static! { + pub static ref BASE_URL: String = env::var("BASE_URL") + .unwrap_or(format!("127.0.0.1:{}", env::var("ROCKET_PORT").unwrap_or(String::from("8000")))); + + pub static ref DB_URL: String = env::var("DB_URL") + .unwrap_or(format!("postgres://plume:plume@localhost/{}", env::var("DB_NAME").unwrap_or(String::from("plume")))); +} + pub mod blog_authors; pub mod blogs; pub mod comments; +pub mod db_conn; pub mod follows; pub mod instance; pub mod likes; @@ -70,4 +102,6 @@ pub mod notifications; pub mod post_authors; pub mod posts; pub mod reshares; +pub mod safe_string; +pub mod schema; pub mod users; diff --git a/src/models/likes.rs b/plume-models/src/likes.rs similarity index 94% rename from src/models/likes.rs rename to plume-models/src/likes.rs index f8d0e182..e8e084d2 100644 --- a/src/models/likes.rs +++ b/plume-models/src/likes.rs @@ -2,17 +2,15 @@ use activitypub::activity; use chrono; use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; -use activity_pub::{ +use plume_common::activity_pub::{ PUBLIC_VISIBILTY, Id, IntoId, inbox::{FromActivity, Deletable, Notify} }; -use models::{ - notifications::*, - posts::Post, - users::User -}; +use notifications::*; +use posts::Post; +use users::User; use schema::likes; #[derive(Queryable, Identifiable)] @@ -75,7 +73,7 @@ impl Like { } } -impl FromActivity for Like { +impl FromActivity for Like { fn from_activity(conn: &PgConnection, like: activity::Like, _actor: Id) -> Like { let liker = User::from_url(conn, like.like_props.actor.as_str().unwrap().to_string()); let post = Post::find_by_ap_url(conn, like.like_props.object.as_str().unwrap().to_string()); @@ -89,7 +87,7 @@ impl FromActivity for Like { } } -impl Notify for Like { +impl Notify for Like { fn notify(&self, conn: &PgConnection) { let liker = User::get(conn, self.user_id).unwrap(); let post = Post::get(conn, self.post_id).unwrap(); @@ -106,7 +104,7 @@ impl Notify for Like { } } -impl Deletable for Like { +impl Deletable for Like { fn delete_activity(conn: &PgConnection, id: Id) -> bool { if let Some(like) = Like::find_by_ap_url(conn, id.into()) { like.delete(conn); diff --git a/src/models/mentions.rs b/plume-models/src/mentions.rs similarity index 96% rename from src/models/mentions.rs rename to plume-models/src/mentions.rs index 45b8abbf..ab2a9dbb 100644 --- a/src/models/mentions.rs +++ b/plume-models/src/mentions.rs @@ -1,13 +1,11 @@ use activitypub::link; use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; -use activity_pub::inbox::Notify; -use models::{ - comments::Comment, - notifications::*, - posts::Post, - users::User -}; +use plume_common::activity_pub::inbox::Notify; +use comments::Comment; +use notifications::*; +use posts::Post; +use users::User; use schema::mentions; #[derive(Queryable, Identifiable, Serialize, Deserialize)] @@ -94,7 +92,7 @@ impl Mention { } } -impl Notify for Mention { +impl Notify for Mention { fn notify(&self, conn: &PgConnection) { let author = self.get_comment(conn) .map(|c| c.get_author(conn).display_name.clone()) diff --git a/src/models/notifications.rs b/plume-models/src/notifications.rs similarity index 97% rename from src/models/notifications.rs rename to plume-models/src/notifications.rs index c5b7d599..10944359 100644 --- a/src/models/notifications.rs +++ b/plume-models/src/notifications.rs @@ -1,7 +1,7 @@ use chrono::NaiveDateTime; use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods}; -use models::users::User; +use users::User; use schema::notifications; #[derive(Queryable, Identifiable, Serialize)] diff --git a/src/models/post_authors.rs b/plume-models/src/post_authors.rs similarity index 91% rename from src/models/post_authors.rs rename to plume-models/src/post_authors.rs index 174507c7..25b90e70 100644 --- a/src/models/post_authors.rs +++ b/plume-models/src/post_authors.rs @@ -1,9 +1,7 @@ use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; -use models::{ - posts::Post, - users::User -}; +use posts::Post; +use users::User; use schema::post_authors; #[derive(Queryable, Identifiable, Associations)] diff --git a/src/models/posts.rs b/plume-models/src/posts.rs similarity index 97% rename from src/models/posts.rs rename to plume-models/src/posts.rs index 56662646..4278855d 100644 --- a/src/models/posts.rs +++ b/plume-models/src/posts.rs @@ -9,19 +9,17 @@ use heck::KebabCase; use serde_json; use BASE_URL; -use activity_pub::{ +use plume_common::activity_pub::{ PUBLIC_VISIBILTY, ap_url, Id, IntoId, inbox::FromActivity }; -use models::{ - blogs::Blog, - instance::Instance, - likes::Like, - mentions::Mention, - post_authors::*, - reshares::Reshare, - users::User -}; +use blogs::Blog; +use instance::Instance; +use likes::Like; +use mentions::Mention; +use post_authors::*; +use reshares::Reshare; +use users::User; use schema::posts; use safe_string::SafeString; @@ -190,7 +188,7 @@ impl Post { } } -impl FromActivity
for Post { +impl FromActivity for Post { fn from_activity(conn: &PgConnection, article: Article, _actor: Id) -> Post { let (blog, authors) = article.object_props.attributed_to_link_vec::() .expect("Post::from_activity: attributedTo error") diff --git a/src/models/reshares.rs b/plume-models/src/reshares.rs similarity index 93% rename from src/models/reshares.rs rename to plume-models/src/reshares.rs index 94f59ccb..335baf84 100644 --- a/src/models/reshares.rs +++ b/plume-models/src/reshares.rs @@ -2,8 +2,10 @@ use activitypub::activity::{Announce, Undo}; use chrono::NaiveDateTime; use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; -use activity_pub::{Id, IntoId, inbox::{FromActivity, Notify, Deletable}, PUBLIC_VISIBILTY}; -use models::{notifications::*, posts::Post, users::User}; +use plume_common::activity_pub::{Id, IntoId, inbox::{FromActivity, Notify, Deletable}, PUBLIC_VISIBILTY}; +use notifications::*; +use posts::Post; +use users::User; use schema::reshares; #[derive(Serialize, Deserialize, Queryable, Identifiable)] @@ -78,7 +80,7 @@ impl Reshare { } } -impl FromActivity for Reshare { +impl FromActivity for Reshare { fn from_activity(conn: &PgConnection, announce: Announce, _actor: Id) -> Reshare { let user = User::from_url(conn, announce.announce_props.actor.as_str().unwrap().to_string()); let post = Post::find_by_ap_url(conn, announce.announce_props.object.as_str().unwrap().to_string()); @@ -92,7 +94,7 @@ impl FromActivity for Reshare { } } -impl Notify for Reshare { +impl Notify for Reshare { fn notify(&self, conn: &PgConnection) { let actor = User::get(conn, self.user_id).unwrap(); let post = self.get_post(conn).unwrap(); @@ -109,7 +111,7 @@ impl Notify for Reshare { } } -impl Deletable for Reshare { +impl Deletable for Reshare { fn delete_activity(conn: &PgConnection, id: Id) -> bool { if let Some(reshare) = Reshare::find_by_ap_url(conn, id.into()) { reshare.delete(conn); diff --git a/src/safe_string.rs b/plume-models/src/safe_string.rs similarity index 100% rename from src/safe_string.rs rename to plume-models/src/safe_string.rs diff --git a/src/schema.rs b/plume-models/src/schema.rs similarity index 100% rename from src/schema.rs rename to plume-models/src/schema.rs diff --git a/src/models/users.rs b/plume-models/src/users.rs similarity index 98% rename from src/models/users.rs rename to plume-models/src/users.rs index 09be8e87..7f367329 100644 --- a/src/models/users.rs +++ b/plume-models/src/users.rs @@ -12,6 +12,11 @@ use openssl::{ rsa::Rsa, sign }; +use plume_common::activity_pub::{ + ap_url, ActivityStream, Id, IntoId, ApSignature, PublicKey, + inbox::WithInbox, + sign::{Signer, gen_keypair} +}; use reqwest::{ Client, header::{Accept, qitem}, @@ -26,22 +31,17 @@ use url::Url; use webfinger::*; use BASE_URL; -use activity_pub::{ - ap_url, ActivityStream, Id, IntoId, ApSignature, PublicKey, - inbox::{Inbox, WithInbox}, - sign::{Signer, gen_keypair} -}; use db_conn::DbConn; -use models::{ - blogs::Blog, - blog_authors::BlogAuthor, - follows::Follow, - instance::*, - post_authors::PostAuthor, - posts::Post -}; -use schema::users; +use blogs::Blog; +use blog_authors::BlogAuthor; +use follows::Follow; +use instance::*; +use likes::Like; +use post_authors::PostAuthor; +use posts::Post; +use reshares::Reshare; use safe_string::SafeString; +use schema::users; pub const AUTH_COOKIE: &'static str = "user_id"; @@ -286,7 +286,6 @@ impl User { pub fn has_liked(&self, conn: &PgConnection, post: &Post) -> bool { use schema::likes; - use models::likes::Like; likes::table .filter(likes::post_id.eq(post.id)) .filter(likes::user_id.eq(self.id)) @@ -297,7 +296,6 @@ impl User { pub fn has_reshared(&self, conn: &PgConnection, post: &Post) -> bool { use schema::reshares; - use models::reshares::Reshare; reshares::table .filter(reshares::post_id.eq(post.id)) .filter(reshares::user_id.eq(self.id)) @@ -418,8 +416,6 @@ impl WithInbox for User { } } -impl Inbox for User {} - impl Signer for User { fn get_key_id(&self) -> String { format!("{}#main-key", self.ap_url) diff --git a/src/activity_pub/inbox.rs b/src/inbox.rs similarity index 67% rename from src/activity_pub/inbox.rs rename to src/inbox.rs index 012108e8..5081357f 100644 --- a/src/activity_pub/inbox.rs +++ b/src/inbox.rs @@ -1,54 +1,19 @@ -use activitypub::{ - Object, - activity::{Announce, Create, Like, Undo} -}; +use activitypub::activity::{Announce, Create, Like, Undo}; use diesel::PgConnection; use failure::Error; use serde_json; -use activity_pub::{ - Id -}; -use models::{ - comments::*, +use plume_common::activity_pub::{Id, inbox::{Deletable, FromActivity, InboxError}}; +use plume_models::{ + comments::Comment, follows::Follow, + instance::Instance, likes, - posts::*, - reshares::* + reshares::Reshare, + posts::Post, + users::User }; -#[derive(Fail, Debug)] -enum InboxError { - #[fail(display = "The `type` property is required, but was not present")] - NoType, - #[fail(display = "Invalid activity type")] - InvalidType, - #[fail(display = "Couldn't undo activity")] - CantUndo -} - -pub trait FromActivity: Sized { - fn from_activity(conn: &PgConnection, obj: T, actor: Id) -> Self; - - fn try_from_activity(conn: &PgConnection, act: Create) -> bool { - if let Ok(obj) = act.create_props.object_object() { - Self::from_activity(conn, obj, act.create_props.actor_link::().unwrap()); - true - } else { - false - } - } -} - -pub trait Notify { - fn notify(&self, conn: &PgConnection); -} - -pub trait Deletable { - /// true if success - fn delete_activity(conn: &PgConnection, id: Id) -> bool; -} - pub trait Inbox { fn received(&self, conn: &PgConnection, act: serde_json::Value) -> Result<(), Error> { let actor_id = Id::new(act["actor"].as_str().unwrap()); @@ -97,8 +62,5 @@ pub trait Inbox { } } -pub trait WithInbox { - fn get_inbox_url(&self) -> String; - - fn get_shared_inbox_url(&self) -> Option; -} +impl Inbox for Instance {} +impl Inbox for User {} diff --git a/src/main.rs b/src/main.rs index 85b4584e..11bb10b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,64 +1,28 @@ -#![feature(plugin, custom_derive, decl_macro, iterator_find_map, iterator_flatten)] +#![feature(custom_derive, decl_macro, plugin)] #![plugin(rocket_codegen)] - + extern crate activitypub; -#[macro_use] -extern crate activitystreams_derive; -extern crate activitystreams_traits; -extern crate ammonia; -extern crate array_tool; -extern crate base64; -extern crate bcrypt; -extern crate chrono; extern crate colored; -extern crate failure; -#[macro_use] -extern crate failure_derive; -extern crate gettextrs; -extern crate heck; -extern crate hex; -#[macro_use] -extern crate hyper; -#[macro_use] extern crate diesel; extern crate dotenv; -#[macro_use] -extern crate lazy_static; -extern crate openssl; -extern crate pulldown_cmark; -extern crate reqwest; +extern crate failure; +extern crate gettextrs; +extern crate heck; +extern crate plume_common; +extern crate plume_models; extern crate rocket; extern crate rocket_contrib; extern crate rocket_i18n; extern crate rpassword; -extern crate serde; -#[macro_use] -extern crate serde_derive; #[macro_use] extern crate serde_json; -extern crate tera; -extern crate url; extern crate webfinger; use rocket_contrib::Template; -use std::env; -mod activity_pub; -mod db_conn; -mod models; -mod safe_string; -mod schema; +mod inbox; mod setup; mod routes; -mod utils; - -lazy_static! { - pub static ref BASE_URL: String = env::var("BASE_URL") - .unwrap_or(format!("127.0.0.1:{}", env::var("ROCKET_PORT").unwrap_or(String::from("8000")))); - - pub static ref DB_URL: String = env::var("DB_URL") - .unwrap_or(format!("postgres://plume:plume@localhost/{}", env::var("DB_NAME").unwrap_or(String::from("plume")))); -} fn main() { let pool = setup::check(); diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs index d06e56d9..68fb818b 100644 --- a/src/routes/blogs.rs +++ b/src/routes/blogs.rs @@ -6,16 +6,16 @@ use rocket::{ use rocket_contrib::Template; use serde_json; -use activity_pub::ActivityStream; -use db_conn::DbConn; -use models::{ +use plume_common::activity_pub::ActivityStream; +use plume_common::utils; +use plume_models::{ blog_authors::*, blogs::*, + db_conn::DbConn, instance::Instance, posts::Post, users::User }; -use utils; #[get("/~/", rank = 2)] fn details(name: String, conn: DbConn, user: Option) -> Template { diff --git a/src/routes/comments.rs b/src/routes/comments.rs index aa9997fc..3fd0f97e 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -4,15 +4,16 @@ use rocket::{ }; use serde_json; -use activity_pub::{broadcast, inbox::Inbox}; -use db_conn::DbConn; -use models::{ +use plume_common::activity_pub::broadcast; +use plume_models::{ blogs::Blog, comments::*, + db_conn::DbConn, instance::Instance, posts::Post, users::User }; +use inbox::Inbox; #[derive(FromForm)] pub struct CommentQuery { diff --git a/src/routes/errors.rs b/src/routes/errors.rs index 83c71795..1f731017 100644 --- a/src/routes/errors.rs +++ b/src/routes/errors.rs @@ -1,7 +1,7 @@ use rocket_contrib::Template; use rocket::Request; use rocket::request::FromRequest; -use models::users::User; +use plume_models::users::User; #[catch(404)] fn not_found(req: &Request) -> Template { diff --git a/src/routes/instance.rs b/src/routes/instance.rs index 4c7816f0..09304dac 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -2,14 +2,14 @@ use gettextrs::gettext; use rocket_contrib::{Json, Template}; use serde_json; -use activity_pub::inbox::Inbox; -use db_conn::DbConn; -use models::{ +use plume_models::{ comments::Comment, + db_conn::DbConn, posts::Post, users::User, instance::* }; +use inbox::Inbox; #[get("/")] fn index(conn: DbConn, user: Option) -> Template { diff --git a/src/routes/likes.rs b/src/routes/likes.rs index c6b0a5cd..3ccd0d6f 100644 --- a/src/routes/likes.rs +++ b/src/routes/likes.rs @@ -1,16 +1,15 @@ use rocket::response::{Redirect, Flash}; -use activity_pub::{broadcast, inbox::Notify}; -use db_conn::DbConn; -use models::{ +use plume_common::activity_pub::{broadcast, inbox::Notify}; +use plume_common::utils; +use plume_models::{ blogs::Blog, + db_conn::DbConn, likes, posts::Post, users::User }; -use utils; - #[get("/~///like")] fn create(blog: String, slug: String, user: User, conn: DbConn) -> Redirect { let b = Blog::find_by_fqn(&*conn, blog.clone()).unwrap(); diff --git a/src/routes/notifications.rs b/src/routes/notifications.rs index 9548ad74..14cf6a74 100644 --- a/src/routes/notifications.rs +++ b/src/routes/notifications.rs @@ -1,10 +1,8 @@ use rocket::response::{Redirect, Flash}; use rocket_contrib::Template; -use db_conn::DbConn; -use models::{notifications::Notification, users::User}; - -use utils; +use plume_common::utils; +use plume_models::{db_conn::DbConn, notifications::Notification, users::User}; #[get("/notifications")] fn notifications(conn: DbConn, user: User) -> Template { diff --git a/src/routes/posts.rs b/src/routes/posts.rs index e5217b66..56a5018f 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -5,19 +5,19 @@ use rocket::response::{Redirect, Flash}; use rocket_contrib::Template; use serde_json; -use activity_pub::{broadcast, ActivityStream}; -use db_conn::DbConn; -use models::{ +use plume_common::activity_pub::{broadcast, ActivityStream}; +use plume_common::utils; +use plume_models::{ blogs::*, + db_conn::DbConn, comments::Comment, mentions::Mention, post_authors::*, posts::*, + safe_string::SafeString, users::User }; use routes::comments::CommentQuery; -use safe_string::SafeString; -use utils; // See: https://github.com/SergioBenitez/Rocket/pull/454 #[get("/~//", rank = 4)] diff --git a/src/routes/reshares.rs b/src/routes/reshares.rs index 4166f263..f83a40f3 100644 --- a/src/routes/reshares.rs +++ b/src/routes/reshares.rs @@ -1,16 +1,15 @@ use rocket::response::{Redirect, Flash}; -use activity_pub::{broadcast, inbox::Notify}; -use db_conn::DbConn; -use models::{ +use plume_common::activity_pub::{broadcast, inbox::Notify}; +use plume_common::utils; +use plume_models::{ blogs::Blog, + db_conn::DbConn, posts::Post, reshares::*, users::User }; -use utils; - #[get("/~///reshare")] fn create(blog: String, slug: String, user: User, conn: DbConn) -> Redirect { let b = Blog::find_by_fqn(&*conn, blog.clone()).unwrap(); diff --git a/src/routes/session.rs b/src/routes/session.rs index 057e63b0..60bb4afe 100644 --- a/src/routes/session.rs +++ b/src/routes/session.rs @@ -6,8 +6,10 @@ use rocket::{ }; use rocket_contrib::Template; -use db_conn::DbConn; -use models::users::{User, AUTH_COOKIE}; +use plume_models::{ + db_conn::DbConn, + users::{User, AUTH_COOKIE} +}; #[get("/login")] fn new(user: Option) -> Template { diff --git a/src/routes/user.rs b/src/routes/user.rs index af8bd5e4..616268eb 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -8,20 +8,21 @@ use rocket::{request::Form, use rocket_contrib::Template; use serde_json; -use activity_pub::{ +use plume_common::activity_pub::{ ActivityStream, broadcast, Id, IntoId, - inbox::{Inbox, Notify} + inbox::{Notify} }; -use db_conn::DbConn; -use models::{ +use plume_common::utils; +use plume_models::{ blogs::Blog, + db_conn::DbConn, follows, instance::Instance, posts::Post, reshares::Reshare, users::* }; -use utils; +use inbox::Inbox; #[get("/me")] fn me(user: Option) -> Result> { diff --git a/src/routes/well_known.rs b/src/routes/well_known.rs index ec9710a2..789c3211 100644 --- a/src/routes/well_known.rs +++ b/src/routes/well_known.rs @@ -3,10 +3,8 @@ use rocket::response::Content; use serde_json; use webfinger::*; -use BASE_URL; -use activity_pub::ap_url; -use db_conn::DbConn; -use models::{blogs::Blog, users::User}; +use plume_common::activity_pub::ap_url; +use plume_models::{BASE_URL, db_conn::DbConn, blogs::Blog, users::User}; #[get("/.well-known/nodeinfo")] fn nodeinfo() -> Content { diff --git a/src/setup.rs b/src/setup.rs index 9c67ed66..45378eed 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -7,12 +7,12 @@ use std::path::Path; use std::process::{exit, Command}; use rpassword; -use DB_URL; -use db_conn::DbConn; -use models::instance::*; -use models::users::*; - -pub type PgPool = Pool>; +use plume_models::{ + DB_URL, + db_conn::{DbConn, PgPool}, + instance::*, + users::* +}; /// Initializes a database pool. fn init_pool() -> Option {