feat: initial port to WD4

This commit is contained in:
aprilthepink 2024-11-19 22:15:19 +01:00
parent 084e85e111
commit c72763c4b1
6 changed files with 96 additions and 126 deletions

View file

@ -6,6 +6,7 @@ use chrono::{DateTime, TimeZone, Utc};
use reqwest::header::{self, CONTENT_TYPE};
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};
use serde::{Deserialize, Serialize};
use serde_json::to_string;
use time::OffsetDateTime;
use url::Url;
@ -22,7 +23,7 @@ use crate::{
};
use super::{
objects::{CategoryType, ContentEntry, ContentFormat, Note, PublicKey},
objects::{CategoryType, ContentEntry, ContentFormat, Note, PublicKey, UserCollections},
superx::request_client,
};
@ -43,12 +44,12 @@ pub async fn versia_post_from_db(
.one(DB.get().unwrap())
.await?;
let author = Url::parse(&creator.unwrap().url)?;
let visibility = match post.visibility.as_str() {
"public" => super::objects::VisibilityType::Public,
"followers" => super::objects::VisibilityType::Followers,
"direct" => super::objects::VisibilityType::Direct,
"unlisted" => super::objects::VisibilityType::Unlisted,
_ => super::objects::VisibilityType::Public,
let group = match post.visibility.as_str() {
"public" => Some("public".to_string()),
"followers" => Some("followers".to_string()),
"direct" => None,
//"unlisted" => super::objects::VisibilityType::Unlisted,
_ => Some("public".to_string()),
};
//let mut mentions = Vec::new();
//for obj in post.tag.clone() {
@ -60,7 +61,7 @@ pub async fn versia_post_from_db(
ContentEntry::from_string(post.content),
);
let note = super::objects::Note {
rtype: super::objects::VersiaType::Note,
rtype: "Note".to_string(),
id: uuid::Uuid::parse_str(&post.id)?,
author: author.clone(),
uri: url.clone(),
@ -69,11 +70,10 @@ pub async fn versia_post_from_db(
mentions: None,
category: Some(CategoryType::Microblog),
device: None,
visibility: Some(visibility),
previews: None,
replies_to: None,
quotes: None,
group: None,
group,
attachments: None,
subject: post.title,
is_sensitive: Some(post.sensitive),
@ -190,11 +190,9 @@ pub async fn versia_user_from_db(
content_type_header.unwrap().to_str().unwrap().to_string()
});
content_format.x.insert(media_type, content_entry);
let mut name = tag.name.chars();
name.next();
name.next_back();
let name = tag.name;
emojis.push(super::objects::CustomEmoji {
name: name.as_str().to_string(),
name,
url: content_format,
});
}
@ -205,20 +203,23 @@ pub async fn versia_user_from_db(
let extensions = super::objects::ExtensionSpecs {
custom_emojis: emojis,
};
let collections = UserCollections {
outbox: outbox_url,
followers: followers_url,
following: following_url,
featured: featured_url,
};
let user = super::objects::User {
rtype: super::objects::VersiaType::User,
rtype: "User".to_string(),
id: uuid::Uuid::parse_str(&user.id)?,
uri: url.clone(),
username: user.username,
display_name,
inbox: inbox_url,
outbox: outbox_url,
followers: followers_url,
following: following_url,
featured: featured_url,
likes: likes_url,
dislikes: dislikes_url,
bio: Some(bio),
collections,
avatar,
header,
fields: Some(fields),
@ -226,10 +227,12 @@ pub async fn versia_user_from_db(
created_at: OffsetDateTime::from_unix_timestamp(user.created_at.timestamp()).unwrap(),
public_key: PublicKey {
actor: url.clone(),
public_key: "AAAAC3NzaC1lZDI1NTE5AAAAIMxsX+lEWkHZt9NOvn9yYFP0Z++186LY4b97C4mwj/f2"
key: "AAAAC3NzaC1lZDI1NTE5AAAAIMxsX+lEWkHZt9NOvn9yYFP0Z++186LY4b97C4mwj/f2"
.to_string(), // dummy key
algorithm: "ed25519".to_string(),
},
extensions: Some(extensions),
manually_approves_followers: false,
};
Ok(user)
}
@ -418,8 +421,8 @@ pub async fn db_user_from_url(url: Url) -> anyhow::Result<entities::user::Model>
),
summary: Set(option_content_format_text(ls_user.bio).await),
updated_at: Set(Some(Utc::now())),
followers: Set(Some(ls_user.followers.to_string())),
following: Set(Some(ls_user.following.to_string())),
followers: Set(Some(ls_user.collections.followers.to_string())),
following: Set(Some(ls_user.collections.following.to_string())),
ap_json: Set(Some(serde_json::to_string(&ap_json).unwrap())),
..Default::default()
};
@ -464,33 +467,33 @@ pub async fn receive_versia_note(
mentions.push(obj.href.clone());
}
let to = match note
.visibility
.group
.clone()
.unwrap_or(super::objects::VisibilityType::Public)
.unwrap_or("nothing".to_string()).as_str()
{
super::objects::VisibilityType::Public => {
let mut vec = vec![public(), Url::parse(&user.followers.to_string().as_str())?];
"public" => {
let mut vec = vec![public(), Url::parse(&user.collections.followers.to_string().as_str())?];
vec.append(&mut mentions.clone());
vec
}
super::objects::VisibilityType::Followers => {
let mut vec = vec![Url::parse(&user.followers.to_string().as_str())?];
"unlisted" => {
let mut vec = vec![Url::parse(&user.collections.followers.to_string().as_str())?];
vec.append(&mut mentions.clone());
vec
}
super::objects::VisibilityType::Direct => mentions.clone(),
super::objects::VisibilityType::Unlisted => {
let mut vec = vec![Url::parse(&user.followers.to_string().as_str())?];
"followers" => {
let mut vec = vec![Url::parse(&user.collections.followers.to_string().as_str())?];
vec.append(&mut mentions.clone());
vec
}
_ => mentions.clone(),
};
let cc = match note
.visibility
.group
.clone()
.unwrap_or(super::objects::VisibilityType::Public)
.unwrap_or("nothing".to_string()).as_str()
{
super::objects::VisibilityType::Unlisted => Some(vec![public()]),
"unlisted" => Some(vec![public()]),
_ => None,
};
let reply: Option<ObjectId<entities::post::Model>> =
@ -542,14 +545,14 @@ pub async fn receive_versia_note(
};
let visibility = match note
.visibility
.group
.clone()
.unwrap_or(super::objects::VisibilityType::Public)
.unwrap_or("nothing".to_string()).as_str()
{
super::objects::VisibilityType::Public => "public",
super::objects::VisibilityType::Followers => "followers",
super::objects::VisibilityType::Direct => "direct",
super::objects::VisibilityType::Unlisted => "unlisted",
"public" => "public",
"followers" => "followers",
"unlisted" => "unlisted",
_ => "direct",
};
if let Some(obj) = note.replies_to {
println!("Quoting: {}", db_post_from_url(obj).await?.url);

View file

@ -37,7 +37,7 @@ pub async fn send_follow_accept_to_versia(model: follow_relation::Model) -> anyh
let versia_followee = versia_user_from_db(followee_model).await?;
let entity = FollowResult {
rtype: super::objects::VersiaType::FollowAccept,
rtype: "FollowAccept".to_string(),
id,
uri,
created_at: OffsetDateTime::now_utc(),

View file

@ -21,7 +21,6 @@ use url::Url;
use super::{
conversion::versia_user_from_db,
http::{versia_url_to_user, versia_url_to_user_and_model},
objects::VersiaType,
};
pub async fn inbox_entry(json: &str) -> Result<()> {
@ -35,9 +34,6 @@ pub async fn inbox_entry(json: &str) -> Result<()> {
Some("Note") => {
let note: super::objects::Note = serde_json::from_str(json)?;
}
Some("Patch") => {
let patch: super::objects::Patch = serde_json::from_str(json)?;
}
Some("Follow") => {
let follow_req: super::objects::Follow = serde_json::from_str(json)?;
follow_request(follow_req).await?;
@ -48,6 +44,9 @@ pub async fn inbox_entry(json: &str) -> Result<()> {
Some("FollowReject") => {
let follow_rej: super::objects::FollowResult = serde_json::from_str(json)?;
}
Some("Unfollow") => {
let unfollow: super::objects::Unfollow = serde_json::from_str(json)?;
}
// Add more cases for other types as needed
_ => {
return Err(anyhow::anyhow!(

View file

@ -35,21 +35,6 @@ fn sort_alphabetically<T: Serialize, S: serde::Serializer>(
#[derive(Serialize)]
pub struct SortAlphabetically<T: Serialize>(#[serde(serialize_with = "sort_alphabetically")] pub T);
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum VersiaType {
User,
Note,
Patch,
Like,
Dislike,
Follow,
FollowAccept,
FollowReject,
Undo,
Extension,
ServerMetadata,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum CategoryType {
Microblog,
@ -61,19 +46,10 @@ pub enum CategoryType {
Messaging,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "snake_case")]
pub enum VisibilityType {
Public,
Unlisted,
Followers,
Direct,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum VersiaExtensions {
#[serde(rename = "pub.versia:microblogging/Announce")]
Announce,
#[serde(rename = "pub.versia:share/Share")]
Share,
#[serde(rename = "pub.versia:custom_emojis")]
CustomEmojis,
#[serde(rename = "pub.versia:reactions/Reaction")]
@ -96,8 +72,9 @@ pub enum VersiaExtensions {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct PublicKey {
pub public_key: String,
pub key: String,
pub actor: Url,
pub algorithm: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
@ -217,6 +194,7 @@ pub struct FieldKV {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ContentEntry {
content: String,
remote: bool,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
@ -238,6 +216,7 @@ impl ContentEntry {
pub fn from_string(string: String) -> ContentEntry {
ContentEntry {
content: string,
remote: false,
description: None,
size: None,
hash: None,
@ -254,18 +233,15 @@ impl ContentEntry {
pub struct User {
pub public_key: PublicKey,
#[serde(rename = "type")]
pub rtype: VersiaType,
pub rtype: String,
pub id: Uuid,
pub uri: Url,
#[serde(with = "iso_versia")]
pub created_at: OffsetDateTime,
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
pub collections: UserCollections,
pub inbox: Url,
pub outbox: Url,
pub featured: Url,
pub followers: Url,
pub following: Url,
pub likes: Url,
pub dislikes: Url,
pub username: String,
@ -280,6 +256,15 @@ pub struct User {
pub indexable: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub extensions: Option<ExtensionSpecs>,
pub manually_approves_followers: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct UserCollections {
pub outbox: Url,
pub featured: Url,
pub followers: Url,
pub following: Url,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
@ -321,7 +306,7 @@ pub struct LinkPreview {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Note {
#[serde(rename = "type")]
pub rtype: VersiaType,
pub rtype: String,
pub id: Uuid,
pub uri: Url,
pub author: Url,
@ -349,46 +334,6 @@ pub struct Note {
pub subject: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_sensitive: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub visibility: Option<VisibilityType>,
//TODO extensions
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Patch {
#[serde(rename = "type")]
pub rtype: VersiaType,
pub id: Uuid,
pub uri: Url,
pub author: Url,
#[serde(with = "iso_versia")]
pub created_at: OffsetDateTime,
#[serde(with = "iso_versia")]
pub patched_at: OffsetDateTime,
#[serde(skip_serializing_if = "Option::is_none")]
pub category: Option<CategoryType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<ContentFormat>,
#[serde(skip_serializing_if = "Option::is_none")]
pub device: Option<DeviceInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub previews: Option<Vec<LinkPreview>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub group: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attachments: Option<Vec<ContentFormat>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub replies_to: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quotes: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mentions: Option<Vec<Url>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_sensitive: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub visibility: Option<VisibilityType>,
//TODO extensions
}
@ -399,14 +344,14 @@ pub struct Outbox {
#[serde(skip_serializing_if = "Option::is_none")]
pub next: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prev: Option<Url>,
pub previous: Option<Url>,
pub items: Vec<Note>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Follow {
#[serde(rename = "type")]
pub rtype: VersiaType,
pub rtype: String,
pub id: Uuid,
pub uri: Url,
pub author: Url,
@ -418,7 +363,7 @@ pub struct Follow {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct FollowResult {
#[serde(rename = "type")]
pub rtype: VersiaType,
pub rtype: String,
pub id: Uuid,
pub uri: Url,
pub author: Url,
@ -426,3 +371,26 @@ pub struct FollowResult {
pub created_at: OffsetDateTime,
pub follower: Url,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Unfollow {
#[serde(rename = "type")]
pub rtype: String,
pub id: Uuid,
pub author: Url,
#[serde(with = "iso_versia")]
pub created_at: OffsetDateTime,
pub followee: Url,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Delete {
#[serde(rename = "type")]
pub rtype: String,
pub id: Uuid,
pub author: Option<Url>,
#[serde(with = "iso_versia")]
pub created_at: OffsetDateTime,
pub deleted_type: String,
pub deleted: Url,
}

View file

@ -10,13 +10,13 @@ pub async fn serialize_user(user: super::objects::User) -> anyhow::Result<String
Ok(data)
}
pub async fn deserialize_versia_type(data: String) -> anyhow::Result<super::objects::VersiaType> {
let versia_type: super::objects::VersiaType = serde_json::from_str(&data)?;
pub async fn deserialize_versia_type(data: String) -> anyhow::Result<String> {
let versia_type: String = serde_json::from_str(&data)?;
Ok(versia_type)
}
pub async fn serialize_versia_type(
versia_type: super::objects::VersiaType,
versia_type: String,
) -> anyhow::Result<String> {
let data = serde_json::to_string(&versia_type)?;
Ok(data)

View file

@ -13,7 +13,7 @@ async fn test_user_serial() {
let user = super::superx::deserialize_user(response.text().await.unwrap())
.await
.unwrap();
let response_outbox = client.get(user.outbox.as_str()).send().await.unwrap();
let response_outbox = client.get(user.collections.outbox.as_str()).send().await.unwrap();
let outbox = super::superx::deserialize_outbox(response_outbox.text().await.unwrap())
.await
.unwrap();
@ -40,7 +40,7 @@ pub async fn main() -> anyhow::Result<()> {
let user_json = serde_json::to_string_pretty(&SortAlphabetically(&user))?;
println!("{}", user_json);
let response_outbox = client.get(user.outbox.as_str()).send().await?;
let response_outbox = client.get(user.collections.outbox.as_str()).send().await?;
let outbox_json = response_outbox.text().await?;
let outbox = super::superx::deserialize_outbox(outbox_json).await?;