Make it possible to display remote blogs
This commit is contained in:
parent
fdc481e384
commit
5e7d513a7e
|
@ -1,3 +1,8 @@
|
|||
use reqwest::Client;
|
||||
use reqwest::header::{Accept, qitem};
|
||||
use reqwest::mime::Mime;
|
||||
use serde_json;
|
||||
use url::Url;
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection};
|
||||
use openssl::hash::MessageDigest;
|
||||
|
@ -60,14 +65,79 @@ impl Blog {
|
|||
.into_iter().nth(0)
|
||||
}
|
||||
|
||||
pub fn find_by_actor_id(conn: &PgConnection, username: String) -> Option<Blog> {
|
||||
blogs::table.filter(blogs::actor_id.eq(username))
|
||||
pub fn find_by_name(conn: &PgConnection, name: String, instance_id: i32) -> Option<Blog> {
|
||||
blogs::table.filter(blogs::actor_id.eq(name))
|
||||
.filter(blogs::instance_id.eq(instance_id))
|
||||
.limit(1)
|
||||
.load::<Blog>(conn)
|
||||
.expect("Error loading blog by actor_id")
|
||||
.expect("Error loading blog by name")
|
||||
.into_iter().nth(0)
|
||||
}
|
||||
|
||||
pub fn find_local(conn: &PgConnection, 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> {
|
||||
if fqn.contains("@") { // remote blog
|
||||
match Instance::find_by_domain(conn, String::from(fqn.split("@").last().unwrap())) {
|
||||
Some(instance) => {
|
||||
match Blog::find_by_name(conn, String::from(fqn.split("@").nth(0).unwrap()), instance.id) {
|
||||
Some(u) => Some(u),
|
||||
None => Blog::fetch_from_webfinger(conn, fqn)
|
||||
}
|
||||
},
|
||||
None => Blog::fetch_from_webfinger(conn, fqn)
|
||||
}
|
||||
} else { // local blog
|
||||
Blog::find_local(conn, fqn)
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_from_webfinger(conn: &PgConnection, acct: String) -> Option<Blog> {
|
||||
match resolve(acct.clone()) {
|
||||
Ok(url) => Blog::fetch_from_url(conn, url),
|
||||
Err(details) => {
|
||||
println!("{}", details);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_from_url(conn: &PgConnection, url: String) -> Option<Blog> {
|
||||
let req = Client::new()
|
||||
.get(&url[..])
|
||||
.header(Accept(vec![qitem("application/activity+json".parse::<Mime>().unwrap())]))
|
||||
.send();
|
||||
match req {
|
||||
Ok(mut res) => {
|
||||
let json: serde_json::Value = serde_json::from_str(&res.text().unwrap()).unwrap();
|
||||
Some(Blog::from_activity(conn, json, Url::parse(url.as_ref()).unwrap().host_str().unwrap().to_string()))
|
||||
},
|
||||
Err(_) => None
|
||||
}
|
||||
}
|
||||
|
||||
fn from_activity(conn: &PgConnection, acct: serde_json::Value, inst: String) -> Blog {
|
||||
let instance = match Instance::find_by_domain(conn, inst.clone()) {
|
||||
Some(instance) => instance,
|
||||
None => {
|
||||
Instance::insert(conn, inst.clone(), inst.clone(), false)
|
||||
}
|
||||
};
|
||||
Blog::insert(conn, NewBlog {
|
||||
actor_id: acct["preferredUsername"].as_str().unwrap().to_string(),
|
||||
title: acct["name"].as_str().unwrap().to_string(),
|
||||
outbox_url: acct["outbox"].as_str().unwrap().to_string(),
|
||||
inbox_url: acct["inbox"].as_str().unwrap().to_string(),
|
||||
summary: acct["summary"].as_str().unwrap().to_string(),
|
||||
instance_id: instance.id,
|
||||
ap_url: acct["id"].as_str().unwrap().to_string(),
|
||||
public_key: acct["publicKey"]["publicKeyPem"].as_str().unwrap_or("").to_string(),
|
||||
private_key: None
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update_boxes(&self, conn: &PgConnection) {
|
||||
if self.outbox_url.len() == 0 {
|
||||
diesel::update(self)
|
||||
|
|
|
@ -16,7 +16,7 @@ use utils;
|
|||
|
||||
#[get("/~/<name>", rank = 2)]
|
||||
fn details(name: String, conn: DbConn, user: Option<User>) -> Template {
|
||||
let blog = Blog::find_by_actor_id(&*conn, name).unwrap();
|
||||
let blog = Blog::find_by_fqn(&*conn, name).unwrap();
|
||||
let recents = Post::get_recents_for_blog(&*conn, &blog, 5);
|
||||
Template::render("blogs/details", json!({
|
||||
"blog": blog,
|
||||
|
@ -34,7 +34,7 @@ fn details(name: String, conn: DbConn, user: Option<User>) -> Template {
|
|||
|
||||
#[get("/~/<name>", format = "application/activity+json", rank = 1)]
|
||||
fn activity_details(name: String, conn: DbConn) -> ActivityPub {
|
||||
let blog = Blog::find_by_actor_id(&*conn, name).unwrap();
|
||||
let blog = Blog::find_local(&*conn, name).unwrap();
|
||||
blog.as_activity_pub(&*conn)
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,6 @@ fn create(conn: DbConn, data: Form<NewBlogForm>, user: User) -> Redirect {
|
|||
|
||||
#[get("/~/<name>/outbox")]
|
||||
fn outbox(name: String, conn: DbConn) -> Outbox {
|
||||
let blog = Blog::find_by_actor_id(&*conn, name).unwrap();
|
||||
let blog = Blog::find_local(&*conn, name).unwrap();
|
||||
blog.outbox(&*conn)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use utils;
|
|||
|
||||
#[get("/~/<blog>/<slug>", rank = 4)]
|
||||
fn details(blog: String, slug: String, conn: DbConn, user: Option<User>) -> Template {
|
||||
let blog = Blog::find_by_actor_id(&*conn, blog).unwrap();
|
||||
let blog = Blog::find_by_fqn(&*conn, blog).unwrap();
|
||||
let post = Post::find_by_slug(&*conn, slug).unwrap();
|
||||
let comments = Comment::find_by_post(&*conn, post.id);
|
||||
Template::render("posts/details", json!({
|
||||
|
@ -68,7 +68,7 @@ struct NewPostForm {
|
|||
|
||||
#[post("/~/<blog_name>/new", data = "<data>")]
|
||||
fn create(blog_name: String, data: Form<NewPostForm>, user: User, conn: DbConn) -> Redirect {
|
||||
let blog = Blog::find_by_actor_id(&*conn, blog_name.to_string()).unwrap();
|
||||
let blog = Blog::find_by_fqn(&*conn, blog_name.to_string()).unwrap();
|
||||
let form = data.get();
|
||||
let slug = form.title.to_string().to_kebab_case();
|
||||
let post = Post::insert(&*conn, NewPost {
|
||||
|
|
|
@ -36,7 +36,7 @@ fn webfinger(query: WebfingerQuery, conn: DbConn) -> Content<Result<String, &'st
|
|||
if res_dom == BASE_URL.as_str() {
|
||||
let res = match User::find_local(&*conn, String::from(user)) {
|
||||
Some(usr) => Ok(usr.webfinger(&*conn)),
|
||||
None => match Blog::find_by_actor_id(&*conn, String::from(user)) {
|
||||
None => match Blog::find_local(&*conn, String::from(user)) {
|
||||
Some(blog) => Ok(blog.webfinger(&*conn)),
|
||||
None => Err("Requested actor not found")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue