From ee7dfee3ef9ec436ba2dcf60ce8b1600ae6cdd05 Mon Sep 17 00:00:00 2001
From: Bat
Date: Thu, 10 May 2018 17:38:03 +0100
Subject: [PATCH] Add an endpoint to like posts
---
src/activity_pub/activity.rs | 40 ++++++++++++++++++++++++++++++++++--
src/main.rs | 4 +++-
src/models/posts.rs | 8 ++++++++
src/routes/likes.rs | 21 +++++++++++++++++++
src/routes/mod.rs | 1 +
src/routes/posts.rs | 3 ++-
templates/posts/details.tera | 6 ++++++
7 files changed, 79 insertions(+), 4 deletions(-)
create mode 100644 src/routes/likes.rs
diff --git a/src/activity_pub/activity.rs b/src/activity_pub/activity.rs
index 7edfa37..b318b5b 100644
--- a/src/activity_pub/activity.rs
+++ b/src/activity_pub/activity.rs
@@ -46,7 +46,7 @@ impl Activity for Accept {
fn serialize(&self) -> serde_json::Value {
json!({
"type": "Accept",
- "id": self.id,
+ "id": self.id,
"actor": self.actor,
"object": self.object,
"published": self.date.to_rfc3339()
@@ -136,7 +136,43 @@ impl Activity for Follow {
fn serialize(&self) -> serde_json::Value {
json!({
"type": "Follow",
- "id": self.id,
+ "id": self.id,
+ "actor": self.actor,
+ "object": self.object
+ })
+ }
+}
+
+#[derive(Clone)]
+pub struct Like {
+ id: String,
+ actor: serde_json::Value,
+ object: serde_json::Value
+}
+
+impl Like {
+ pub fn new(actor: &A, obj: &B, conn: &PgConnection) -> Like {
+ Like {
+ id: format!("{}/like/{}", actor.compute_id(conn), obj.compute_id(conn)),
+ actor: serde_json::Value::String(actor.compute_id(conn)),
+ object: serde_json::Value::String(obj.compute_id(conn))
+ }
+ }
+}
+
+impl Activity for Like {
+ fn get_id(&self) -> String {
+ self.id.clone()
+ }
+
+ fn get_type(&self) -> String {
+ "Follow".to_string()
+ }
+
+ fn serialize(&self) -> serde_json::Value {
+ json!({
+ "type": "Follow",
+ "id": self.id,
"actor": self.actor,
"object": self.object
})
diff --git a/src/main.rs b/src/main.rs
index 610f633..7854469 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -92,7 +92,9 @@ fn main() {
routes::posts::create,
routes::comments::new,
- routes::comments::create
+ routes::comments::create,
+
+ routes::likes::create
])
.manage(init_pool())
.attach(Template::fairing())
diff --git a/src/models/posts.rs b/src/models/posts.rs
index 992f663..36cc54e 100644
--- a/src/models/posts.rs
+++ b/src/models/posts.rs
@@ -8,6 +8,7 @@ use activity_pub::{PUBLIC_VISIBILTY, ap_url};
use activity_pub::actor::Actor;
use activity_pub::object::Object;
use models::blogs::Blog;
+use models::likes::Like;
use models::users::User;
use models::post_authors::PostAuthor;
use schema::posts;
@@ -85,6 +86,13 @@ impl Post {
.into_iter().nth(0).unwrap()
}
+ pub fn get_likes(&self, conn: &PgConnection) -> 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 update_ap_url(&self, conn: &PgConnection) {
if self.ap_url.len() == 0 {
diesel::update(self)
diff --git a/src/routes/likes.rs b/src/routes/likes.rs
new file mode 100644
index 0000000..ff558cf
--- /dev/null
+++ b/src/routes/likes.rs
@@ -0,0 +1,21 @@
+use rocket::response::Redirect;
+
+use activity_pub::activity::Like;
+use activity_pub::outbox::broadcast;
+use db_conn::DbConn;
+use models::likes;
+use models::posts::Post;
+use models::users::User;
+
+#[get("/~///like")]
+fn create(blog: String, slug: String, user: User, conn: DbConn) -> Redirect {
+ let post = Post::find_by_slug(&*conn, slug.clone()).unwrap();
+ likes::Like::insert(&*conn, likes::NewLike {
+ post_id: post.id,
+ user_id: user.id
+ });
+ let act = Like::new(&user, &post, &*conn);
+ broadcast(&*conn, &user, act, user.get_followers(&*conn));
+
+ Redirect::to(format!("/~/{}/{}/", blog, slug).as_ref())
+}
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index 7a225a9..4b4a40a 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -1,6 +1,7 @@
pub mod blogs;
pub mod comments;
pub mod instance;
+pub mod likes;
pub mod posts;
pub mod session;
pub mod user;
diff --git a/src/routes/posts.rs b/src/routes/posts.rs
index dd9f2b7..e88cc3e 100644
--- a/src/routes/posts.rs
+++ b/src/routes/posts.rs
@@ -31,7 +31,8 @@ fn details(blog: String, slug: String, conn: DbConn) -> Template {
"content": c.content,
"author": c.get_author(&*conn)
})
- }).collect::>()
+ }).collect::>(),
+ "n_likes": post.get_likes(&*conn).len()
}))
}
diff --git a/templates/posts/details.tera b/templates/posts/details.tera
index 0c62d14..959c04c 100644
--- a/templates/posts/details.tera
+++ b/templates/posts/details.tera
@@ -13,6 +13,12 @@
License: {{ post.license }}
+
+
+ {{ n_likes }} like{{ n_likes | pluralize }}
+
+ Add yours
+
Comments
{% for comment in comments %}