mirror of
https://git.joinplu.me/Plume/Plume.git
synced 2024-11-25 21:11:01 +00:00
Introduce features to choose between SQlite or Postgres
This commit is contained in:
parent
88456faf84
commit
38d737ed0c
20 changed files with 265 additions and 239 deletions
|
@ -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"]
|
||||
|
|
|
@ -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 ''
|
||||
)
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection};
|
||||
use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods};
|
||||
|
||||
use schema::blog_authors;
|
||||
|
||||
|
|
|
@ -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<String>,
|
||||
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<User> {
|
||||
pub fn list_authors(&self, conn: &Connection) -> Vec<User> {
|
||||
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<Blog> {
|
||||
pub fn find_for_author(conn: &Connection, author_id: i32) -> Vec<Blog> {
|
||||
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<Blog> {
|
||||
pub fn find_local(conn: &Connection, name: String) -> Option<Blog> {
|
||||
Blog::find_by_name(conn, name, Instance::local_id(conn))
|
||||
}
|
||||
|
||||
pub fn find_by_fqn(conn: &PgConnection, fqn: String) -> Option<Blog> {
|
||||
pub fn find_by_fqn(conn: &Connection, fqn: String) -> Option<Blog> {
|
||||
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<Blog> {
|
||||
fn fetch_from_webfinger(conn: &Connection, acct: String) -> Option<Blog> {
|
||||
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<Blog> {
|
||||
fn fetch_from_url(conn: &Connection, url: String) -> Option<Blog> {
|
||||
let req = Client::new()
|
||||
.get(&url[..])
|
||||
.header(Accept(ap_accept_header().into_iter().map(|h| qitem(h.parse::<Mime>().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<OrderedCollection> {
|
||||
pub fn outbox(&self, conn: &Connection) -> ActivityStream<OrderedCollection> {
|
||||
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<serde_json::Value> {
|
||||
fn get_activities(&self, _conn: &Connection) -> Vec<serde_json::Value> {
|
||||
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<Blog> {
|
||||
pub fn from_url(conn: &Connection, url: String) -> Option<Blog> {
|
||||
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
|
||||
|
|
|
@ -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<i32>,
|
||||
pub post_id: i32,
|
||||
pub author_id: i32,
|
||||
pub creation_date: chrono::NaiveDateTime,
|
||||
pub creation_date: SqlDateTime,
|
||||
pub ap_url: Option<String>,
|
||||
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<Comment>) -> serde_json::Value {
|
||||
pub fn to_json(&self, conn: &Connection, others: &Vec<Comment>) -> 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<Note, PgConnection> 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<Note, PgConnection> for Comment {
|
|||
}
|
||||
|
||||
impl Notify<PgConnection> 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(),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<Follow> {
|
||||
pub fn find(conn: &Connection, from: i32, to: i32) -> Option<Follow> {
|
||||
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<A: Signer + IntoId + Clone, B: Clone + WithInbox + Actor + IntoId>(
|
||||
conn: &PgConnection,
|
||||
conn: &Connection,
|
||||
from: &B,
|
||||
target: &A,
|
||||
follow: FollowAct,
|
||||
|
@ -80,7 +81,7 @@ impl Follow {
|
|||
}
|
||||
|
||||
impl FromActivity<FollowAct, PgConnection> 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::<Id>().map(|l| l.into())
|
||||
.unwrap_or_else(|_| follow.follow_props.actor_object::<Person>().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<FollowAct, PgConnection> for Follow {
|
|||
}
|
||||
|
||||
impl Notify<PgConnection> 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<PgConnection> for Follow {
|
|||
}
|
||||
|
||||
impl Deletable<PgConnection, Undo> 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<PgConnection, Undo> 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);
|
||||
}
|
||||
|
|
|
@ -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<Instance> {
|
||||
pub fn get_local(conn: &Connection) -> Option<Instance> {
|
||||
instances::table.filter(instances::local.eq(true))
|
||||
.limit(1)
|
||||
.load::<Instance>(conn)
|
||||
|
@ -47,13 +47,13 @@ impl Instance {
|
|||
.into_iter().nth(0)
|
||||
}
|
||||
|
||||
pub fn get_remotes(conn: &PgConnection) -> Vec<Instance> {
|
||||
pub fn get_remotes(conn: &Connection) -> Vec<Instance> {
|
||||
instances::table.filter(instances::local.eq(false))
|
||||
.load::<Instance>(conn)
|
||||
.expect("Error loading remote instances infos")
|
||||
}
|
||||
|
||||
pub fn page(conn: &PgConnection, (min, max): (i32, i32)) -> Vec<Instance> {
|
||||
pub fn page(conn: &Connection, (min, max): (i32, i32)) -> Vec<Instance> {
|
||||
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::<Instance>(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::<Instance>(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::<User>(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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Self> {
|
||||
pub fn $fn(conn: &crate::Connection, $($col: $type),+) -> Option<Self> {
|
||||
$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<Self> {
|
||||
pub fn $fn(conn: &crate::Connection, $($col: $type),+) -> Vec<Self> {
|
||||
$table::table
|
||||
$(.filter($table::$col.eq($col)))+
|
||||
.load::<Self>(conn)
|
||||
|
@ -53,7 +54,7 @@ macro_rules! list_by {
|
|||
|
||||
macro_rules! get {
|
||||
($table:ident) => {
|
||||
pub fn get(conn: &PgConnection, id: i32) -> Option<Self> {
|
||||
pub fn get(conn: &crate::Connection, id: i32) -> Option<Self> {
|
||||
$table::table.filter($table::id.eq(id))
|
||||
.limit(1)
|
||||
.load::<Self>(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;
|
||||
|
|
|
@ -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<activity::Like, PgConnection> for Like {
|
||||
fn from_activity(conn: &PgConnection, like: activity::Like, _actor: Id) -> Like {
|
||||
impl FromActivity<activity::Like, Connection> 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<activity::Like, PgConnection> for Like {
|
|||
}
|
||||
}
|
||||
|
||||
impl Notify<PgConnection> for Like {
|
||||
fn notify(&self, conn: &PgConnection) {
|
||||
impl Notify<Connection> 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<PgConnection> for Like {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deletable<PgConnection, activity::Undo> for Like {
|
||||
fn delete(&self, conn: &PgConnection) -> activity::Undo {
|
||||
impl Deletable<Connection, activity::Undo> 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<PgConnection, activity::Undo> 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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<User> {
|
||||
pub fn get_mentioned(&self, conn: &Connection) -> Option<User> {
|
||||
User::get(conn, self.mentioned_id)
|
||||
}
|
||||
|
||||
pub fn get_post(&self, conn: &PgConnection) -> Option<Post> {
|
||||
pub fn get_post(&self, conn: &Connection) -> Option<Post> {
|
||||
self.post_id.and_then(|id| Post::get(conn, id))
|
||||
}
|
||||
|
||||
pub fn get_comment(&self, conn: &PgConnection) -> Option<Comment> {
|
||||
pub fn get_comment(&self, conn: &Connection) -> Option<Comment> {
|
||||
self.comment_id.and_then(|id| Comment::get(conn, id))
|
||||
}
|
||||
|
||||
pub fn get_user(&self, conn: &PgConnection) -> Option<User> {
|
||||
pub fn get_user(&self, conn: &Connection) -> Option<User> {
|
||||
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<Self> {
|
||||
pub fn from_activity(conn: &Connection, ment: link::Mention, inside: i32, in_post: bool, notify: bool) -> Option<Self> {
|
||||
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<PgConnection> 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(),
|
||||
|
|
|
@ -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<Notification> {
|
||||
pub fn find_for_user(conn: &Connection, user: &User) -> Vec<Notification> {
|
||||
notifications::table.filter(notifications::user_id.eq(user.id))
|
||||
.order_by(notifications::creation_date.desc())
|
||||
.load::<Notification>(conn)
|
||||
.expect("Couldn't load user notifications")
|
||||
}
|
||||
|
||||
pub fn page_for_user(conn: &PgConnection, user: &User, (min, max): (i32, i32)) -> Vec<Notification> {
|
||||
pub fn page_for_user(conn: &Connection, user: &User, (min, max): (i32, i32)) -> Vec<Notification> {
|
||||
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<S: Into<String>>(conn: &PgConnection, kind: S, obj: i32) -> Option<Notification> {
|
||||
pub fn find<S: Into<String>>(conn: &Connection, kind: S, obj: i32) -> Option<Notification> {
|
||||
notifications::table.filter(notifications::kind.eq(kind.into()))
|
||||
.filter(notifications::object_id.eq(obj))
|
||||
.get_result::<Notification>(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|
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods};
|
||||
use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods};
|
||||
|
||||
use posts::Post;
|
||||
use users::User;
|
||||
|
|
|
@ -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<Post> {
|
||||
pub fn list_by_tag(conn: &Connection, tag: String, (min, max): (i32, i32)) -> Vec<Post> {
|
||||
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<Post> {
|
||||
pub fn get_recents(conn: &Connection, limit: i64) -> Vec<Post> {
|
||||
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<Post> {
|
||||
pub fn get_recents_for_author(conn: &Connection, author: &User, limit: i64) -> Vec<Post> {
|
||||
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<Post> {
|
||||
pub fn get_recents_for_blog(conn: &Connection, blog: &Blog, limit: i64) -> Vec<Post> {
|
||||
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<Post> {
|
||||
pub fn get_for_blog(conn: &Connection, blog:&Blog) -> Vec<Post> {
|
||||
posts::table.filter(posts::blog_id.eq(blog.id))
|
||||
.filter(posts::published.eq(true))
|
||||
.load::<Post>(conn)
|
||||
.expect("Error loading posts for blog")
|
||||
}
|
||||
|
||||
pub fn blog_page(conn: &PgConnection, blog: &Blog, (min, max): (i32, i32)) -> Vec<Post> {
|
||||
pub fn blog_page(conn: &Connection, blog: &Blog, (min, max): (i32, i32)) -> Vec<Post> {
|
||||
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<Post> {
|
||||
pub fn get_recents_page(conn: &Connection, (min, max): (i32, i32)) -> Vec<Post> {
|
||||
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<Post> {
|
||||
pub fn get_instance_page(conn: &Connection, instance_id: i32, (min, max): (i32, i32)) -> Vec<Post> {
|
||||
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<i32>, (min, max): (i32, i32)) -> Vec<Post> {
|
||||
pub fn user_feed_page(conn: &Connection, followed: Vec<i32>, (min, max): (i32, i32)) -> Vec<Post> {
|
||||
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<Post> {
|
||||
pub fn drafts_by_author(conn: &Connection, author: &User) -> Vec<Post> {
|
||||
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<User> {
|
||||
pub fn get_authors(&self, conn: &Connection) -> Vec<User> {
|
||||
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::<User>(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<Like> {
|
||||
pub fn get_likes(&self, conn: &Connection) -> Vec<Like> {
|
||||
use schema::likes;
|
||||
likes::table.filter(likes::post_id.eq(self.id))
|
||||
.load::<Like>(conn)
|
||||
.expect("Couldn't load likes associted to post")
|
||||
}
|
||||
|
||||
pub fn get_reshares(&self, conn: &PgConnection) -> Vec<Reshare> {
|
||||
pub fn get_reshares(&self, conn: &Connection) -> Vec<Reshare> {
|
||||
use schema::reshares;
|
||||
reshares::table.filter(reshares::post_id.eq(self.id))
|
||||
.load::<Reshare>(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<String> {
|
||||
pub fn get_receivers_urls(&self, conn: &Connection) -> Vec<String> {
|
||||
let followers = self.get_authors(conn).into_iter().map(|a| a.get_followers(conn)).collect::<Vec<Vec<User>>>();
|
||||
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<Article, PgConnection> for Post {
|
||||
fn from_activity(conn: &PgConnection, article: Article, _actor: Id) -> Post {
|
||||
impl FromActivity<Article, Connection> 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<Article, PgConnection> for Post {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deletable<PgConnection, Delete> for Post {
|
||||
fn delete(&self, conn: &PgConnection) -> Delete {
|
||||
impl Deletable<Connection, Delete> 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<PgConnection, Delete> 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Reshare> {
|
||||
pub fn get_recents_for_author(conn: &Connection, user: &User, limit: i64) -> Vec<Reshare> {
|
||||
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<Post> {
|
||||
pub fn get_post(&self, conn: &Connection) -> Option<Post> {
|
||||
Post::get(conn, self.post_id)
|
||||
}
|
||||
|
||||
pub fn get_user(&self, conn: &PgConnection) -> Option<User> {
|
||||
pub fn get_user(&self, conn: &Connection) -> Option<User> {
|
||||
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<Announce, PgConnection> 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::<Id>().expect("Reshare::from_activity: actor error").into());
|
||||
let post = Post::find_by_ap_url(conn, announce.announce_props.object_link::<Id>().expect("Reshare::from_activity: object error").into());
|
||||
let reshare = Reshare::insert(conn, NewReshare {
|
||||
|
@ -86,7 +86,7 @@ impl FromActivity<Announce, PgConnection> for Reshare {
|
|||
}
|
||||
|
||||
impl Notify<PgConnection> 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<PgConnection> for Reshare {
|
|||
}
|
||||
|
||||
impl Deletable<PgConnection, Undo> 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<PgConnection, Undo> 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);
|
||||
}
|
||||
|
|
|
@ -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<Text>,
|
||||
|
@ -25,13 +25,13 @@ table! {
|
|||
|
||||
table! {
|
||||
comments (id) {
|
||||
id -> Integer,
|
||||
id -> Int4,
|
||||
content -> Text,
|
||||
in_response_to_id -> Nullable<Integer>,
|
||||
post_id -> Integer,
|
||||
author_id -> Integer,
|
||||
in_response_to_id -> Nullable<Int4>,
|
||||
post_id -> Int4,
|
||||
author_id -> Int4,
|
||||
creation_date -> Timestamp,
|
||||
ap_url -> Nullable<Text>,
|
||||
ap_url -> Nullable<Varchar>,
|
||||
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<Text>,
|
||||
sensitive -> Bool,
|
||||
content_warning -> Nullable<Text>,
|
||||
owner_id -> Integer,
|
||||
owner_id -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
mentions (id) {
|
||||
id -> Integer,
|
||||
mentioned_id -> Integer,
|
||||
post_id -> Nullable<Integer>,
|
||||
comment_id -> Nullable<Integer>,
|
||||
ap_url -> Text,
|
||||
id -> Int4,
|
||||
mentioned_id -> Int4,
|
||||
post_id -> Nullable<Int4>,
|
||||
comment_id -> Nullable<Int4>,
|
||||
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<Text>,
|
||||
hashed_password -> Nullable<Text>,
|
||||
instance_id -> Integer,
|
||||
instance_id -> Int4,
|
||||
creation_date -> Timestamp,
|
||||
ap_url -> Text,
|
||||
private_key -> Nullable<Text>,
|
||||
public_key -> Text,
|
||||
shared_inbox_url -> Nullable<Text>,
|
||||
followers_endpoint -> Text,
|
||||
avatar_id -> Nullable<Integer>,
|
||||
shared_inbox_url -> Nullable<Varchar>,
|
||||
followers_endpoint -> Varchar,
|
||||
avatar_id -> Nullable<Int4>,
|
||||
last_fetched_date -> Timestamp,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<User> {
|
||||
pub fn one_by_instance(conn: &Connection) -> Vec<User> {
|
||||
users::table.distinct_on(users::instance_id)
|
||||
.get_results::<User>(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::<User>(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::<User>(conn)
|
||||
.expect("Couldn't load local users")
|
||||
.len()
|
||||
}
|
||||
|
||||
pub fn find_local(conn: &PgConnection, username: String) -> Option<User> {
|
||||
pub fn find_local(conn: &Connection, username: String) -> Option<User> {
|
||||
User::find_by_name(conn, username, Instance::local_id(conn))
|
||||
}
|
||||
|
||||
pub fn find_by_fqn(conn: &PgConnection, fqn: String) -> Option<User> {
|
||||
pub fn find_by_fqn(conn: &Connection, fqn: String) -> Option<User> {
|
||||
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<User> {
|
||||
fn fetch_from_webfinger(conn: &Connection, acct: String) -> Option<User> {
|
||||
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<User> {
|
||||
pub fn fetch_from_url(conn: &Connection, url: String) -> Option<User> {
|
||||
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<User> {
|
||||
pub fn get_local_page(conn: &Connection, (min, max): (i32, i32)) -> Vec<User> {
|
||||
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<OrderedCollection> {
|
||||
pub fn outbox(&self, conn: &Connection) -> ActivityStream<OrderedCollection> {
|
||||
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<serde_json::Value> {
|
||||
fn get_activities(&self, conn: &Connection) -> Vec<serde_json::Value> {
|
||||
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::<Vec<serde_json::Value>>()
|
||||
}
|
||||
|
||||
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<User> {
|
||||
pub fn get_followers(&self, conn: &Connection) -> Vec<User> {
|
||||
use schema::follows;
|
||||
let follows = Follow::belonging_to(self).select(follows::follower_id);
|
||||
users::table.filter(users::id.eq(any(follows))).load::<User>(conn).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_followers_page(&self, conn: &PgConnection, (min, max): (i32, i32)) -> Vec<User> {
|
||||
pub fn get_followers_page(&self, conn: &Connection, (min, max): (i32, i32)) -> Vec<User> {
|
||||
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::<User>(conn).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_following(&self, conn: &PgConnection) -> Vec<User> {
|
||||
pub fn get_following(&self, conn: &Connection) -> Vec<User> {
|
||||
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::<User>(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<User> {
|
||||
pub fn from_url(conn: &Connection, url: String) -> Option<User> {
|
||||
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,
|
||||
|
|
Loading…
Reference in a new issue