From 38d737ed0c35c8469571241b42f62689ea30af4a Mon Sep 17 00:00:00 2001 From: Bat Date: Wed, 26 Sep 2018 16:22:42 +0100 Subject: [PATCH] Introduce features to choose between SQlite or Postgres --- Cargo.toml | 5 + .../2018-05-10-154336_create_likes/up.sql | 4 +- plume-models/Cargo.toml | 7 +- plume-models/src/blog_authors.rs | 2 +- plume-models/src/blogs.rs | 39 +++--- plume-models/src/comments.rs | 23 ++-- plume-models/src/db_conn.rs | 2 +- plume-models/src/follows.rs | 15 ++- plume-models/src/instance.rs | 26 ++-- plume-models/src/lib.rs | 23 +++- plume-models/src/likes.rs | 25 ++-- plume-models/src/medias.rs | 14 +- plume-models/src/mentions.rs | 17 +-- plume-models/src/notifications.rs | 14 +- plume-models/src/post_authors.rs | 2 +- plume-models/src/posts.rs | 66 +++++----- plume-models/src/reshares.rs | 22 ++-- plume-models/src/schema.rs | 122 +++++++++--------- plume-models/src/tags.rs | 8 +- plume-models/src/users.rs | 68 +++++----- 20 files changed, 265 insertions(+), 239 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f4bc5d8a..6cc0f3cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,5 +62,10 @@ rev = "b326a9893a1849c9abdb39cab9fd7c4a52eb9674" git = "https://github.com/BaptisteGelez/rocket_i18n" rev = "75a3bfd7b847324c078a355a7f101f8241a9f59b" +[features] +default = ["postgres"] +postgres = ["plume-models/postgres"] +sqlite = ["plume-models/sqlite"] + [workspace] members = ["plume-api", "plume-models", "plume-common"] diff --git a/migrations/sqlite/2018-05-10-154336_create_likes/up.sql b/migrations/sqlite/2018-05-10-154336_create_likes/up.sql index 0309fb0a..b406a7b6 100644 --- a/migrations/sqlite/2018-05-10-154336_create_likes/up.sql +++ b/migrations/sqlite/2018-05-10-154336_create_likes/up.sql @@ -3,6 +3,6 @@ CREATE TABLE likes ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, user_id INTEGER REFERENCES users(id) ON DELETE CASCADE NOT NULL, post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE NOT NULL, - ap_url VARCHAR NOT NULL default '', - creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP + creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ap_url VARCHAR NOT NULL default '' ) diff --git a/plume-models/Cargo.toml b/plume-models/Cargo.toml index 0cefb535..c05d7a89 100644 --- a/plume-models/Cargo.toml +++ b/plume-models/Cargo.toml @@ -23,7 +23,7 @@ features = ["serde"] version = "0.4" [dependencies.diesel] -features = ["postgres", "sqlite", "r2d2", "chrono"] +features = ["r2d2", "chrono"] version = "1.3.2" [dependencies.plume-api] @@ -35,3 +35,8 @@ path = "../plume-common" [dependencies.rocket] git = "https://github.com/SergioBenitez/Rocket" rev = "55459db7732b9a240826a5c120c650f87e3372ce" + +[features] +default = ["postgres"] +postgres = ["diesel/postgres"] +sqlite = ["diesel/sqlite"] diff --git a/plume-models/src/blog_authors.rs b/plume-models/src/blog_authors.rs index 106832a8..95f8a4d2 100644 --- a/plume-models/src/blog_authors.rs +++ b/plume-models/src/blog_authors.rs @@ -1,4 +1,4 @@ -use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection}; +use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods}; use schema::blog_authors; diff --git a/plume-models/src/blogs.rs b/plume-models/src/blogs.rs index c825f6aa..2005bf09 100644 --- a/plume-models/src/blogs.rs +++ b/plume-models/src/blogs.rs @@ -6,8 +6,7 @@ use reqwest::{ }; use serde_json; use url::Url; -use chrono::NaiveDateTime; -use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection, dsl::any}; +use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, dsl::any}; use openssl::{ hash::MessageDigest, pkey::{PKey, Private}, @@ -16,7 +15,7 @@ use openssl::{ }; use webfinger::*; -use {BASE_URL, USE_HTTPS}; +use {BASE_URL, USE_HTTPS, Connection, SqlDateTime}; use plume_common::activity_pub::{ ap_accept_header, ApSignature, ActivityStream, Id, IntoId, PublicKey, inbox::WithInbox, @@ -38,7 +37,7 @@ pub struct Blog { pub outbox_url: String, pub inbox_url: String, pub instance_id: i32, - pub creation_date: NaiveDateTime, + pub creation_date: SqlDateTime, pub ap_url: String, pub private_key: Option, pub public_key: String @@ -66,11 +65,11 @@ impl Blog { find_by!(blogs, find_by_ap_url, ap_url as String); find_by!(blogs, find_by_name, actor_id as String, instance_id as i32); - pub fn get_instance(&self, conn: &PgConnection) -> Instance { + pub fn get_instance(&self, conn: &Connection) -> Instance { Instance::get(conn, self.instance_id).expect("Couldn't find instance") } - pub fn list_authors(&self, conn: &PgConnection) -> Vec { + pub fn list_authors(&self, conn: &Connection) -> Vec { use schema::blog_authors; use schema::users; let authors_ids = blog_authors::table.filter(blog_authors::blog_id.eq(self.id)).select(blog_authors::author_id); @@ -79,7 +78,7 @@ impl Blog { .expect("Couldn't load authors of a blog") } - pub fn find_for_author(conn: &PgConnection, author_id: i32) -> Vec { + pub fn find_for_author(conn: &Connection, author_id: i32) -> Vec { use schema::blog_authors; let author_ids = blog_authors::table.filter(blog_authors::author_id.eq(author_id)).select(blog_authors::blog_id); blogs::table.filter(blogs::id.eq(any(author_ids))) @@ -87,11 +86,11 @@ impl Blog { .expect("Couldn't load blogs ") } - pub fn find_local(conn: &PgConnection, name: String) -> Option { + pub fn find_local(conn: &Connection, name: String) -> Option { Blog::find_by_name(conn, name, Instance::local_id(conn)) } - pub fn find_by_fqn(conn: &PgConnection, fqn: String) -> Option { + pub fn find_by_fqn(conn: &Connection, fqn: String) -> Option { if fqn.contains("@") { // remote blog match Instance::find_by_domain(conn, String::from(fqn.split("@").last().unwrap())) { Some(instance) => { @@ -107,7 +106,7 @@ impl Blog { } } - fn fetch_from_webfinger(conn: &PgConnection, acct: String) -> Option { + fn fetch_from_webfinger(conn: &Connection, acct: String) -> Option { match resolve(acct.clone(), *USE_HTTPS) { Ok(wf) => wf.links.into_iter().find(|l| l.mime_type == Some(String::from("application/activity+json"))).and_then(|l| Blog::fetch_from_url(conn, l.href.expect("No href for AP WF link"))), Err(details) => { @@ -117,7 +116,7 @@ impl Blog { } } - fn fetch_from_url(conn: &PgConnection, url: String) -> Option { + fn fetch_from_url(conn: &Connection, url: String) -> Option { let req = Client::new() .get(&url[..]) .header(Accept(ap_accept_header().into_iter().map(|h| qitem(h.parse::().expect("Invalid Content-Type"))).collect())) @@ -134,7 +133,7 @@ impl Blog { } } - fn from_activity(conn: &PgConnection, acct: CustomGroup, inst: String) -> Blog { + fn from_activity(conn: &Connection, acct: CustomGroup, inst: String) -> Blog { let instance = match Instance::find_by_domain(conn, inst.clone()) { Some(instance) => instance, None => { @@ -166,7 +165,7 @@ impl Blog { }) } - pub fn into_activity(&self, _conn: &PgConnection) -> CustomGroup { + pub fn into_activity(&self, _conn: &Connection) -> CustomGroup { let mut blog = Group::default(); blog.ap_actor_props.set_preferred_username_string(self.actor_id.clone()).expect("Blog::into_activity: preferredUsername error"); blog.object_props.set_name_string(self.title.clone()).expect("Blog::into_activity: name error"); @@ -185,7 +184,7 @@ impl Blog { CustomGroup::new(blog, ap_signature) } - pub fn update_boxes(&self, conn: &PgConnection) { + pub fn update_boxes(&self, conn: &Connection) { let instance = self.get_instance(conn); if self.outbox_url.len() == 0 { diesel::update(self) @@ -206,14 +205,14 @@ impl Blog { } } - pub fn outbox(&self, conn: &PgConnection) -> ActivityStream { + pub fn outbox(&self, conn: &Connection) -> ActivityStream { let mut coll = OrderedCollection::default(); coll.collection_props.items = serde_json::to_value(self.get_activities(conn)).unwrap(); coll.collection_props.set_total_items_u64(self.get_activities(conn).len() as u64).unwrap(); ActivityStream::new(coll) } - fn get_activities(&self, _conn: &PgConnection) -> Vec { + fn get_activities(&self, _conn: &Connection) -> Vec { vec![] } @@ -221,7 +220,7 @@ impl Blog { PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.clone().unwrap().as_ref()).unwrap()).unwrap() } - pub fn webfinger(&self, conn: &PgConnection) -> Webfinger { + pub fn webfinger(&self, conn: &Connection) -> Webfinger { Webfinger { subject: format!("acct:{}@{}", self.actor_id, self.get_instance(conn).public_domain), aliases: vec![self.ap_url.clone()], @@ -248,7 +247,7 @@ impl Blog { } } - pub fn from_url(conn: &PgConnection, url: String) -> Option { + pub fn from_url(conn: &Connection, url: String) -> Option { Blog::find_by_ap_url(conn, url.clone()).or_else(|| { // The requested user was not in the DB // We try to fetch it if it is remote @@ -260,7 +259,7 @@ impl Blog { }) } - pub fn get_fqn(&self, conn: &PgConnection) -> String { + pub fn get_fqn(&self, conn: &Connection) -> String { if self.instance_id == Instance::local_id(conn) { self.actor_id.clone() } else { @@ -268,7 +267,7 @@ impl Blog { } } - pub fn to_json(&self, conn: &PgConnection) -> serde_json::Value { + pub fn to_json(&self, conn: &Connection) -> serde_json::Value { let mut json = serde_json::to_value(self).unwrap(); json["fqn"] = json!(self.get_fqn(conn)); json diff --git a/plume-models/src/comments.rs b/plume-models/src/comments.rs index 040193e0..b35275e5 100644 --- a/plume-models/src/comments.rs +++ b/plume-models/src/comments.rs @@ -12,6 +12,7 @@ use plume_common::activity_pub::{ inbox::{FromActivity, Notify} }; use plume_common::utils; +use {Connection, SqlDateTime}; use instance::Instance; use mentions::Mention; use notifications::*; @@ -27,7 +28,7 @@ pub struct Comment { pub in_response_to_id: Option, pub post_id: i32, pub author_id: i32, - pub creation_date: chrono::NaiveDateTime, + pub creation_date: SqlDateTime, pub ap_url: Option, pub sensitive: bool, pub spoiler_text: String @@ -51,15 +52,15 @@ impl Comment { list_by!(comments, list_by_post, post_id as i32); find_by!(comments, find_by_ap_url, ap_url as String); - pub fn get_author(&self, conn: &PgConnection) -> User { + pub fn get_author(&self, conn: &Connection) -> User { User::get(conn, self.author_id).unwrap() } - pub fn get_post(&self, conn: &PgConnection) -> Post { + pub fn get_post(&self, conn: &Connection) -> Post { Post::get(conn, self.post_id).unwrap() } - pub fn count_local(conn: &PgConnection) -> usize { + pub fn count_local(conn: &Connection) -> usize { use schema::users; let local_authors = users::table.filter(users::instance_id.eq(Instance::local_id(conn))).select(users::id); comments::table.filter(comments::author_id.eq(any(local_authors))) @@ -68,7 +69,7 @@ impl Comment { .len() } - pub fn to_json(&self, conn: &PgConnection, others: &Vec) -> serde_json::Value { + pub fn to_json(&self, conn: &Connection, others: &Vec) -> serde_json::Value { let mut json = serde_json::to_value(self).unwrap(); json["author"] = self.get_author(conn).to_json(conn); let mentions = Mention::list_for_comment(conn, self.id).into_iter() @@ -82,7 +83,7 @@ impl Comment { json } - pub fn update_ap_url(&self, conn: &PgConnection) -> Comment { + pub fn update_ap_url(&self, conn: &Connection) -> Comment { if self.ap_url.is_none() { diesel::update(self) .set(comments::ap_url.eq(self.compute_id(conn))) @@ -93,11 +94,11 @@ impl Comment { } } - pub fn compute_id(&self, conn: &PgConnection) -> String { + pub fn compute_id(&self, conn: &Connection) -> String { format!("{}comment/{}", self.get_post(conn).ap_url, self.id) } - pub fn into_activity(&self, conn: &PgConnection) -> Note { + pub fn into_activity(&self, conn: &Connection) -> Note { let (html, mentions) = utils::md_to_html(self.content.get().as_ref()); let author = User::get(conn, self.author_id).unwrap(); @@ -119,7 +120,7 @@ impl Comment { note } - pub fn create_activity(&self, conn: &PgConnection) -> Create { + pub fn create_activity(&self, conn: &Connection) -> Create { let author = User::get(conn, self.author_id).unwrap(); let note = self.into_activity(conn); @@ -134,7 +135,7 @@ impl Comment { } impl FromActivity for Comment { - fn from_activity(conn: &PgConnection, note: Note, actor: Id) -> Comment { + fn from_activity(conn: &Connection, 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()); @@ -168,7 +169,7 @@ impl FromActivity for Comment { } impl Notify for Comment { - fn notify(&self, conn: &PgConnection) { + fn notify(&self, conn: &Connection) { for author in self.get_post(conn).get_authors(conn) { Notification::insert(conn, NewNotification { kind: notification_kind::COMMENT.to_string(), diff --git a/plume-models/src/db_conn.rs b/plume-models/src/db_conn.rs index 797496b2..557100d6 100644 --- a/plume-models/src/db_conn.rs +++ b/plume-models/src/db_conn.rs @@ -27,7 +27,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for DbConn { } } -// For the convenience of using an &DbConn as an &PgConnection. +// For the convenience of using an &DbConn as an &Connection. impl Deref for DbConn { type Target = PgConnection; diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 9c29aacc..311d87d9 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -2,6 +2,7 @@ use activitypub::{Actor, activity::{Accept, Follow as FollowAct, Undo}, actor::P use diesel::{self, PgConnection, ExpressionMethods, QueryDsl, RunQueryDsl}; use plume_common::activity_pub::{broadcast, Id, IntoId, inbox::{FromActivity, Notify, WithInbox, Deletable}, sign::Signer}; +use Connection; use blogs::Blog; use notifications::*; use users::User; @@ -29,14 +30,14 @@ impl Follow { get!(follows); find_by!(follows, find_by_ap_url, ap_url as String); - pub fn find(conn: &PgConnection, from: i32, to: i32) -> Option { + pub fn find(conn: &Connection, from: i32, to: i32) -> Option { follows::table.filter(follows::follower_id.eq(from)) .filter(follows::following_id.eq(to)) .get_result(conn) .ok() } - pub fn into_activity(&self, conn: &PgConnection) -> FollowAct { + pub fn into_activity(&self, conn: &Connection) -> FollowAct { let user = User::get(conn, self.follower_id).unwrap(); let target = User::get(conn, self.following_id).unwrap(); @@ -52,7 +53,7 @@ impl Follow { /// from -> The one sending the follow request /// target -> The target of the request, responding with Accept pub fn accept_follow( - conn: &PgConnection, + conn: &Connection, from: &B, target: &A, follow: FollowAct, @@ -80,7 +81,7 @@ impl Follow { } impl FromActivity for Follow { - fn from_activity(conn: &PgConnection, follow: FollowAct, _actor: Id) -> Follow { + fn from_activity(conn: &Connection, follow: FollowAct, _actor: Id) -> Follow { let from_id = follow.follow_props.actor_link::().map(|l| l.into()) .unwrap_or_else(|_| follow.follow_props.actor_object::().expect("No actor object (nor ID) on Follow").object_props.id_string().expect("No ID on actor on Follow")); let from = User::from_url(conn, from_id).unwrap(); @@ -95,7 +96,7 @@ impl FromActivity for Follow { } impl Notify for Follow { - fn notify(&self, conn: &PgConnection) { + fn notify(&self, conn: &Connection) { Notification::insert(conn, NewNotification { kind: notification_kind::FOLLOW.to_string(), object_id: self.id, @@ -105,7 +106,7 @@ impl Notify for Follow { } impl Deletable for Follow { - fn delete(&self, conn: &PgConnection) -> Undo { + fn delete(&self, conn: &Connection) -> Undo { diesel::delete(self).execute(conn).expect("Coudn't delete follow"); // delete associated notification if any @@ -120,7 +121,7 @@ impl Deletable for Follow { undo } - fn delete_id(id: String, conn: &PgConnection) { + fn delete_id(id: String, conn: &Connection) { if let Some(follow) = Follow::find_by_ap_url(conn, id) { follow.delete(conn); } diff --git a/plume-models/src/instance.rs b/plume-models/src/instance.rs index 8466fa68..9df7be91 100644 --- a/plume-models/src/instance.rs +++ b/plume-models/src/instance.rs @@ -1,8 +1,8 @@ -use chrono::NaiveDateTime; -use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection}; +use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods}; use std::iter::Iterator; use plume_common::utils::md_to_html; +use {Connection, SqlDateTime}; use safe_string::SafeString; use ap_url; use users::User; @@ -15,7 +15,7 @@ pub struct Instance { pub name: String, pub local: bool, pub blocked: bool, - pub creation_date: NaiveDateTime, + pub creation_date: SqlDateTime, pub open_registrations: bool, pub short_description: SafeString, pub long_description: SafeString, @@ -39,7 +39,7 @@ pub struct NewInstance { } impl Instance { - pub fn get_local(conn: &PgConnection) -> Option { + pub fn get_local(conn: &Connection) -> Option { instances::table.filter(instances::local.eq(true)) .limit(1) .load::(conn) @@ -47,13 +47,13 @@ impl Instance { .into_iter().nth(0) } - pub fn get_remotes(conn: &PgConnection) -> Vec { + pub fn get_remotes(conn: &Connection) -> Vec { instances::table.filter(instances::local.eq(false)) .load::(conn) .expect("Error loading remote instances infos") } - pub fn page(conn: &PgConnection, (min, max): (i32, i32)) -> Vec { + pub fn page(conn: &Connection, (min, max): (i32, i32)) -> Vec { instances::table.order(instances::public_domain.asc()) .offset(min.into()) .limit((max - min).into()) @@ -61,7 +61,7 @@ impl Instance { .expect("Error loading a page of instances") } - pub fn local_id(conn: &PgConnection) -> i32 { + pub fn local_id(conn: &Connection) -> i32 { Instance::get_local(conn).unwrap().id } @@ -69,7 +69,7 @@ impl Instance { get!(instances); find_by!(instances, find_by_domain, public_domain as String); - pub fn toggle_block(&self, conn: &PgConnection) { + pub fn toggle_block(&self, conn: &Connection) { diesel::update(self) .set(instances::blocked.eq(!self.blocked)) .get_result::(conn) @@ -77,7 +77,7 @@ impl Instance { } /// id: AP object id - pub fn is_blocked(conn: &PgConnection, id: String) -> bool { + pub fn is_blocked(conn: &Connection, id: String) -> bool { for block in instances::table.filter(instances::blocked.eq(true)) .get_results::(conn) .expect("Error listing blocked instances") { @@ -89,7 +89,7 @@ impl Instance { false } - pub fn has_admin(&self, conn: &PgConnection) -> bool { + pub fn has_admin(&self, conn: &Connection) -> bool { users::table.filter(users::instance_id.eq(self.id)) .filter(users::is_admin.eq(true)) .load::(conn) @@ -97,7 +97,7 @@ impl Instance { .len() > 0 } - pub fn main_admin(&self, conn: &PgConnection) -> User { + pub fn main_admin(&self, conn: &Connection) -> User { users::table.filter(users::instance_id.eq(self.id)) .filter(users::is_admin.eq(true)) .limit(1) @@ -115,7 +115,7 @@ impl Instance { )) } - pub fn update(&self, conn: &PgConnection, name: String, open_registrations: bool, short_description: SafeString, long_description: SafeString) -> Instance { + pub fn update(&self, conn: &Connection, name: String, open_registrations: bool, short_description: SafeString, long_description: SafeString) -> Instance { let (sd, _) = md_to_html(short_description.as_ref()); let (ld, _) = md_to_html(long_description.as_ref()); diesel::update(self) @@ -130,7 +130,7 @@ impl Instance { .expect("Couldn't update instance") } - pub fn count(conn: &PgConnection) -> i64 { + pub fn count(conn: &Connection) -> i64 { instances::table.count().get_result(conn).expect("Couldn't count instances") } } diff --git a/plume-models/src/lib.rs b/plume-models/src/lib.rs index 71c4f4e5..04f485e3 100644 --- a/plume-models/src/lib.rs +++ b/plume-models/src/lib.rs @@ -1,4 +1,5 @@ #![allow(proc_macro_derive_resolution_fallback)] // This can be removed after diesel-1.4 +#![feature(crate_in_paths)] extern crate activitypub; extern crate ammonia; @@ -28,7 +29,7 @@ use std::env; macro_rules! find_by { ($table:ident, $fn:ident, $($col:ident as $type:ident),+) => { /// Try to find a $table with a given $col - pub fn $fn(conn: &PgConnection, $($col: $type),+) -> Option { + pub fn $fn(conn: &crate::Connection, $($col: $type),+) -> Option { $table::table $(.filter($table::$col.eq($col)))+ .limit(1) @@ -42,7 +43,7 @@ macro_rules! find_by { macro_rules! list_by { ($table:ident, $fn:ident, $($col:ident as $type:ident),+) => { /// Try to find a $table with a given $col - pub fn $fn(conn: &PgConnection, $($col: $type),+) -> Vec { + pub fn $fn(conn: &crate::Connection, $($col: $type),+) -> Vec { $table::table $(.filter($table::$col.eq($col)))+ .load::(conn) @@ -53,7 +54,7 @@ macro_rules! list_by { macro_rules! get { ($table:ident) => { - pub fn get(conn: &PgConnection, id: i32) -> Option { + pub fn get(conn: &crate::Connection, id: i32) -> Option { $table::table.filter($table::id.eq(id)) .limit(1) .load::(conn) @@ -65,7 +66,7 @@ macro_rules! get { macro_rules! insert { ($table:ident, $from:ident) => { - pub fn insert(conn: &PgConnection, new: $from) -> Self { + pub fn insert(conn: &crate::Connection, new: $from) -> Self { diesel::insert_into($table::table) .values(new) .get_result(conn) @@ -76,7 +77,7 @@ macro_rules! insert { macro_rules! update { ($table:ident) => { - pub fn update(&self, conn: &PgConnection) -> Self { + pub fn update(&self, conn: &crate::Connection) -> Self { diesel::update(self) .set(self) .get_result(conn) @@ -104,6 +105,18 @@ pub fn ap_url(url: String) -> String { format!("{}://{}", scheme, url) } +#[cfg(all(not(feature = "postgres"), feature = "sqlite"))] +pub type SqlDateTime = chrono::NaiveDateTime; + +#[cfg(all(not(feature = "postgres"), feature = "sqlite"))] +pub type Connection = diesel::SqliteConnection; + +#[cfg(all(not(feature = "sqlite"), feature = "postgres"))] +pub type SqlDateTime = chrono::NaiveDateTime; + +#[cfg(all(not(feature = "sqlite"), feature = "postgres"))] +pub type Connection = diesel::PgConnection; + pub mod admin; pub mod blog_authors; pub mod blogs; diff --git a/plume-models/src/likes.rs b/plume-models/src/likes.rs index 9bf1bec3..31f59542 100644 --- a/plume-models/src/likes.rs +++ b/plume-models/src/likes.rs @@ -1,6 +1,6 @@ use activitypub::activity; -use chrono; -use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; +use chrono::NaiveDateTime; +use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods}; use plume_common::activity_pub::{ PUBLIC_VISIBILTY, @@ -8,6 +8,7 @@ use plume_common::activity_pub::{ IntoId, inbox::{FromActivity, Deletable, Notify} }; +use Connection; use notifications::*; use posts::Post; use users::User; @@ -18,7 +19,7 @@ pub struct Like { pub id: i32, pub user_id: i32, pub post_id: i32, - pub creation_date: chrono::NaiveDateTime, + pub creation_date: NaiveDateTime, pub ap_url: String } @@ -36,7 +37,7 @@ impl Like { find_by!(likes, find_by_ap_url, ap_url as String); find_by!(likes, find_by_user_on_post, user_id as i32, post_id as i32); - pub fn update_ap_url(&self, conn: &PgConnection) { + pub fn update_ap_url(&self, conn: &Connection) { if self.ap_url.len() == 0 { diesel::update(self) .set(likes::ap_url.eq(format!( @@ -48,7 +49,7 @@ impl Like { } } - pub fn into_activity(&self, conn: &PgConnection) -> activity::Like { + pub fn into_activity(&self, conn: &Connection) -> activity::Like { let mut act = activity::Like::default(); act.like_props.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).expect("Like::into_activity: actor error"); act.like_props.set_object_link(Post::get(conn, self.post_id).unwrap().into_id()).expect("Like::into_activity: object error"); @@ -60,8 +61,8 @@ impl Like { } } -impl FromActivity for Like { - fn from_activity(conn: &PgConnection, like: activity::Like, _actor: Id) -> Like { +impl FromActivity for Like { + fn from_activity(conn: &Connection, 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()); let res = Like::insert(conn, NewLike { @@ -74,8 +75,8 @@ impl FromActivity for Like { } } -impl Notify for Like { - fn notify(&self, conn: &PgConnection) { +impl Notify for Like { + fn notify(&self, conn: &Connection) { let post = Post::get(conn, self.post_id).unwrap(); for author in post.get_authors(conn) { Notification::insert(conn, NewNotification { @@ -87,8 +88,8 @@ impl Notify for Like { } } -impl Deletable for Like { - fn delete(&self, conn: &PgConnection) -> activity::Undo { +impl Deletable for Like { + fn delete(&self, conn: &Connection) -> activity::Undo { diesel::delete(self).execute(conn).unwrap(); // delete associated notification if any @@ -106,7 +107,7 @@ impl Deletable for Like { act } - fn delete_id(id: String, conn: &PgConnection) { + fn delete_id(id: String, conn: &Connection) { if let Some(like) = Like::find_by_ap_url(conn, id.into()) { like.delete(conn); } diff --git a/plume-models/src/medias.rs b/plume-models/src/medias.rs index c78edbd9..7785dc4c 100644 --- a/plume-models/src/medias.rs +++ b/plume-models/src/medias.rs @@ -1,8 +1,8 @@ -use diesel::{self, PgConnection, QueryDsl, ExpressionMethods, RunQueryDsl}; +use diesel::{self, QueryDsl, ExpressionMethods, RunQueryDsl}; use serde_json; use std::fs; -use ap_url; +use {ap_url, Connection}; use instance::Instance; use schema::medias; @@ -35,7 +35,7 @@ impl Media { get!(medias); list_by!(medias, for_user, owner_id as i32); - pub fn to_json(&self, conn: &PgConnection) -> serde_json::Value { + pub fn to_json(&self, conn: &Connection) -> serde_json::Value { let mut json = serde_json::to_value(self).unwrap(); let url = self.url(conn); let (preview, html, md) = match self.file_path.rsplitn(2, '.').next().unwrap() { @@ -63,7 +63,7 @@ impl Media { json } - pub fn url(&self, conn: &PgConnection) -> String { + pub fn url(&self, conn: &Connection) -> String { if self.is_remote { self.remote_url.clone().unwrap_or(String::new()) } else { @@ -71,12 +71,12 @@ impl Media { } } - pub fn delete(&self, conn: &PgConnection) { + pub fn delete(&self, conn: &Connection) { fs::remove_file(self.file_path.as_str()).expect("Couldn't delete media from disk"); diesel::delete(self).execute(conn).expect("Couldn't remove media from DB"); } - pub fn save_remote(conn: &PgConnection, url: String) -> Media { + pub fn save_remote(conn: &Connection, url: String) -> Media { Media::insert(conn, NewMedia { file_path: String::new(), alt_text: String::new(), @@ -88,7 +88,7 @@ impl Media { }) } - pub fn set_owner(&self, conn: &PgConnection, id: i32) { + pub fn set_owner(&self, conn: &Connection, id: i32) { diesel::update(self) .set(medias::owner_id.eq(id)) .execute(conn) diff --git a/plume-models/src/mentions.rs b/plume-models/src/mentions.rs index 237a49a7..524a1e96 100644 --- a/plume-models/src/mentions.rs +++ b/plume-models/src/mentions.rs @@ -2,6 +2,7 @@ use activitypub::link; use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; use plume_common::activity_pub::inbox::Notify; +use Connection; use comments::Comment; use notifications::*; use posts::Post; @@ -34,26 +35,26 @@ impl Mention { list_by!(mentions, list_for_post, post_id as i32); list_by!(mentions, list_for_comment, comment_id as i32); - pub fn get_mentioned(&self, conn: &PgConnection) -> Option { + pub fn get_mentioned(&self, conn: &Connection) -> Option { User::get(conn, self.mentioned_id) } - pub fn get_post(&self, conn: &PgConnection) -> Option { + pub fn get_post(&self, conn: &Connection) -> Option { self.post_id.and_then(|id| Post::get(conn, id)) } - pub fn get_comment(&self, conn: &PgConnection) -> Option { + pub fn get_comment(&self, conn: &Connection) -> Option { self.comment_id.and_then(|id| Comment::get(conn, id)) } - pub fn get_user(&self, conn: &PgConnection) -> Option { + pub fn get_user(&self, conn: &Connection) -> Option { match self.get_post(conn) { Some(p) => p.get_authors(conn).into_iter().next(), None => self.get_comment(conn).map(|c| c.get_author(conn)) } } - pub fn build_activity(conn: &PgConnection, ment: String) -> link::Mention { + pub fn build_activity(conn: &Connection, ment: String) -> link::Mention { let user = User::find_by_fqn(conn, ment.clone()); let mut mention = link::Mention::default(); mention.link_props.set_href_string(user.clone().map(|u| u.ap_url).unwrap_or(String::new())).expect("Error setting mention's href"); @@ -61,7 +62,7 @@ impl Mention { mention } - pub fn to_activity(&self, conn: &PgConnection) -> link::Mention { + pub fn to_activity(&self, conn: &Connection) -> link::Mention { let user = self.get_mentioned(conn); let mut mention = link::Mention::default(); mention.link_props.set_href_string(user.clone().map(|u| u.ap_url).unwrap_or(String::new())).expect("Error setting mention's href"); @@ -69,7 +70,7 @@ impl Mention { mention } - pub fn from_activity(conn: &PgConnection, ment: link::Mention, inside: i32, in_post: bool, notify: bool) -> Option { + pub fn from_activity(conn: &Connection, ment: link::Mention, inside: i32, in_post: bool, notify: bool) -> Option { let ap_url = ment.link_props.href_string().ok()?; let mentioned = User::find_by_ap_url(conn, ap_url)?; @@ -104,7 +105,7 @@ impl Mention { } impl Notify for Mention { - fn notify(&self, conn: &PgConnection) { + fn notify(&self, conn: &Connection) { self.get_mentioned(conn).map(|m| { Notification::insert(conn, NewNotification { kind: notification_kind::MENTION.to_string(), diff --git a/plume-models/src/notifications.rs b/plume-models/src/notifications.rs index c30d16d2..6060bc7d 100644 --- a/plume-models/src/notifications.rs +++ b/plume-models/src/notifications.rs @@ -1,7 +1,7 @@ -use chrono::NaiveDateTime; -use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods}; +use diesel::{self, RunQueryDsl, QueryDsl, ExpressionMethods}; use serde_json; +use {Connection, SqlDateTime}; use comments::Comment; use follows::Follow; use likes::Like; @@ -23,7 +23,7 @@ pub mod notification_kind { pub struct Notification { pub id: i32, pub user_id: i32, - pub creation_date: NaiveDateTime, + pub creation_date: SqlDateTime, pub kind: String, pub object_id: i32 } @@ -40,14 +40,14 @@ impl Notification { insert!(notifications, NewNotification); get!(notifications); - pub fn find_for_user(conn: &PgConnection, user: &User) -> Vec { + pub fn find_for_user(conn: &Connection, user: &User) -> Vec { notifications::table.filter(notifications::user_id.eq(user.id)) .order_by(notifications::creation_date.desc()) .load::(conn) .expect("Couldn't load user notifications") } - pub fn page_for_user(conn: &PgConnection, user: &User, (min, max): (i32, i32)) -> Vec { + pub fn page_for_user(conn: &Connection, user: &User, (min, max): (i32, i32)) -> Vec { notifications::table.filter(notifications::user_id.eq(user.id)) .order_by(notifications::creation_date.desc()) .offset(min.into()) @@ -56,14 +56,14 @@ impl Notification { .expect("Couldn't load user notifications page") } - pub fn find>(conn: &PgConnection, kind: S, obj: i32) -> Option { + pub fn find>(conn: &Connection, kind: S, obj: i32) -> Option { notifications::table.filter(notifications::kind.eq(kind.into())) .filter(notifications::object_id.eq(obj)) .get_result::(conn) .ok() } - pub fn to_json(&self, conn: &PgConnection) -> serde_json::Value { + pub fn to_json(&self, conn: &Connection) -> serde_json::Value { let mut json = json!(self); json["object"] = json!(match self.kind.as_ref() { notification_kind::COMMENT => Comment::get(conn, self.object_id).map(|comment| diff --git a/plume-models/src/post_authors.rs b/plume-models/src/post_authors.rs index 25b90e70..2024881a 100644 --- a/plume-models/src/post_authors.rs +++ b/plume-models/src/post_authors.rs @@ -1,4 +1,4 @@ -use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; +use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods}; use posts::Post; use users::User; diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 0e1b2c58..56d26a42 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -5,7 +5,7 @@ use activitypub::{ }; use canapi::{Error, Provider}; use chrono::{NaiveDateTime, TimeZone, Utc}; -use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, BelongingToDsl, dsl::any}; +use diesel::{self, RunQueryDsl, QueryDsl, ExpressionMethods, BelongingToDsl, dsl::any}; use heck::KebabCase; use serde_json; @@ -15,7 +15,7 @@ use plume_common::activity_pub::{ PUBLIC_VISIBILTY, Id, IntoId, inbox::{Deletable, FromActivity} }; -use {BASE_URL, ap_url}; +use {BASE_URL, ap_url, Connection, SqlDateTime}; use blogs::Blog; use instance::Instance; use likes::Like; @@ -36,7 +36,7 @@ pub struct Post { pub content: SafeString, pub published: bool, pub license: String, - pub creation_date: NaiveDateTime, + pub creation_date: SqlDateTime, pub ap_url: String, pub subtitle: String, pub source: String, @@ -112,7 +112,7 @@ impl Post { find_by!(posts, find_by_slug, slug as String, blog_id as i32); find_by!(posts, find_by_ap_url, ap_url as String); - pub fn list_by_tag(conn: &PgConnection, tag: String, (min, max): (i32, i32)) -> Vec { + pub fn list_by_tag(conn: &Connection, tag: String, (min, max): (i32, i32)) -> Vec { use schema::tags; let ids = tags::table.filter(tags::tag.eq(tag)).select(tags::post_id); @@ -125,7 +125,7 @@ impl Post { .expect("Error loading posts by tag") } - pub fn count_for_tag(conn: &PgConnection, tag: String) -> i64 { + pub fn count_for_tag(conn: &Connection, tag: String) -> i64 { use schema::tags; let ids = tags::table.filter(tags::tag.eq(tag)).select(tags::post_id); posts::table.filter(posts::id.eq(any(ids))) @@ -135,7 +135,7 @@ impl Post { .expect("Error counting posts by tag") } - pub fn count_local(conn: &PgConnection) -> usize { + pub fn count_local(conn: &Connection) -> usize { use schema::post_authors; use schema::users; let local_authors = users::table.filter(users::instance_id.eq(Instance::local_id(conn))).select(users::id); @@ -147,11 +147,11 @@ impl Post { .len() } - pub fn count(conn: &PgConnection) -> i64 { + pub fn count(conn: &Connection) -> i64 { posts::table.filter(posts::published.eq(true)).count().get_result(conn).expect("Couldn't count posts") } - pub fn get_recents(conn: &PgConnection, limit: i64) -> Vec { + pub fn get_recents(conn: &Connection, limit: i64) -> Vec { posts::table.order(posts::creation_date.desc()) .filter(posts::published.eq(true)) .limit(limit) @@ -159,7 +159,7 @@ impl Post { .expect("Error loading recent posts") } - pub fn get_recents_for_author(conn: &PgConnection, author: &User, limit: i64) -> Vec { + pub fn get_recents_for_author(conn: &Connection, author: &User, limit: i64) -> Vec { use schema::post_authors; let posts = PostAuthor::belonging_to(author).select(post_authors::post_id); @@ -171,7 +171,7 @@ impl Post { .expect("Error loading recent posts for author") } - pub fn get_recents_for_blog(conn: &PgConnection, blog: &Blog, limit: i64) -> Vec { + pub fn get_recents_for_blog(conn: &Connection, blog: &Blog, limit: i64) -> Vec { posts::table.filter(posts::blog_id.eq(blog.id)) .filter(posts::published.eq(true)) .order(posts::creation_date.desc()) @@ -180,14 +180,14 @@ impl Post { .expect("Error loading recent posts for blog") } - pub fn get_for_blog(conn: &PgConnection, blog:&Blog) -> Vec { + pub fn get_for_blog(conn: &Connection, blog:&Blog) -> Vec { posts::table.filter(posts::blog_id.eq(blog.id)) .filter(posts::published.eq(true)) .load::(conn) .expect("Error loading posts for blog") } - pub fn blog_page(conn: &PgConnection, blog: &Blog, (min, max): (i32, i32)) -> Vec { + pub fn blog_page(conn: &Connection, blog: &Blog, (min, max): (i32, i32)) -> Vec { posts::table.filter(posts::blog_id.eq(blog.id)) .filter(posts::published.eq(true)) .order(posts::creation_date.desc()) @@ -198,7 +198,7 @@ impl Post { } /// Give a page of all the recent posts known to this instance (= federated timeline) - pub fn get_recents_page(conn: &PgConnection, (min, max): (i32, i32)) -> Vec { + pub fn get_recents_page(conn: &Connection, (min, max): (i32, i32)) -> Vec { posts::table.order(posts::creation_date.desc()) .filter(posts::published.eq(true)) .offset(min.into()) @@ -208,7 +208,7 @@ impl Post { } /// Give a page of posts from a specific instance - pub fn get_instance_page(conn: &PgConnection, instance_id: i32, (min, max): (i32, i32)) -> Vec { + pub fn get_instance_page(conn: &Connection, instance_id: i32, (min, max): (i32, i32)) -> Vec { use schema::blogs; let blog_ids = blogs::table.filter(blogs::instance_id.eq(instance_id)).select(blogs::id); @@ -223,7 +223,7 @@ impl Post { } /// Give a page of customized user feed, based on a list of followed users - pub fn user_feed_page(conn: &PgConnection, followed: Vec, (min, max): (i32, i32)) -> Vec { + pub fn user_feed_page(conn: &Connection, followed: Vec, (min, max): (i32, i32)) -> Vec { use schema::post_authors; let post_ids = post_authors::table.filter(post_authors::author_id.eq(any(followed))) .select(post_authors::post_id); @@ -237,7 +237,7 @@ impl Post { .expect("Error loading user feed page") } - pub fn drafts_by_author(conn: &PgConnection, author: &User) -> Vec { + pub fn drafts_by_author(conn: &Connection, author: &User) -> Vec { use schema::post_authors; let posts = PostAuthor::belonging_to(author).select(post_authors::post_id); @@ -248,14 +248,14 @@ impl Post { .expect("Error listing drafts") } - pub fn get_authors(&self, conn: &PgConnection) -> Vec { + pub fn get_authors(&self, conn: &Connection) -> Vec { use schema::users; use schema::post_authors; let author_list = PostAuthor::belonging_to(self).select(post_authors::author_id); users::table.filter(users::id.eq(any(author_list))).load::(conn).unwrap() } - pub fn get_blog(&self, conn: &PgConnection) -> Blog { + pub fn get_blog(&self, conn: &Connection) -> Blog { use schema::blogs; blogs::table.filter(blogs::id.eq(self.blog_id)) .limit(1) @@ -264,21 +264,21 @@ impl Post { .into_iter().nth(0).unwrap() } - pub fn get_likes(&self, conn: &PgConnection) -> Vec { + pub fn get_likes(&self, conn: &Connection) -> Vec { use schema::likes; likes::table.filter(likes::post_id.eq(self.id)) .load::(conn) .expect("Couldn't load likes associted to post") } - pub fn get_reshares(&self, conn: &PgConnection) -> Vec { + pub fn get_reshares(&self, conn: &Connection) -> Vec { use schema::reshares; reshares::table.filter(reshares::post_id.eq(self.id)) .load::(conn) .expect("Couldn't load reshares associted to post") } - pub fn update_ap_url(&self, conn: &PgConnection) -> Post { + pub fn update_ap_url(&self, conn: &Connection) -> Post { if self.ap_url.len() == 0 { diesel::update(self) .set(posts::ap_url.eq(self.compute_id(conn))) @@ -288,7 +288,7 @@ impl Post { } } - pub fn get_receivers_urls(&self, conn: &PgConnection) -> Vec { + pub fn get_receivers_urls(&self, conn: &Connection) -> Vec { let followers = self.get_authors(conn).into_iter().map(|a| a.get_followers(conn)).collect::>>(); let to = followers.into_iter().fold(vec![], |mut acc, f| { for x in f { @@ -299,7 +299,7 @@ impl Post { to } - pub fn into_activity(&self, conn: &PgConnection) -> Article { + pub fn into_activity(&self, conn: &Connection) -> Article { let mut to = self.get_receivers_urls(conn); to.push(PUBLIC_VISIBILTY.to_string()); @@ -328,7 +328,7 @@ impl Post { article } - pub fn create_activity(&self, conn: &PgConnection) -> Create { + pub fn create_activity(&self, conn: &Connection) -> Create { let article = self.into_activity(conn); let mut act = Create::default(); act.object_props.set_id_string(format!("{}activity", self.ap_url)).expect("Post::create_activity: id error"); @@ -341,7 +341,7 @@ impl Post { act } - pub fn update_activity(&self, conn: &PgConnection) -> Update { + pub fn update_activity(&self, conn: &Connection) -> Update { let article = self.into_activity(conn); let mut act = Update::default(); act.object_props.set_id_string(format!("{}/update-{}", self.ap_url, Utc::now().timestamp())).expect("Post::update_activity: id error"); @@ -354,7 +354,7 @@ impl Post { act } - pub fn handle_update(conn: &PgConnection, updated: Article) { + pub fn handle_update(conn: &Connection, updated: Article) { let id = updated.object_props.id_string().expect("Post::handle_update: id error"); let mut post = Post::find_by_ap_url(conn, id).unwrap(); @@ -382,7 +382,7 @@ impl Post { post.update(conn); } - pub fn to_json(&self, conn: &PgConnection) -> serde_json::Value { + pub fn to_json(&self, conn: &Connection) -> serde_json::Value { let blog = self.get_blog(conn); json!({ "post": self, @@ -394,13 +394,13 @@ impl Post { }) } - pub fn compute_id(&self, conn: &PgConnection) -> String { + pub fn compute_id(&self, conn: &Connection) -> String { ap_url(format!("{}/~/{}/{}/", BASE_URL.as_str(), self.get_blog(conn).get_fqn(conn), self.slug)) } } -impl FromActivity for Post { - fn from_activity(conn: &PgConnection, article: Article, _actor: Id) -> Post { +impl FromActivity for Post { + fn from_activity(conn: &Connection, article: Article, _actor: Id) -> Post { if let Some(post) = Post::find_by_ap_url(conn, article.object_props.id_string().unwrap_or(String::new())) { post } else { @@ -457,8 +457,8 @@ impl FromActivity for Post { } } -impl Deletable for Post { - fn delete(&self, conn: &PgConnection) -> Delete { +impl Deletable for Post { + fn delete(&self, conn: &Connection) -> Delete { let mut act = Delete::default(); act.delete_props.set_actor_link(self.get_authors(conn)[0].clone().into_id()).expect("Post::delete: actor error"); @@ -473,7 +473,7 @@ impl Deletable for Post { act } - fn delete_id(id: String, conn: &PgConnection) { + fn delete_id(id: String, conn: &Connection) { Post::find_by_ap_url(conn, id).map(|p| p.delete(conn)); } } diff --git a/plume-models/src/reshares.rs b/plume-models/src/reshares.rs index 17012637..bb3fdbf6 100644 --- a/plume-models/src/reshares.rs +++ b/plume-models/src/reshares.rs @@ -1,8 +1,8 @@ use activitypub::activity::{Announce, Undo}; -use chrono::NaiveDateTime; use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; use plume_common::activity_pub::{Id, IntoId, inbox::{FromActivity, Notify, Deletable}, PUBLIC_VISIBILTY}; +use {Connection, SqlDateTime}; use notifications::*; use posts::Post; use users::User; @@ -14,7 +14,7 @@ pub struct Reshare { pub user_id: i32, pub post_id: i32, pub ap_url: String, - pub creation_date: NaiveDateTime + pub creation_date: SqlDateTime } #[derive(Insertable)] @@ -31,7 +31,7 @@ impl Reshare { find_by!(reshares, find_by_ap_url, ap_url as String); find_by!(reshares, find_by_user_on_post, user_id as i32, post_id as i32); - pub fn update_ap_url(&self, conn: &PgConnection) { + pub fn update_ap_url(&self, conn: &Connection) { if self.ap_url.len() == 0 { diesel::update(self) .set(reshares::ap_url.eq(format!( @@ -43,7 +43,7 @@ impl Reshare { } } - pub fn get_recents_for_author(conn: &PgConnection, user: &User, limit: i64) -> Vec { + pub fn get_recents_for_author(conn: &Connection, user: &User, limit: i64) -> Vec { reshares::table.filter(reshares::user_id.eq(user.id)) .order(reshares::creation_date.desc()) .limit(limit) @@ -51,15 +51,15 @@ impl Reshare { .expect("Error loading recent reshares for user") } - pub fn get_post(&self, conn: &PgConnection) -> Option { + pub fn get_post(&self, conn: &Connection) -> Option { Post::get(conn, self.post_id) } - pub fn get_user(&self, conn: &PgConnection) -> Option { + pub fn get_user(&self, conn: &Connection) -> Option { User::get(conn, self.user_id) } - pub fn into_activity(&self, conn: &PgConnection) -> Announce { + pub fn into_activity(&self, conn: &Connection) -> Announce { let mut act = Announce::default(); act.announce_props.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); act.announce_props.set_object_link(Post::get(conn, self.post_id).unwrap().into_id()).unwrap(); @@ -72,7 +72,7 @@ impl Reshare { } impl FromActivity for Reshare { - fn from_activity(conn: &PgConnection, announce: Announce, _actor: Id) -> Reshare { + fn from_activity(conn: &Connection, announce: Announce, _actor: Id) -> Reshare { let user = User::from_url(conn, announce.announce_props.actor_link::().expect("Reshare::from_activity: actor error").into()); let post = Post::find_by_ap_url(conn, announce.announce_props.object_link::().expect("Reshare::from_activity: object error").into()); let reshare = Reshare::insert(conn, NewReshare { @@ -86,7 +86,7 @@ impl FromActivity for Reshare { } impl Notify for Reshare { - fn notify(&self, conn: &PgConnection) { + fn notify(&self, conn: &Connection) { let post = self.get_post(conn).unwrap(); for author in post.get_authors(conn) { Notification::insert(conn, NewNotification { @@ -99,7 +99,7 @@ impl Notify for Reshare { } impl Deletable for Reshare { - fn delete(&self, conn: &PgConnection) -> Undo { + fn delete(&self, conn: &Connection) -> Undo { diesel::delete(self).execute(conn).unwrap(); // delete associated notification if any @@ -117,7 +117,7 @@ impl Deletable for Reshare { act } - fn delete_id(id: String, conn: &PgConnection) { + fn delete_id(id: String, conn: &Connection) { if let Some(reshare) = Reshare::find_by_ap_url(conn, id) { reshare.delete(conn); } diff --git a/plume-models/src/schema.rs b/plume-models/src/schema.rs index 539db327..7d51d678 100644 --- a/plume-models/src/schema.rs +++ b/plume-models/src/schema.rs @@ -1,21 +1,21 @@ table! { blog_authors (id) { - id -> Integer, - blog_id -> Integer, - author_id -> Integer, + id -> Int4, + blog_id -> Int4, + author_id -> Int4, is_owner -> Bool, } } table! { blogs (id) { - id -> Integer, - actor_id -> Text, - title -> Text, + id -> Int4, + actor_id -> Varchar, + title -> Varchar, summary -> Text, - outbox_url -> Text, - inbox_url -> Text, - instance_id -> Integer, + outbox_url -> Varchar, + inbox_url -> Varchar, + instance_id -> Int4, creation_date -> Timestamp, ap_url -> Text, private_key -> Nullable, @@ -25,13 +25,13 @@ table! { table! { comments (id) { - id -> Integer, + id -> Int4, content -> Text, - in_response_to_id -> Nullable, - post_id -> Integer, - author_id -> Integer, + in_response_to_id -> Nullable, + post_id -> Int4, + author_id -> Int4, creation_date -> Timestamp, - ap_url -> Nullable, + ap_url -> Nullable, sensitive -> Bool, spoiler_text -> Text, } @@ -39,18 +39,18 @@ table! { table! { follows (id) { - id -> Integer, - follower_id -> Integer, - following_id -> Integer, + id -> Int4, + follower_id -> Int4, + following_id -> Int4, ap_url -> Text, } } table! { instances (id) { - id -> Integer, - public_domain -> Text, - name -> Text, + id -> Int4, + public_domain -> Varchar, + name -> Varchar, local -> Bool, blocked -> Bool, creation_date -> Timestamp, @@ -58,73 +58,73 @@ table! { short_description -> Text, long_description -> Text, default_license -> Text, - long_description_html -> Text, - short_description_html -> Text, + long_description_html -> Varchar, + short_description_html -> Varchar, } } table! { likes (id) { - id -> Integer, - user_id -> Integer, - post_id -> Integer, - ap_url -> Text, + id -> Int4, + user_id -> Int4, + post_id -> Int4, creation_date -> Timestamp, + ap_url -> Varchar, } } table! { medias (id) { - id -> Integer, + id -> Int4, file_path -> Text, alt_text -> Text, is_remote -> Bool, remote_url -> Nullable, sensitive -> Bool, content_warning -> Nullable, - owner_id -> Integer, + owner_id -> Int4, } } table! { mentions (id) { - id -> Integer, - mentioned_id -> Integer, - post_id -> Nullable, - comment_id -> Nullable, - ap_url -> Text, + id -> Int4, + mentioned_id -> Int4, + post_id -> Nullable, + comment_id -> Nullable, + ap_url -> Varchar, } } table! { notifications (id) { - id -> Integer, - user_id -> Integer, + id -> Int4, + user_id -> Int4, creation_date -> Timestamp, - kind -> Text, - object_id -> Integer, + kind -> Varchar, + object_id -> Int4, } } table! { post_authors (id) { - id -> Integer, - post_id -> Integer, - author_id -> Integer, + id -> Int4, + post_id -> Int4, + author_id -> Int4, } } table! { posts (id) { - id -> Integer, - blog_id -> Integer, - slug -> Text, - title -> Text, + id -> Int4, + blog_id -> Int4, + slug -> Varchar, + title -> Varchar, content -> Text, published -> Bool, - license -> Text, + license -> Varchar, creation_date -> Timestamp, - ap_url -> Text, + ap_url -> Varchar, subtitle -> Text, source -> Text, } @@ -132,42 +132,42 @@ table! { table! { reshares (id) { - id -> Integer, - user_id -> Integer, - post_id -> Integer, - ap_url -> Text, + id -> Int4, + user_id -> Int4, + post_id -> Int4, + ap_url -> Varchar, creation_date -> Timestamp, } } table! { tags (id) { - id -> Integer, + id -> Int4, tag -> Text, is_hastag -> Bool, - post_id -> Integer, + post_id -> Int4, } } table! { users (id) { - id -> Integer, - username -> Text, - display_name -> Text, - outbox_url -> Text, - inbox_url -> Text, + id -> Int4, + username -> Varchar, + display_name -> Varchar, + outbox_url -> Varchar, + inbox_url -> Varchar, is_admin -> Bool, summary -> Text, email -> Nullable, hashed_password -> Nullable, - instance_id -> Integer, + instance_id -> Int4, creation_date -> Timestamp, ap_url -> Text, private_key -> Nullable, public_key -> Text, - shared_inbox_url -> Nullable, - followers_endpoint -> Text, - avatar_id -> Nullable, + shared_inbox_url -> Nullable, + followers_endpoint -> Varchar, + avatar_id -> Nullable, last_fetched_date -> Timestamp, } } diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index b8ac6147..d906601f 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -1,7 +1,7 @@ -use diesel::{self, PgConnection, ExpressionMethods, RunQueryDsl, QueryDsl}; +use diesel::{self, ExpressionMethods, RunQueryDsl, QueryDsl}; use plume_common::activity_pub::Hashtag; -use ap_url; +use {ap_url, Connection}; use instance::Instance; use schema::tags; @@ -27,14 +27,14 @@ impl Tag { find_by!(tags, find_by_name, tag as String); list_by!(tags, for_post, post_id as i32); - pub fn into_activity(&self, conn: &PgConnection) -> Hashtag { + pub fn into_activity(&self, conn: &Connection) -> Hashtag { let mut ht = Hashtag::default(); ht.set_href_string(ap_url(format!("{}/tag/{}", Instance::get_local(conn).unwrap().public_domain, self.tag))).expect("Tag::into_activity: href error"); ht.set_name_string(self.tag.clone()).expect("Tag::into_activity: name error"); ht } - pub fn from_activity(conn: &PgConnection, tag: Hashtag, post: i32) -> Tag { + pub fn from_activity(conn: &Connection, tag: Hashtag, post: i32) -> Tag { Tag::insert(conn, NewTag { tag: tag.name_string().expect("Tag::from_activity: name error"), is_hastag: false, diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index d8addb19..c26421bb 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -5,8 +5,8 @@ use activitypub::{ object::Image, }; use bcrypt; -use chrono::{NaiveDateTime, Utc}; -use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, BelongingToDsl, PgConnection, dsl::any}; +use chrono::{Utc, NaiveDateTime}; +use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, BelongingToDsl, dsl::any}; use openssl::{ hash::MessageDigest, pkey::{PKey, Private}, @@ -31,7 +31,7 @@ use serde_json; use url::Url; use webfinger::*; -use {BASE_URL, USE_HTTPS, ap_url}; +use {BASE_URL, USE_HTTPS, ap_url, Connection}; use db_conn::DbConn; use blogs::Blog; use blog_authors::BlogAuthor; @@ -100,28 +100,28 @@ impl User { find_by!(users, find_by_name, username as String, instance_id as i32); find_by!(users, find_by_ap_url, ap_url as String); - pub fn one_by_instance(conn: &PgConnection) -> Vec { + pub fn one_by_instance(conn: &Connection) -> Vec { users::table.distinct_on(users::instance_id) .get_results::(conn) .expect("Error in User::on_by_instance") } - pub fn delete(&self, conn: &PgConnection) { + pub fn delete(&self, conn: &Connection) { diesel::delete(self).execute(conn).expect("Couldn't remove user from DB"); } - pub fn get_instance(&self, conn: &PgConnection) -> Instance { + pub fn get_instance(&self, conn: &Connection) -> Instance { Instance::get(conn, self.instance_id).expect("Couldn't find instance") } - pub fn grant_admin_rights(&self, conn: &PgConnection) { + pub fn grant_admin_rights(&self, conn: &Connection) { diesel::update(self) .set(users::is_admin.eq(true)) .load::(conn) .expect("Couldn't grant admin rights"); } - pub fn update(&self, conn: &PgConnection, name: String, email: String, summary: String) -> User { + pub fn update(&self, conn: &Connection, name: String, email: String, summary: String) -> User { diesel::update(self) .set(( users::display_name.eq(name), @@ -132,18 +132,18 @@ impl User { .into_iter().nth(0).unwrap() } - pub fn count_local(conn: &PgConnection) -> usize { + pub fn count_local(conn: &Connection) -> usize { users::table.filter(users::instance_id.eq(Instance::local_id(conn))) .load::(conn) .expect("Couldn't load local users") .len() } - pub fn find_local(conn: &PgConnection, username: String) -> Option { + pub fn find_local(conn: &Connection, username: String) -> Option { User::find_by_name(conn, username, Instance::local_id(conn)) } - pub fn find_by_fqn(conn: &PgConnection, fqn: String) -> Option { + pub fn find_by_fqn(conn: &Connection, fqn: String) -> Option { if fqn.contains("@") { // remote user match Instance::find_by_domain(conn, String::from(fqn.split("@").last().unwrap())) { Some(instance) => { @@ -159,7 +159,7 @@ impl User { } } - fn fetch_from_webfinger(conn: &PgConnection, acct: String) -> Option { + fn fetch_from_webfinger(conn: &Connection, acct: String) -> Option { match resolve(acct.clone(), *USE_HTTPS) { Ok(wf) => wf.links.into_iter().find(|l| l.mime_type == Some(String::from("application/activity+json"))).and_then(|l| User::fetch_from_url(conn, l.href.expect("No href for AP WF link"))), Err(details) => { @@ -192,11 +192,11 @@ impl User { } } - pub fn fetch_from_url(conn: &PgConnection, url: String) -> Option { + pub fn fetch_from_url(conn: &Connection, url: String) -> Option { User::fetch(url.clone()).map(|json| (User::from_activity(conn, json, Url::parse(url.as_ref()).unwrap().host_str().unwrap().to_string()))) } - fn from_activity(conn: &PgConnection, acct: CustomPerson, inst: String) -> User { + fn from_activity(conn: &Connection, acct: CustomPerson, inst: String) -> User { let instance = match Instance::find_by_domain(conn, inst.clone()) { Some(instance) => instance, None => { @@ -242,7 +242,7 @@ impl User { user } - pub fn refetch(&self, conn: &PgConnection) { + pub fn refetch(&self, conn: &Connection) { User::fetch(self.ap_url.clone()).map(|json| { let avatar = Media::save_remote(conn, json.object.object_props.icon_image().expect("User::refetch: icon error") .object_props.url_string().expect("User::refetch: icon.url error")); @@ -274,7 +274,7 @@ impl User { } } - pub fn update_boxes(&self, conn: &PgConnection) { + pub fn update_boxes(&self, conn: &Connection) { let instance = self.get_instance(conn); if self.outbox_url.len() == 0 { diesel::update(self) @@ -307,7 +307,7 @@ impl User { } } - pub fn get_local_page(conn: &PgConnection, (min, max): (i32, i32)) -> Vec { + pub fn get_local_page(conn: &Connection, (min, max): (i32, i32)) -> Vec { users::table.filter(users::instance_id.eq(1)) .order(users::username.asc()) .offset(min.into()) @@ -316,7 +316,7 @@ impl User { .expect("Error getting local users page") } - pub fn outbox(&self, conn: &PgConnection) -> ActivityStream { + pub fn outbox(&self, conn: &Connection) -> ActivityStream { let acts = self.get_activities(conn); let n_acts = acts.len(); let mut coll = OrderedCollection::default(); @@ -369,7 +369,7 @@ impl User { } } - fn get_activities(&self, conn: &PgConnection) -> Vec { + fn get_activities(&self, conn: &Connection) -> Vec { use schema::posts; use schema::post_authors; let posts_by_self = PostAuthor::belonging_to(self).select(post_authors::post_id); @@ -382,7 +382,7 @@ impl User { }).collect::>() } - pub fn get_fqn(&self, conn: &PgConnection) -> String { + pub fn get_fqn(&self, conn: &Connection) -> String { if self.instance_id == Instance::local_id(conn) { self.username.clone() } else { @@ -390,13 +390,13 @@ impl User { } } - pub fn get_followers(&self, conn: &PgConnection) -> Vec { + pub fn get_followers(&self, conn: &Connection) -> Vec { use schema::follows; let follows = Follow::belonging_to(self).select(follows::follower_id); users::table.filter(users::id.eq(any(follows))).load::(conn).unwrap() } - pub fn get_followers_page(&self, conn: &PgConnection, (min, max): (i32, i32)) -> Vec { + pub fn get_followers_page(&self, conn: &Connection, (min, max): (i32, i32)) -> Vec { use schema::follows; let follows = Follow::belonging_to(self).select(follows::follower_id); users::table.filter(users::id.eq(any(follows))) @@ -405,13 +405,13 @@ impl User { .load::(conn).unwrap() } - pub fn get_following(&self, conn: &PgConnection) -> Vec { + pub fn get_following(&self, conn: &Connection) -> Vec { use schema::follows; let follows = follows::table.filter(follows::follower_id.eq(self.id)).select(follows::following_id); users::table.filter(users::id.eq(any(follows))).load::(conn).unwrap() } - pub fn is_followed_by(&self, conn: &PgConnection, other_id: i32) -> bool { + pub fn is_followed_by(&self, conn: &Connection, other_id: i32) -> bool { use schema::follows; follows::table .filter(follows::follower_id.eq(other_id)) @@ -421,7 +421,7 @@ impl User { .len() > 0 } - pub fn is_following(&self, conn: &PgConnection, other_id: i32) -> bool { + pub fn is_following(&self, conn: &Connection, other_id: i32) -> bool { use schema::follows; follows::table .filter(follows::follower_id.eq(self.id)) @@ -431,7 +431,7 @@ impl User { .len() > 0 } - pub fn has_liked(&self, conn: &PgConnection, post: &Post) -> bool { + pub fn has_liked(&self, conn: &Connection, post: &Post) -> bool { use schema::likes; likes::table .filter(likes::post_id.eq(post.id)) @@ -441,7 +441,7 @@ impl User { .len() > 0 } - pub fn has_reshared(&self, conn: &PgConnection, post: &Post) -> bool { + pub fn has_reshared(&self, conn: &Connection, post: &Post) -> bool { use schema::reshares; reshares::table .filter(reshares::post_id.eq(post.id)) @@ -451,7 +451,7 @@ impl User { .len() > 0 } - pub fn is_author_in(&self, conn: &PgConnection, blog: Blog) -> bool { + pub fn is_author_in(&self, conn: &Connection, blog: Blog) -> bool { use schema::blog_authors; blog_authors::table.filter(blog_authors::author_id.eq(self.id)) .filter(blog_authors::blog_id.eq(blog.id)) @@ -464,7 +464,7 @@ impl User { PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.clone().unwrap().as_ref()).unwrap()).unwrap() } - pub fn into_activity(&self, conn: &PgConnection) -> CustomPerson { + pub fn into_activity(&self, conn: &Connection) -> CustomPerson { let mut actor = Person::default(); actor.object_props.set_id_string(self.ap_url.clone()).expect("User::into_activity: id error"); actor.object_props.set_name_string(self.display_name.clone()).expect("User::into_activity: name error"); @@ -494,7 +494,7 @@ impl User { CustomPerson::new(actor, ap_signature) } - pub fn to_json(&self, conn: &PgConnection) -> serde_json::Value { + pub fn to_json(&self, conn: &Connection) -> serde_json::Value { let mut json = serde_json::to_value(self).unwrap(); json["fqn"] = serde_json::Value::String(self.get_fqn(conn)); json["name"] = if self.display_name.len() > 0 { @@ -506,7 +506,7 @@ impl User { json } - pub fn webfinger(&self, conn: &PgConnection) -> Webfinger { + pub fn webfinger(&self, conn: &Connection) -> Webfinger { Webfinger { subject: format!("acct:{}@{}", self.username, self.get_instance(conn).public_domain), aliases: vec![self.ap_url.clone()], @@ -533,7 +533,7 @@ impl User { } } - pub fn from_url(conn: &PgConnection, url: String) -> Option { + pub fn from_url(conn: &Connection, url: String) -> Option { User::find_by_ap_url(conn, url.clone()).or_else(|| { // The requested user was not in the DB // We try to fetch it if it is remote @@ -545,7 +545,7 @@ impl User { }) } - pub fn set_avatar(&self, conn: &PgConnection, id: i32) { + pub fn set_avatar(&self, conn: &Connection, id: i32) { diesel::update(self) .set(users::avatar_id.eq(id)) .execute(conn) @@ -609,7 +609,7 @@ impl Signer for User { impl NewUser { /// Creates a new local user pub fn new_local( - conn: &PgConnection, + conn: &Connection, username: String, display_name: String, is_admin: bool,