use activitypub::{ activity::Follow, collection::OrderedCollection }; use rocket::{request::Form, response::{Redirect, Flash} }; use rocket_contrib::Template; use serde_json; use activity_pub::{ activity_pub, ActivityPub, ActivityStream, context, broadcast, Id, IntoId, inbox::{Inbox, Notify}, actor::Actor }; use db_conn::DbConn; use models::{ blogs::Blog, follows, instance::Instance, posts::Post, reshares::Reshare, users::* }; use utils; #[get("/me")] fn me(user: Option) -> Result> { match user { Some(user) => Ok(Redirect::to(uri!(details: name = user.username))), None => Err(utils::requires_login("", uri!(me))) } } #[get("/@/", rank = 2)] fn details(name: String, conn: DbConn, account: Option) -> Template { may_fail!(User::find_by_fqn(&*conn, name), "Couldn't find requested user", |user| { let recents = Post::get_recents_for_author(&*conn, &user, 6); let reshares = Reshare::get_recents_for_author(&*conn, &user, 6); let user_id = user.id.clone(); let n_followers = user.get_followers(&*conn).len(); Template::render("users/details", json!({ "user": serde_json::to_value(user.clone()).unwrap(), "instance_url": user.get_instance(&*conn).public_domain, "is_remote": user.instance_id != Instance::local_id(&*conn), "follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false), "account": account, "recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::>(), "reshares": reshares.into_iter().map(|r| r.get_post(&*conn).unwrap().to_json(&*conn)).collect::>(), "is_self": account.map(|a| a.id == user_id).unwrap_or(false), "n_followers": n_followers })) }) } #[get("/dashboard")] fn dashboard(user: User, conn: DbConn) -> Template { let blogs = Blog::find_for_author(&*conn, user.id); Template::render("users/dashboard", json!({ "account": user, "blogs": blogs })) } #[get("/dashboard", rank = 2)] fn dashboard_auth() -> Flash { utils::requires_login("You need to be logged in order to access your dashboard", uri!(dashboard)) } #[get("/@//follow")] fn follow(name: String, conn: DbConn, user: User) -> Redirect { let target = User::find_by_fqn(&*conn, name.clone()).unwrap(); let f = follows::Follow::insert(&*conn, follows::NewFollow { follower_id: user.id, following_id: target.id }); f.notify(&*conn); let mut act = Follow::default(); act.follow_props.set_actor_link::(user.clone().into_id()).unwrap(); act.follow_props.set_object_object(user.into_activity(&*conn)).unwrap(); act.object_props.set_id_string(format!("{}/follow/{}", user.ap_url, target.ap_url)).unwrap(); broadcast(&*conn, &user, act, vec![target]); Redirect::to(uri!(details: name = name)) } #[get("/@//follow", rank = 2)] fn follow_auth(name: String) -> Flash { utils::requires_login("You need to be logged in order to follow someone", uri!(follow: name = name)) } #[get("/@//followers", rank = 2)] fn followers(name: String, conn: DbConn, account: Option) -> Template { may_fail!(User::find_by_fqn(&*conn, name.clone()), "Couldn't find requested user", |user| { let user_id = user.id.clone(); Template::render("users/followers", json!({ "user": serde_json::to_value(user.clone()).unwrap(), "instance_url": user.get_instance(&*conn).public_domain, "is_remote": user.instance_id != Instance::local_id(&*conn), "follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false), "followers": user.get_followers(&*conn).into_iter().map(|f| f.to_json(&*conn)).collect::>(), "account": account, "is_self": account.map(|a| a.id == user_id).unwrap_or(false), "n_followers": user.get_followers(&*conn).len() })) }) } #[get("/@/", format = "application/activity+json", rank = 1)] fn activity_details(name: String, conn: DbConn) -> ActivityPub { let user = User::find_local(&*conn, name).unwrap(); user.as_activity_pub(&*conn) } #[get("/users/new")] fn new(user: Option) -> Template { Template::render("users/new", json!({ "account": user })) } #[get("/@//edit")] fn edit(name: String, user: User) -> Option