2022-06-13 07:24:55 +00:00
|
|
|
use async_std::channel::Sender;
|
|
|
|
use log::{debug, warn};
|
2022-07-07 08:02:13 +00:00
|
|
|
use markdown;
|
2022-06-13 07:24:55 +00:00
|
|
|
use rocket::{form::Form, get, post, response::Redirect, uri, FromForm, State};
|
|
|
|
use rocket_dyn_templates::{tera::Context, Template};
|
2022-07-07 08:02:13 +00:00
|
|
|
use uri_encode;
|
2022-06-13 07:24:55 +00:00
|
|
|
|
|
|
|
use crate::{db::Database, sbot, task_loop::Task, utils, WhoAmI};
|
|
|
|
|
|
|
|
#[derive(FromForm)]
|
|
|
|
pub struct Peer {
|
|
|
|
pub public_key: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/")]
|
|
|
|
pub async fn home(db: &State<Database>) -> Template {
|
|
|
|
let peers = db.get_peers();
|
|
|
|
|
|
|
|
let mut context = Context::new();
|
|
|
|
context.insert("peers", &peers);
|
|
|
|
|
2022-07-07 08:02:13 +00:00
|
|
|
Template::render("base", &context.into_json())
|
2022-06-13 07:24:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/posts/<public_key>")]
|
|
|
|
pub async fn posts(db: &State<Database>, public_key: &str) -> Template {
|
|
|
|
let peers = db.get_peers();
|
|
|
|
let posts = db.get_posts(public_key).unwrap();
|
|
|
|
|
|
|
|
let mut context = Context::new();
|
|
|
|
context.insert("selected_peer", &public_key);
|
|
|
|
context.insert("peers", &peers);
|
|
|
|
context.insert("posts", &posts);
|
|
|
|
|
2022-07-07 08:02:13 +00:00
|
|
|
Template::render("base", &context.into_json())
|
2022-06-13 07:24:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/posts/<public_key>/<msg_id>")]
|
|
|
|
pub async fn post(db: &State<Database>, public_key: &str, msg_id: &str) -> Template {
|
|
|
|
let peers = db.get_peers();
|
|
|
|
let posts = db.get_posts(public_key).unwrap();
|
|
|
|
let post = db.get_post(public_key, msg_id).unwrap();
|
|
|
|
|
|
|
|
let mut context = Context::new();
|
|
|
|
context.insert("selected_peer", &public_key);
|
2022-07-07 08:02:13 +00:00
|
|
|
context.insert(
|
|
|
|
"selected_peer_encoded",
|
|
|
|
&uri_encode::encode_uri_component(public_key),
|
|
|
|
);
|
2022-06-13 07:24:55 +00:00
|
|
|
context.insert("selected_post", &msg_id);
|
2022-07-07 08:02:13 +00:00
|
|
|
context.insert(
|
|
|
|
"selected_post_encoded",
|
|
|
|
&uri_encode::encode_uri_component(msg_id),
|
|
|
|
);
|
2022-06-13 07:24:55 +00:00
|
|
|
context.insert("peers", &peers);
|
|
|
|
context.insert("posts", &posts);
|
2022-07-07 08:02:13 +00:00
|
|
|
// TODO: consider converting markdown to html here
|
2022-06-13 07:24:55 +00:00
|
|
|
context.insert("post", &post);
|
2022-07-07 08:02:13 +00:00
|
|
|
context.insert("post_is_selected", &true);
|
2022-06-13 07:24:55 +00:00
|
|
|
|
2022-07-07 08:02:13 +00:00
|
|
|
Template::render("base", &context.into_json())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/posts/<public_key>/<msg_id>/read")]
|
|
|
|
pub async fn mark_post_read(db: &State<Database>, public_key: &str, msg_id: &str) -> Redirect {
|
|
|
|
// Retrieve the post from the database, mark it as read and reinsert it.
|
|
|
|
if let Ok(Some(mut post)) = db.get_post(public_key, msg_id) {
|
|
|
|
post.read = true;
|
|
|
|
db.add_post(public_key, post).unwrap();
|
|
|
|
} else {
|
|
|
|
warn!(
|
|
|
|
"failed to find post {} authored by {} in database",
|
|
|
|
msg_id, public_key
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
Redirect::to(uri!(post(public_key, msg_id)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/posts/<public_key>/<msg_id>/unread")]
|
|
|
|
pub async fn mark_post_unread(db: &State<Database>, public_key: &str, msg_id: &str) -> Redirect {
|
|
|
|
// Retrieve the post from the database, mark it as unread and reinsert it.
|
|
|
|
if let Ok(Some(mut post)) = db.get_post(public_key, msg_id) {
|
|
|
|
post.read = false;
|
|
|
|
db.add_post(public_key, post).unwrap();
|
|
|
|
} else {
|
|
|
|
warn!(
|
|
|
|
"failed to find post {} authored by {} in database",
|
|
|
|
msg_id, public_key
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
Redirect::to(uri!(post(public_key, msg_id)))
|
2022-06-13 07:24:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[post("/subscribe", data = "<peer>")]
|
|
|
|
pub async fn subscribe_form(
|
|
|
|
db: &State<Database>,
|
|
|
|
whoami: &State<WhoAmI>,
|
|
|
|
tx: &State<Sender<Task>>,
|
|
|
|
peer: Form<Peer>,
|
|
|
|
) -> Redirect {
|
|
|
|
if utils::validate_public_key(&peer.public_key).is_ok() {
|
|
|
|
debug!("public key {} is valid", &peer.public_key);
|
|
|
|
// TODO: consider getting the peer name here so we can insert it
|
|
|
|
match db.add_peer(&peer.public_key) {
|
|
|
|
Ok(_) => {
|
|
|
|
debug!("added {} to peer tree in database", &peer.public_key);
|
|
|
|
// TODO: i don't think we actually want to follow...
|
|
|
|
// we might still have the data in our ssb db, even if we don't follow
|
|
|
|
match sbot::is_following(&whoami.public_key, &peer.public_key).await {
|
|
|
|
Ok(status) if status.as_str() == "false" => {
|
|
|
|
match sbot::follow_peer(&peer.public_key).await {
|
|
|
|
Ok(_) => debug!("followed {}", &peer.public_key),
|
|
|
|
Err(e) => warn!("failed to follow {}: {}", &peer.public_key, e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(status) if status.as_str() == "true" => {
|
|
|
|
debug!("we already follow {}", &peer.public_key)
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
let peer = peer.public_key.to_string();
|
2022-07-07 08:02:13 +00:00
|
|
|
// Fetch all root posts authored by the peer we're subscribing
|
|
|
|
// to. Posts will be added to the key-value database.
|
2022-06-13 07:24:55 +00:00
|
|
|
if let Err(e) = tx.send(Task::FetchAll(peer)).await {
|
|
|
|
warn!("task loop error: {}", e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(_e) => warn!(
|
|
|
|
"failed to add {} to peer tree in database",
|
|
|
|
&peer.public_key
|
|
|
|
),
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
warn!("{} is invalid", &peer.public_key);
|
|
|
|
}
|
|
|
|
|
|
|
|
Redirect::to(uri!(home))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[post("/unsubscribe", data = "<peer>")]
|
|
|
|
pub fn unsubscribe_form(db: &State<Database>, peer: Form<Peer>) -> Redirect {
|
|
|
|
// validate the public key
|
|
|
|
match utils::validate_public_key(&peer.public_key) {
|
|
|
|
Ok(_) => {
|
|
|
|
debug!("public key {} is valid", &peer.public_key);
|
|
|
|
match db.remove_peer(&peer.public_key) {
|
|
|
|
Ok(_) => debug!("removed {} from peer tree in database", &peer.public_key),
|
|
|
|
Err(_e) => warn!(
|
|
|
|
"failed to remove {} from peer tree in database",
|
|
|
|
&peer.public_key
|
|
|
|
),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(e) => warn!("{} is invalid: {}", &peer.public_key, e),
|
|
|
|
}
|
|
|
|
|
|
|
|
Redirect::to(uri!(home))
|
|
|
|
}
|