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 chrono::NaiveDateTime;
|
||||||
use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection};
|
use diesel::{self, QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection};
|
||||||
use openssl::hash::MessageDigest;
|
use openssl::hash::MessageDigest;
|
||||||
@ -60,14 +65,79 @@ impl Blog {
|
|||||||
.into_iter().nth(0)
|
.into_iter().nth(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_by_actor_id(conn: &PgConnection, username: String) -> Option<Blog> {
|
pub fn find_by_name(conn: &PgConnection, name: String, instance_id: i32) -> Option<Blog> {
|
||||||
blogs::table.filter(blogs::actor_id.eq(username))
|
blogs::table.filter(blogs::actor_id.eq(name))
|
||||||
|
.filter(blogs::instance_id.eq(instance_id))
|
||||||
.limit(1)
|
.limit(1)
|
||||||
.load::<Blog>(conn)
|
.load::<Blog>(conn)
|
||||||
.expect("Error loading blog by actor_id")
|
.expect("Error loading blog by name")
|
||||||
.into_iter().nth(0)
|
.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) {
|
pub fn update_boxes(&self, conn: &PgConnection) {
|
||||||
if self.outbox_url.len() == 0 {
|
if self.outbox_url.len() == 0 {
|
||||||
diesel::update(self)
|
diesel::update(self)
|
||||||
|
@ -16,7 +16,7 @@ use utils;
|
|||||||
|
|
||||||
#[get("/~/<name>", rank = 2)]
|
#[get("/~/<name>", rank = 2)]
|
||||||
fn details(name: String, conn: DbConn, user: Option<User>) -> Template {
|
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);
|
let recents = Post::get_recents_for_blog(&*conn, &blog, 5);
|
||||||
Template::render("blogs/details", json!({
|
Template::render("blogs/details", json!({
|
||||||
"blog": blog,
|
"blog": blog,
|
||||||
@ -34,7 +34,7 @@ fn details(name: String, conn: DbConn, user: Option<User>) -> Template {
|
|||||||
|
|
||||||
#[get("/~/<name>", format = "application/activity+json", rank = 1)]
|
#[get("/~/<name>", format = "application/activity+json", rank = 1)]
|
||||||
fn activity_details(name: String, conn: DbConn) -> ActivityPub {
|
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)
|
blog.as_activity_pub(&*conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +74,6 @@ fn create(conn: DbConn, data: Form<NewBlogForm>, user: User) -> Redirect {
|
|||||||
|
|
||||||
#[get("/~/<name>/outbox")]
|
#[get("/~/<name>/outbox")]
|
||||||
fn outbox(name: String, conn: DbConn) -> 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)
|
blog.outbox(&*conn)
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ use utils;
|
|||||||
|
|
||||||
#[get("/~/<blog>/<slug>", rank = 4)]
|
#[get("/~/<blog>/<slug>", rank = 4)]
|
||||||
fn details(blog: String, slug: String, conn: DbConn, user: Option<User>) -> Template {
|
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 post = Post::find_by_slug(&*conn, slug).unwrap();
|
||||||
let comments = Comment::find_by_post(&*conn, post.id);
|
let comments = Comment::find_by_post(&*conn, post.id);
|
||||||
Template::render("posts/details", json!({
|
Template::render("posts/details", json!({
|
||||||
@ -68,7 +68,7 @@ struct NewPostForm {
|
|||||||
|
|
||||||
#[post("/~/<blog_name>/new", data = "<data>")]
|
#[post("/~/<blog_name>/new", data = "<data>")]
|
||||||
fn create(blog_name: String, data: Form<NewPostForm>, user: User, conn: DbConn) -> Redirect {
|
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 form = data.get();
|
||||||
let slug = form.title.to_string().to_kebab_case();
|
let slug = form.title.to_string().to_kebab_case();
|
||||||
let post = Post::insert(&*conn, NewPost {
|
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() {
|
if res_dom == BASE_URL.as_str() {
|
||||||
let res = match User::find_local(&*conn, String::from(user)) {
|
let res = match User::find_local(&*conn, String::from(user)) {
|
||||||
Some(usr) => Ok(usr.webfinger(&*conn)),
|
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)),
|
Some(blog) => Ok(blog.webfinger(&*conn)),
|
||||||
None => Err("Requested actor not found")
|
None => Err("Requested actor not found")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user