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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user