Consider the following

If you're going to throw out records where certain fields are missing
anyway, you might as well define your own types that are easier to work
with. You don't need the full expressiveness of the activitystreams
built-in types if you're just calling unwrap everywhere.
This commit is contained in:
asonix 2020-03-19 15:37:00 -05:00
parent 5976006859
commit 1043a6b7c2

View file

@ -8,11 +8,10 @@ use crate::db::post_view::PostView;
use crate::naive_now;
use crate::routes::nodeinfo::{NodeInfo, NodeInfoWellKnown};
use crate::settings::Settings;
use activitystreams::actor::{properties::ApActorProperties, Group};
use activitystreams::collection::{OrderedCollection, UnorderedCollection};
use activitystreams::ext::Ext;
use activitystreams::object::ObjectBox;
use activitystreams::object::Page;
use activitystreams::actor::kind::GroupType;
use activitystreams::collection::kind::{CollectionType, OrderedCollectionType};
use activitystreams::object::kind::PageType;
use activitystreams::primitives::XsdDateTime;
use failure::Error;
use log::warn;
use serde::Deserialize;
@ -70,82 +69,109 @@ where
Ok(x)
}
pub fn get_remote_community_posts(identifier: &str) -> Result<GetPostsResponse, Error> {
let community =
fetch_remote_object::<Ext<Group, ApActorProperties>>(&get_remote_community_uri(identifier))?;
let outbox_uri = &community.extension.get_outbox().to_string();
let outbox = fetch_remote_object::<OrderedCollection>(outbox_uri)?;
let items = outbox.collection_props.get_many_items_object_boxs();
#[derive(serde::Deserialize)]
struct ValidCommunity {
#[allow(dead_code)]
#[serde(rename = "type")]
kind: GroupType,
let posts: Vec<PostView> = items
.unwrap()
.map(|obox: &ObjectBox| {
let page: Page = obox.clone().to_concrete::<Page>().unwrap();
PostView {
id: -1,
name: page.object_props.get_name_xsd_string().unwrap().to_string(),
url: page
.object_props
.get_url_xsd_any_uri()
.map(|u| u.to_string()),
body: page
.object_props
.get_content_xsd_string()
.map(|c| c.to_string()),
creator_id: -1,
community_id: -1,
removed: false,
locked: false,
published: page
.object_props
.get_published()
.unwrap()
.as_ref()
.naive_local()
.to_owned(),
updated: page
.object_props
.get_updated()
.map(|u| u.as_ref().to_owned().naive_local()),
deleted: false,
nsfw: false,
stickied: false,
embed_title: None,
embed_description: None,
embed_html: None,
thumbnail_url: None,
banned: false,
banned_from_community: false,
creator_name: "".to_string(),
creator_avatar: None,
community_name: "".to_string(),
community_removed: false,
community_deleted: false,
community_nsfw: false,
number_of_comments: -1,
score: -1,
upvotes: -1,
downvotes: -1,
hot_rank: -1,
newest_activity_time: naive_now(),
user_id: None,
my_vote: None,
subscribed: None,
read: None,
saved: None,
}
followers: String,
outbox: String,
name: String,
summary: Option<String>,
published: XsdDateTime,
updated: Option<XsdDateTime>,
}
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct ValidOutbox {
#[allow(dead_code)]
#[serde(rename = "type")]
kind: OrderedCollectionType,
items: Vec<ValidPage>,
total_items: i64,
}
#[derive(serde::Deserialize)]
struct ValidPage {
#[allow(dead_code)]
#[serde(rename = "type")]
kind: PageType,
name: String,
url: Option<String>,
content: Option<String>,
published: XsdDateTime,
updated: Option<XsdDateTime>,
}
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct ValidFollowers {
#[allow(dead_code)]
#[serde(rename = "type")]
kind: CollectionType,
total_items: i64,
}
pub fn get_remote_community_posts(identifier: &str) -> Result<GetPostsResponse, Error> {
let community = fetch_remote_object::<ValidCommunity>(&get_remote_community_uri(identifier))?;
let outbox_uri = &community.outbox;
let outbox = fetch_remote_object::<ValidOutbox>(outbox_uri)?;
let posts: Vec<PostView> = outbox
.items
.into_iter()
.map(|page| PostView {
id: -1,
name: page.name,
url: page.url,
body: page.content,
creator_id: -1,
community_id: -1,
removed: false,
locked: false,
published: page.published.as_datetime().naive_local(),
updated: page.updated.map(|u| u.as_ref().naive_local()),
deleted: false,
nsfw: false,
stickied: false,
embed_title: None,
embed_description: None,
embed_html: None,
thumbnail_url: None,
banned: false,
banned_from_community: false,
creator_name: "".to_string(),
creator_avatar: None,
community_name: "".to_string(),
community_removed: false,
community_deleted: false,
community_nsfw: false,
number_of_comments: -1,
score: -1,
upvotes: -1,
downvotes: -1,
hot_rank: -1,
newest_activity_time: naive_now(),
user_id: None,
my_vote: None,
subscribed: None,
read: None,
saved: None,
})
.collect();
Ok(GetPostsResponse { posts })
}
pub fn get_remote_community(identifier: &str) -> Result<GetCommunityResponse, failure::Error> {
let community =
fetch_remote_object::<Ext<Group, ApActorProperties>>(&get_remote_community_uri(identifier))?;
let followers_uri = &community.extension.get_followers().unwrap().to_string();
let outbox_uri = &community.extension.get_outbox().to_string();
let outbox = fetch_remote_object::<OrderedCollection>(outbox_uri)?;
let followers = fetch_remote_object::<UnorderedCollection>(followers_uri)?;
let community = fetch_remote_object::<ValidCommunity>(&get_remote_community_uri(identifier))?;
let outbox = fetch_remote_object::<ValidOutbox>(&community.outbox)?;
let followers = fetch_remote_object::<ValidFollowers>(&community.followers)?;
// TODO: this is only for testing until we can call that function from GetPosts
// (once string ids are supported)
//dbg!(get_remote_community_posts(identifier)?);
@ -157,40 +183,20 @@ pub fn get_remote_community(identifier: &str) -> Result<GetCommunityResponse, fa
// TODO: we need to merge id and name into a single thing (stuff like @user@instance.com)
id: 1337, //community.object_props.get_id()
name: identifier.to_string(),
title: community
.as_ref()
.get_name_xsd_string()
.unwrap()
.to_string(),
description: community
.as_ref()
.get_summary_xsd_string()
.map(|s| s.to_string()),
title: community.name,
description: community.summary,
category_id: -1,
creator_id: -1, //community.object_props.get_attributed_to_xsd_any_uri()
removed: false,
published: community
.as_ref()
.get_published()
.unwrap()
.as_ref()
.naive_local()
.to_owned(),
updated: community
.as_ref()
.get_updated()
.map(|u| u.as_ref().to_owned().naive_local()),
published: community.published.as_datetime().naive_local(),
updated: community.updated.map(|u| u.as_datetime().naive_local()),
deleted: false,
nsfw: false,
creator_name: "".to_string(),
creator_avatar: None,
category_name: "".to_string(),
number_of_subscribers: *followers
.collection_props
.get_total_items()
.unwrap()
.as_ref() as i64, // TODO: need to use the same type
number_of_posts: *outbox.collection_props.get_total_items().unwrap().as_ref() as i64,
number_of_subscribers: followers.total_items,
number_of_posts: outbox.total_items,
number_of_comments: -1,
hot_rank: -1,
user_id: None,