feat: lysand user

This commit is contained in:
aprilthepink 2024-05-13 21:31:33 +02:00
parent 9e6445d192
commit eec3a037bb
7 changed files with 369 additions and 22 deletions

191
Cargo.lock generated
View file

@ -25,14 +25,14 @@ dependencies = [
"http-signature-normalization", "http-signature-normalization",
"http-signature-normalization-reqwest", "http-signature-normalization-reqwest",
"httpdate", "httpdate",
"hyper", "hyper 0.14.28",
"itertools", "itertools",
"moka", "moka",
"once_cell", "once_cell",
"openssl", "openssl",
"pin-project-lite", "pin-project-lite",
"regex", "regex",
"reqwest", "reqwest 0.11.27",
"reqwest-middleware", "reqwest-middleware",
"serde", "serde",
"serde_json", "serde_json",
@ -91,7 +91,7 @@ dependencies = [
"encoding_rs", "encoding_rs",
"flate2", "flate2",
"futures-core", "futures-core",
"h2", "h2 0.3.26",
"http 0.2.12", "http 0.2.12",
"httparse", "httparse",
"httpdate", "httpdate",
@ -477,7 +477,7 @@ dependencies = [
"headers", "headers",
"http 0.2.12", "http 0.2.12",
"http-body 0.4.6", "http-body 0.4.6",
"hyper", "hyper 0.14.28",
"itoa", "itoa",
"matchit", "matchit",
"memchr", "memchr",
@ -538,6 +538,12 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]] [[package]]
name = "base64ct" name = "base64ct"
version = "1.6.0" version = "1.6.0"
@ -1372,6 +1378,25 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "h2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 1.1.0",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.3"
@ -1553,7 +1578,7 @@ dependencies = [
"base64 0.13.1", "base64 0.13.1",
"http-signature-normalization", "http-signature-normalization",
"httpdate", "httpdate",
"reqwest", "reqwest 0.11.27",
"reqwest-middleware", "reqwest-middleware",
"sha2", "sha2",
"thiserror", "thiserror",
@ -1588,7 +1613,7 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-util", "futures-util",
"h2", "h2 0.3.26",
"http 0.2.12", "http 0.2.12",
"http-body 0.4.6", "http-body 0.4.6",
"httparse", "httparse",
@ -1602,6 +1627,26 @@ dependencies = [
"want", "want",
] ]
[[package]]
name = "hyper"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2 0.4.4",
"http 1.1.0",
"http-body 1.0.0",
"httparse",
"itoa",
"pin-project-lite",
"smallvec",
"tokio",
"want",
]
[[package]] [[package]]
name = "hyper-tls" name = "hyper-tls"
version = "0.5.0" version = "0.5.0"
@ -1609,12 +1654,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [ dependencies = [
"bytes", "bytes",
"hyper", "hyper 0.14.28",
"native-tls", "native-tls",
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
] ]
[[package]]
name = "hyper-tls"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes",
"http-body-util",
"hyper 1.3.1",
"hyper-util",
"native-tls",
"tokio",
"tokio-native-tls",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.3.1",
"pin-project-lite",
"socket2",
"tokio",
"tower",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.60" version = "0.1.60"
@ -1826,10 +1907,13 @@ dependencies = [
"lazy_static", "lazy_static",
"num_cpus", "num_cpus",
"rand", "rand",
"reqwest 0.12.4",
"sea-orm", "sea-orm",
"serde", "serde",
"serde_derive",
"serde_json", "serde_json",
"thiserror", "thiserror",
"time",
"tokio", "tokio",
"tracing", "tracing",
"url", "url",
@ -2458,11 +2542,11 @@ dependencies = [
"encoding_rs", "encoding_rs",
"futures-core", "futures-core",
"futures-util", "futures-util",
"h2", "h2 0.3.26",
"http 0.2.12", "http 0.2.12",
"http-body 0.4.6", "http-body 0.4.6",
"hyper", "hyper 0.14.28",
"hyper-tls", "hyper-tls 0.5.0",
"ipnet", "ipnet",
"js-sys", "js-sys",
"log", "log",
@ -2472,7 +2556,7 @@ dependencies = [
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"rustls-pemfile", "rustls-pemfile 1.0.4",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
@ -2487,7 +2571,51 @@ dependencies = [
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-streams", "wasm-streams",
"web-sys", "web-sys",
"winreg", "winreg 0.50.0",
]
[[package]]
name = "reqwest"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
dependencies = [
"base64 0.22.1",
"bytes",
"encoding_rs",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.4.4",
"http 1.1.0",
"http-body 1.0.0",
"http-body-util",
"hyper 1.3.1",
"hyper-tls 0.6.0",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"mime_guess",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile 2.1.2",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"system-configuration",
"tokio",
"tokio-native-tls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg 0.52.0",
] ]
[[package]] [[package]]
@ -2499,7 +2627,7 @@ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
"http 0.2.12", "http 0.2.12",
"reqwest", "reqwest 0.11.27",
"serde", "serde",
"task-local-extensions", "task-local-extensions",
"thiserror", "thiserror",
@ -2647,6 +2775,22 @@ dependencies = [
"base64 0.21.7", "base64 0.21.7",
] ]
[[package]]
name = "rustls-pemfile"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
dependencies = [
"base64 0.22.1",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.101.7" version = "0.101.7"
@ -2819,18 +2963,18 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.197" version = "1.0.201"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.197" version = "1.0.201"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3023,7 +3167,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"rust_decimal", "rust_decimal",
"rustls", "rustls",
"rustls-pemfile", "rustls-pemfile 1.0.4",
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2",
@ -3494,6 +3638,7 @@ dependencies = [
"futures-util", "futures-util",
"pin-project", "pin-project",
"pin-project-lite", "pin-project-lite",
"tokio",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing", "tracing",
@ -4036,6 +4181,16 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "winreg"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "wyz" name = "wyz"
version = "0.5.1" version = "0.5.1"

View file

@ -29,6 +29,9 @@ serde_json = "1.0.115"
chrono = "0.4.38" chrono = "0.4.38"
lazy_static = "1.4.0" lazy_static = "1.4.0"
async_once = "0.2.6" async_once = "0.2.6"
reqwest = { version = "0.12.4", features = ["blocking", "json", "multipart"] }
time = { version = "0.3.36", features = ["serde"] }
serde_derive = "1.0.201"
[dependencies.sea-orm] [dependencies.sea-orm]
version = "0.12.0" version = "0.12.0"

View file

@ -1 +1,3 @@
pub mod objects; pub mod objects;
pub mod superx;
pub mod test;

View file

@ -1,13 +1,135 @@
extern crate serde; // 1.0.68
extern crate serde_derive; // 1.0.68
use std::{
collections::HashMap,
fmt::{Display, Formatter},
};
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
use time::{
format_description::well_known::{iso8601, Iso8601},
OffsetDateTime,
};
use url::Url; use url::Url;
pub enum LysandType { const FORMAT: Iso8601<6651332276412969266533270467398074368> = Iso8601::<
User, {
iso8601::Config::DEFAULT
.set_year_is_six_digits(false)
.encode()
},
>;
time::serde::format_description!(iso_lysand, OffsetDateTime, FORMAT);
fn sort_alphabetically<T: Serialize, S: serde::Serializer>(
value: &T,
serializer: S,
) -> Result<S::Ok, S::Error> {
let value = serde_json::to_value(value).map_err(serde::ser::Error::custom)?;
value.serialize(serializer)
} }
pub struct User { #[derive(Serialize)]
pub struct SortAlphabetically<T: Serialize>(#[serde(serialize_with = "sort_alphabetically")] pub T);
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum LysandType {
User,
Note,
Patch,
Like,
Dislike,
Follow,
FollowAccept,
FollowReject,
Undo,
Extension,
ServerMetadata,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct PublicKey {
public_key: String, public_key: String,
actor: Url,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ContentHash {
md5: Option<String>,
sha1: Option<String>,
sha256: Option<String>,
sha512: Option<String>,
}
#[derive(Debug, Clone)]
struct ContentFormat {
x: HashMap<String, ContentEntry>,
}
impl Serialize for ContentFormat {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_map(Some(self.x.len()))?;
for (k, v) in &self.x {
seq.serialize_entry(&k.to_string(), &v)?;
}
seq.end()
}
}
impl<'de> Deserialize<'de> for ContentFormat {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let map = HashMap::deserialize(deserializer)?;
Ok(ContentFormat { x: map })
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
struct FieldKV {
key: ContentFormat,
value: ContentFormat,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ContentEntry {
content: String,
description: Option<String>,
size: Option<u64>,
hash: Option<ContentHash>,
blurhash: Option<String>,
fps: Option<u64>,
width: Option<u64>,
height: Option<u64>,
duration: Option<u64>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct User {
public_key: PublicKey,
#[serde(rename = "type")]
rtype: LysandType,
id: String, id: String,
uri: Url, uri: Url,
created_at: String, #[serde(with = "iso_lysand")]
created_at: OffsetDateTime,
display_name: Option<String>, display_name: Option<String>,
// TODO bio: Option<String>,
inbox: Url,
outbox: Url,
featured: Url,
followers: Url,
following: Url,
likes: Url,
dislikes: Url,
username: String,
bio: Option<ContentFormat>,
avatar: Option<ContentFormat>,
header: Option<ContentFormat>,
fields: Option<Vec<FieldKV>>,
} }

35
src/lysand/superx.rs Normal file
View file

@ -0,0 +1,35 @@
use super::objects::SortAlphabetically;
pub async fn deserialize_user(data: String) -> anyhow::Result<super::objects::User> {
let user: super::objects::User = serde_json::from_str(&data)?;
Ok(user)
}
pub async fn serialize_user(user: super::objects::User) -> anyhow::Result<String> {
let data = serde_json::to_string(&SortAlphabetically(&user))?;
Ok(data)
}
pub async fn deserialize_lysand_type(data: String) -> anyhow::Result<super::objects::LysandType> {
let lysand_type: super::objects::LysandType = serde_json::from_str(&data)?;
Ok(lysand_type)
}
pub async fn serialize_lysand_type(
lysand_type: super::objects::LysandType,
) -> anyhow::Result<String> {
let data = serde_json::to_string(&lysand_type)?;
Ok(data)
}
#[inline]
pub fn request_client() -> reqwest::Client {
reqwest::Client::builder()
.user_agent(concat!(
env!("CARGO_PKG_NAME"),
"/",
env!("CARGO_PKG_VERSION"),
))
.build()
.unwrap()
}

26
src/lysand/test.rs Normal file
View file

@ -0,0 +1,26 @@
use crate::lysand::objects::SortAlphabetically;
use super::superx::request_client;
pub async fn main() -> anyhow::Result<()> {
let client = request_client();
println!("Requesting user");
let response = client
.get("https://social.lysand.org/users/018ec082-0ae1-761c-b2c5-22275a611771")
.send()
.await?;
println!("Response: {:?}", response);
let user_json = response.text().await?;
println!("User JSON: {:?}", user_json);
let user = super::superx::deserialize_user(user_json).await?;
println!("\n\n\nUser: ");
print!("{:#?}", user);
println!("\n\n\nas JSON:");
let user_json = serde_json::to_string_pretty(&SortAlphabetically(&user))?;
println!("{}", user_json);
Ok(())
}

View file

@ -149,6 +149,10 @@ static FEDERATION_CONFIG: OnceLock<FederationConfig<State>> = OnceLock::new();
async fn main() -> actix_web::Result<(), anyhow::Error> { async fn main() -> actix_web::Result<(), anyhow::Error> {
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
//TODO remove this
lysand::test::main().await?;
return Ok(());
let ap_id = Url::parse(&format!( let ap_id = Url::parse(&format!(
"https://{}/{}", "https://{}/{}",
DOMAIN.to_string(), DOMAIN.to_string(),