From: Felix Ableitner Date: Thu, 2 Jan 2020 18:22:23 +0000 (+0100) Subject: Merge branch 'master' into federation X-Git-Url: http://these/git/readmes/README.ja.md?a=commitdiff_plain;h=e09a035373db224a17631146af1a7c9a357d2056;p=lemmy.git Merge branch 'master' into federation --- e09a035373db224a17631146af1a7c9a357d2056 diff --cc server/src/apub/puller.rs index efca6c7b,00000000..fe6f492a mode 100644,000000..100644 --- a/server/src/apub/puller.rs +++ b/server/src/apub/puller.rs @@@ -1,97 -1,0 +1,98 @@@ +extern crate reqwest; + +use self::reqwest::Error; +use crate::api::community::{GetCommunityResponse, ListCommunitiesResponse}; +use crate::api::post::GetPosts; +use crate::api::UserOperation; +use crate::db::community_view::CommunityView; +use crate::naive_now; +use crate::settings::Settings; +use activitypub::actor::Group; + +// TODO: right now all of the data is requested on demand, for production we will need to store +// things in the local database to not ruin the performance + +fn fetch_communities_from_instance(domain: &str) -> Result, Error> { + // TODO: check nodeinfo to make sure we are dealing with a lemmy instance + // -> means we need proper nodeinfo json classes instead of inline generation + // TODO: follow pagination (seems like page count is missing?) + // TODO: see if there is any standard for discovering remote actors, so we dont have to rely on lemmy apis + let communities_uri = format!("http://{}/api/v1/communities/list?sort=Hot", domain); + let communities1: ListCommunitiesResponse = reqwest::get(&communities_uri)?.json()?; + let mut communities2 = communities1.communities.to_owned(); + for c in &mut communities2 { + c.name = format_community_name(&c.name, domain); + } + Ok(communities2) +} + +pub fn get_remote_community_posts(name: String) -> Result { + // TODO: this is for urls like /c/!main@example.com, activitypub exposes it through the outbox + // https://www.w3.org/TR/activitypub/#outbox + dbg!(name); + unimplemented!() +} + +pub fn get_remote_community(identifier: String) -> Result { + let x: Vec<&str> = identifier.split("@").collect(); + let name = x[0].replace("!", ""); + let instance = x[1]; + let community_uri = format!("http://{}/federation/c/{}", instance, name); + let community: Group = reqwest::get(&community_uri)?.json()?; + + // TODO: looks like a bunch of data is missing from the activitypub response + // TODO: i dont think simple numeric ids are going to work, we probably need something like uuids + // TODO: why are the Group properties not typed? + Ok(GetCommunityResponse { + op: UserOperation::GetCommunity.to_string(), + moderators: vec![], + admins: vec![], + community: CommunityView { + id: -1, + name: identifier.clone(), + title: identifier, + description: community.object_props.summary.map(|c| c.to_string()), + category_id: -1, + creator_id: -1, + removed: false, - published: naive_now(), // TODO: community.object_props.published ++ published: naive_now(), // TODO: community.object_props.published + updated: Some(naive_now()), // TODO: community.object_props.updated + deleted: false, + nsfw: false, + creator_name: "".to_string(), ++ creator_avatar: None, + category_name: "".to_string(), + number_of_subscribers: -1, + number_of_posts: -1, + number_of_comments: -1, + hot_rank: -1, + user_id: None, + subscribed: None, + }, + }) +} + +pub fn get_following_instances() -> Result, Error> { + let instance_list = match Settings::get().federated_instance.clone() { + Some(f) => vec![f, Settings::get().hostname.clone()], + None => vec![Settings::get().hostname.clone()], + }; + Ok(instance_list) +} + +pub fn get_all_communities() -> Result, Error> { + let mut communities_list: Vec = vec![]; + for instance in &get_following_instances()? { + communities_list.append(fetch_communities_from_instance(instance)?.as_mut()); + } + Ok(communities_list) +} + +/// If community is on local instance, don't include the @instance part +pub fn format_community_name(name: &str, instance: &str) -> String { + if instance == Settings::get().hostname { + format!("!{}", name) + } else { + format!("!{}@{}", name, instance) + } +} diff --cc server/src/main.rs index d7002359,10a7a855..ab079703 --- a/server/src/main.rs +++ b/server/src/main.rs @@@ -296,12 -42,5 +42,6 @@@ fn main() .start(); println!("Started http server at {}:{}", settings.bind, settings.port); + let _ = sys.run(); } - - fn index() -> Result { - Ok(NamedFile::open( - Settings::get().front_end_dir.to_owned() + "/index.html", - )?) - } diff --cc server/src/routes/federation.rs index 00000000,ea6039d6..019a9a71 mode 000000,100644..100644 --- a/server/src/routes/federation.rs +++ b/server/src/routes/federation.rs @@@ -1,0 -1,18 +1,38 @@@ ++use crate::api::community::ListCommunities; ++use crate::api::Perform; ++use crate::api::{Oper, UserOperation}; + use crate::apub; -use actix_web::web; ++use crate::settings::Settings; ++use actix_web::web::Query; ++use actix_web::{web, HttpResponse}; + + pub fn config(cfg: &mut web::ServiceConfig) { - cfg - .route( - "/federation/c/{community_name}", - web::get().to(apub::community::get_apub_community), - ) - .route( - "/federation/c/{community_name}/followers", - web::get().to(apub::community::get_apub_community_followers), - ) - .route( - "/federation/u/{user_name}", - web::get().to(apub::user::get_apub_user), - ); ++ if Settings::get().federation_enabled { ++ println!("federation enabled, host is {}", Settings::get().hostname); ++ cfg ++ .route( ++ "/federation/c/{community_name}", ++ web::get().to(apub::community::get_apub_community), ++ ) ++ .route( ++ "/federation/c/{community_name}/followers", ++ web::get().to(apub::community::get_apub_community_followers), ++ ) ++ .route( ++ "/federation/u/{user_name}", ++ web::get().to(apub::user::get_apub_user), ++ ) ++ // TODO: this is a very quick and dirty implementation for http api calls ++ .route( ++ "/api/v1/communities/list", ++ web::get().to(|query: Query| { ++ let res = Oper::new(UserOperation::ListCommunities, query.into_inner()) ++ .perform() ++ .unwrap(); ++ HttpResponse::Ok() ++ .content_type("application/json") ++ .body(serde_json::to_string(&res).unwrap()) ++ }), ++ ); ++ } + }