aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXe Iaso <me@christine.website>2022-10-30 14:22:56 -0400
committerXe Iaso <me@christine.website>2022-10-30 14:22:56 -0400
commitc654d84537a50e164c57852fc89216eec8e55d69 (patch)
tree7844201ca37fe998309f81b000dc86477d05e4ca
parent79a0a167ee87e925091a55f7de88d02bcea42c92 (diff)
downloadxesite-c654d84537a50e164c57852fc89216eec8e55d69.tar.xz
xesite-c654d84537a50e164c57852fc89216eec8e55d69.zip
start working on a mastodon post embed tag
Signed-off-by: Xe Iaso <me@christine.website>
-rw-r--r--Cargo.lock177
-rw-r--r--Cargo.toml5
-rw-r--r--data/toots/8e4f43b38bb5572d8002f73dac7a4fcd9b3573d205ea8d2b8b1b28aab7d03447.json44
-rw-r--r--data/toots/a83e23736eb81745c08464f913685f6e8479db6096355aa8c217c66c3e120be3.json28
-rw-r--r--default.nix1
-rw-r--r--flake.nix1
-rw-r--r--lib/xesite_templates/Cargo.toml4
-rw-r--r--lib/xesite_templates/src/lib.rs35
-rw-r--r--lib/xesite_types/Cargo.toml1
-rw-r--r--lib/xesite_types/src/mastodon.rs118
-rw-r--r--src/bin/fetch_mastodon_post.rs56
-rw-r--r--src/lib.rs7
12 files changed, 410 insertions, 67 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 67b0f46..dadbcee 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -554,7 +554,7 @@ dependencies = [
"dtoa-short",
"itoa 0.4.8",
"matches",
- "phf",
+ "phf 0.8.0",
"proc-macro2",
"quote",
"smallvec",
@@ -835,6 +835,16 @@ dependencies = [
]
[[package]]
+name = "futf"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843"
+dependencies = [
+ "mac",
+ "new_debug_unreachable",
+]
+
+[[package]]
name = "futures"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1085,6 +1095,33 @@ dependencies = [
]
[[package]]
+name = "html2text"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db2a75f4fdb748c0980b4d04f8edafc749bf4b5bfa738bf6c1565c7e6118d6ca"
+dependencies = [
+ "html5ever",
+ "markup5ever",
+ "tendril",
+ "unicode-width",
+ "xml5ever",
+]
+
+[[package]]
+name = "html5ever"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7"
+dependencies = [
+ "log",
+ "mac",
+ "markup5ever",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "http"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1365,12 +1402,32 @@ dependencies = [
]
[[package]]
+name = "mac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
+
+[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
+name = "markup5ever"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016"
+dependencies = [
+ "log",
+ "phf 0.10.1",
+ "phf_codegen 0.10.0",
+ "string_cache",
+ "string_cache_codegen",
+ "tendril",
+]
+
+[[package]]
name = "matches"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1495,6 +1552,12 @@ dependencies = [
]
[[package]]
+name = "new_debug_unreachable"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
+
+[[package]]
name = "nodrop"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1790,18 +1853,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_macros",
- "phf_shared",
+ "phf_shared 0.8.0",
"proc-macro-hack",
]
[[package]]
+name = "phf"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
+dependencies = [
+ "phf_shared 0.10.0",
+]
+
+[[package]]
name = "phf_codegen"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
dependencies = [
- "phf_generator",
- "phf_shared",
+ "phf_generator 0.8.0",
+ "phf_shared 0.8.0",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
+dependencies = [
+ "phf_generator 0.10.0",
+ "phf_shared 0.10.0",
]
[[package]]
@@ -1810,18 +1892,28 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
- "phf_shared",
+ "phf_shared 0.8.0",
"rand 0.7.3",
]
[[package]]
+name = "phf_generator"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
+dependencies = [
+ "phf_shared 0.10.0",
+ "rand 0.8.5",
+]
+
+[[package]]
name = "phf_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
dependencies = [
- "phf_generator",
- "phf_shared",
+ "phf_generator 0.8.0",
+ "phf_shared 0.8.0",
"proc-macro-hack",
"proc-macro2",
"quote",
@@ -1838,6 +1930,15 @@ dependencies = [
]
[[package]]
+name = "phf_shared"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
name = "pin-project"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2274,8 +2375,8 @@ dependencies = [
"fxhash",
"log",
"matches",
- "phf",
- "phf_codegen",
+ "phf 0.8.0",
+ "phf_codegen 0.8.0",
"precomputed-hash",
"servo_arc",
"smallvec",
@@ -2490,6 +2591,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
+name = "string_cache"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08"
+dependencies = [
+ "new_debug_unreachable",
+ "once_cell",
+ "parking_lot",
+ "phf_shared 0.10.0",
+ "precomputed-hash",
+ "serde",
+]
+
+[[package]]
+name = "string_cache_codegen"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
+dependencies = [
+ "phf_generator 0.10.0",
+ "phf_shared 0.10.0",
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2550,6 +2677,17 @@ dependencies = [
]
[[package]]
+name = "tendril"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0"
+dependencies = [
+ "futf",
+ "mac",
+ "utf-8",
+]
+
+[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2961,6 +3099,12 @@ dependencies = [
]
[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3237,6 +3381,7 @@ dependencies = [
"eyre",
"futures",
"glob",
+ "hex",
"http",
"http-body",
"hyper",
@@ -3259,6 +3404,7 @@ dependencies = [
"serde_dhall",
"serde_json",
"serde_yaml",
+ "sha2",
"sitemap",
"thiserror",
"tokio",
@@ -3297,6 +3443,7 @@ name = "xesite_templates"
version = "0.1.0"
dependencies = [
"maud",
+ "xesite_types",
]
[[package]]
@@ -3304,6 +3451,7 @@ name = "xesite_types"
version = "0.1.0"
dependencies = [
"chrono",
+ "html2text",
"serde",
"serde_json",
]
@@ -3315,6 +3463,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
[[package]]
+name = "xml5ever"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4034e1d05af98b51ad7214527730626f019682d797ba38b51689212118d8e650"
+dependencies = [
+ "log",
+ "mac",
+ "markup5ever",
+]
+
+[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 449c76b..1aec1d0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,6 +21,7 @@ envy = "0.4"
estimated_read_time = "1"
futures = "0.3"
glob = "0.3"
+hex = "0.4"
http = "0.2"
http-body = "0.4"
hyper = "0.14"
@@ -33,9 +34,11 @@ prometheus = { version = "0.13", default-features = false, features = ["process"
rand = "0"
regex = "1"
reqwest = { version = "0.11", features = ["json"] }
-serde_dhall = "0.11.2"
serde = { version = "1", features = ["derive"] }
+serde_json = "1"
+serde_dhall = "0.11.2"
serde_yaml = "0.9"
+sha2 = "0.9"
sitemap = "0.4"
thiserror = "1"
tokio = { version = "1", features = ["full"] }
diff --git a/data/toots/8e4f43b38bb5572d8002f73dac7a4fcd9b3573d205ea8d2b8b1b28aab7d03447.json b/data/toots/8e4f43b38bb5572d8002f73dac7a4fcd9b3573d205ea8d2b8b1b28aab7d03447.json
new file mode 100644
index 0000000..fc6b68b
--- /dev/null
+++ b/data/toots/8e4f43b38bb5572d8002f73dac7a4fcd9b3573d205ea8d2b8b1b28aab7d03447.json
@@ -0,0 +1,44 @@
+{
+ "id": "https://pony.social/users/cadey/statuses/109258440953407431",
+ "type": "Note",
+ "inReplyTo": null,
+ "published": "2022-10-30T17:38:23Z",
+ "url": "https://pony.social/@cadey/109258440953407431",
+ "attributedTo": "https://pony.social/users/cadey",
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://pony.social/users/cadey/followers"
+ ],
+ "sensitive": false,
+ "atomUri": "https://pony.social/users/cadey/statuses/109258440953407431",
+ "inReplyToAtomUri": null,
+ "conversation": "tag:pony.social,2022-10-30:objectId=5763802:objectType=Conversation",
+ "content": "<p>Testing a video upload for writing something to do with Mastodon</p>",
+ "contentMap": {
+ "en": "<p>Testing a video upload for writing something to do with Mastodon</p>"
+ },
+ "attachment": [
+ {
+ "type": "Document",
+ "mediaType": "video/mp4",
+ "url": "https://cdn.pony.social/file/tscs37-pony-social/media_attachments/files/109/258/439/779/239/363/original/66210576226643d7.mp4",
+ "name": null,
+ "blurhash": "UMAKXFoe4TWWtQkCRQV@jEj[WDjbWVjYoLf+",
+ "width": 1280,
+ "height": 720
+ }
+ ],
+ "tag": [],
+ "replies": {
+ "id": "https://pony.social/users/cadey/statuses/109258440953407431/replies",
+ "type": "Collection",
+ "first": {
+ "type": "CollectionPage",
+ "next": "https://pony.social/users/cadey/statuses/109258440953407431/replies?only_other_accounts=true&page=true",
+ "partOf": "https://pony.social/users/cadey/statuses/109258440953407431/replies",
+ "items": []
+ }
+ }
+} \ No newline at end of file
diff --git a/data/toots/a83e23736eb81745c08464f913685f6e8479db6096355aa8c217c66c3e120be3.json b/data/toots/a83e23736eb81745c08464f913685f6e8479db6096355aa8c217c66c3e120be3.json
new file mode 100644
index 0000000..15e8f2a
--- /dev/null
+++ b/data/toots/a83e23736eb81745c08464f913685f6e8479db6096355aa8c217c66c3e120be3.json
@@ -0,0 +1,28 @@
+{
+ "id": "https://pony.social/users/cadey",
+ "type": "Person",
+ "following": "https://pony.social/users/cadey/following",
+ "followers": "https://pony.social/users/cadey/followers",
+ "inbox": "https://pony.social/users/cadey/inbox",
+ "outbox": "https://pony.social/users/cadey/outbox",
+ "featured": "https://pony.social/users/cadey/collections/featured",
+ "featuredTags": "https://pony.social/users/cadey/collections/tags",
+ "preferredUsername": "cadey",
+ "name": "Xe",
+ "summary": "<p>🔞 Minors, please DNI</p><p>Any statements are my own, not my employer&#39;s</p><p>Archmage of Infrastructure at that VPN company that isn&#39;t actually a VPN company I guess it&#39;s complicated</p><p>ΘΔ</p><p>zi ai-uh-so /zi ai.ə.soʊ/</p>",
+ "url": "https://pony.social/@cadey",
+ "manuallyApprovesFollowers": false,
+ "discoverable": true,
+ "published": "2021-06-30T00:00:00Z",
+ "devices": "https://pony.social/users/cadey/collections/devices",
+ "icon": {
+ "type": "Image",
+ "mediaType": "image/png",
+ "url": "https://cdn.pony.social/file/tscs37-pony-social/accounts/avatars/106/500/315/995/032/015/original/056011b7379c0ecc.png"
+ },
+ "image": {
+ "type": "Image",
+ "mediaType": "image/jpeg",
+ "url": "https://cdn.pony.social/file/tscs37-pony-social/accounts/headers/106/500/315/995/032/015/original/d32327b86f0038ee.jpeg"
+ }
+} \ No newline at end of file
diff --git a/default.nix b/default.nix
index 9cdec71..5ce17c1 100644
--- a/default.nix
+++ b/default.nix
@@ -47,6 +47,7 @@ in pkgs.stdenv.mkDerivation {
cp -rf ${config} $out/config.dhall
cp -rf $src/blog $out/blog
cp -rf $src/css $out/css
+ cp -rf $src/data $out/data
cp -rf $src/gallery $out/gallery
cp -rf $src/static $out/static
cp -rf $src/talks $out/talks
diff --git a/flake.nix b/flake.nix
index 6fe3915..2c48cd8 100644
--- a/flake.nix
+++ b/flake.nix
@@ -45,6 +45,7 @@
installPhase = ''
mkdir -p $out
+ cp -vrf $src/data $out
cp -vrf $src/static $out
cp -vrf $src/css $out
'';
diff --git a/lib/xesite_templates/Cargo.toml b/lib/xesite_templates/Cargo.toml
index 06ab92d..3d66e59 100644
--- a/lib/xesite_templates/Cargo.toml
+++ b/lib/xesite_templates/Cargo.toml
@@ -6,4 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-maud = "0.23.0" \ No newline at end of file
+maud = "0.23.0"
+
+xesite_types = { path = "../xesite_types" } \ No newline at end of file
diff --git a/lib/xesite_templates/src/lib.rs b/lib/xesite_templates/src/lib.rs
index a24e239..b3298d9 100644
--- a/lib/xesite_templates/src/lib.rs
+++ b/lib/xesite_templates/src/lib.rs
@@ -1,4 +1,5 @@
use maud::{html, Markup, PreEscaped};
+use xesite_types::mastodon::{Toot, User};
pub fn talk_warning() -> Markup {
html! {
@@ -165,3 +166,37 @@ pub fn advertiser_nag() -> Markup {
}
}
}
+
+pub fn toot_embed(u: User, t: Toot) -> Markup {
+ html! {
+ .media {
+ .media-left {
+ .avatarholder {
+ img src=(u.icon.url);
+ }
+ }
+ .media-body {
+ .media-heading { (u.name) " @" (u.preferred_username) }
+ .media-content {
+ (PreEscaped::<String>(t.content))
+
+ @for att in &t.attachment {
+ @if att.media_type.starts_with("image/") {
+ img src=(att.url) alt=(att.name.clone().unwrap_or("no description provided".into()));
+ }
+
+ @if att.media_type.starts_with("video/") {
+ video width=(att.width) height=(att.height) controls {
+ source src=(att.url) type=(att.media_type);
+ "Your browser does not support the video tag, see this URL: "
+ a href=(att.url) {(att.url)}
+ }
+ }
+ }
+
+ a href=(t.url) { "Link" }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/xesite_types/Cargo.toml b/lib/xesite_types/Cargo.toml
index 6d1854d..60f6bbf 100644
--- a/lib/xesite_types/Cargo.toml
+++ b/lib/xesite_types/Cargo.toml
@@ -9,5 +9,6 @@ license = "zlib"
[dependencies]
chrono = { version = "0.4", features = [ "serde" ] }
+html2text = "0.4"
serde = { version = "1.0", features = [ "derive" ] }
serde_json = "1" \ No newline at end of file
diff --git a/lib/xesite_types/src/mastodon.rs b/lib/xesite_types/src/mastodon.rs
index 3b4eb2a..4cf1e96 100644
--- a/lib/xesite_types/src/mastodon.rs
+++ b/lib/xesite_types/src/mastodon.rs
@@ -4,193 +4,199 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct User {
#[serde(rename = "id")]
- id: String,
+ pub id: String,
#[serde(rename = "type")]
- user_type: String,
+ pub user_type: String,
#[serde(rename = "following")]
- following: String,
+ pub following: String,
#[serde(rename = "followers")]
- followers: String,
+ pub followers: String,
#[serde(rename = "inbox")]
- inbox: String,
+ pub inbox: String,
#[serde(rename = "outbox")]
- outbox: String,
+ pub outbox: String,
#[serde(rename = "featured")]
- featured: String,
+ pub featured: String,
#[serde(rename = "featuredTags")]
- featured_tags: String,
+ pub featured_tags: String,
#[serde(rename = "preferredUsername")]
- preferred_username: String,
+ pub preferred_username: String,
#[serde(rename = "name")]
- name: String,
+ pub name: String,
#[serde(rename = "summary")]
- summary: String,
+ pub summary: String,
#[serde(rename = "url")]
- url: String,
+ pub url: String,
#[serde(rename = "manuallyApprovesFollowers")]
- manually_approves_followers: bool,
+ pub manually_approves_followers: bool,
#[serde(rename = "discoverable")]
- discoverable: bool,
+ pub discoverable: bool,
#[serde(rename = "published")]
- published: String,
+ pub published: String,
#[serde(rename = "devices")]
- devices: String,
+ pub devices: String,
#[serde(rename = "icon")]
- icon: Icon,
+ pub icon: Icon,
#[serde(rename = "image")]
- image: Icon,
+ pub image: Icon,
}
#[derive(Serialize, Deserialize)]
pub struct Icon {
#[serde(rename = "type")]
- icon_type: String,
+ pub icon_type: String,
#[serde(rename = "mediaType")]
- media_type: String,
+ pub media_type: String,
#[serde(rename = "url")]
- url: String,
+ pub url: String,
}
#[derive(Serialize, Deserialize)]
pub struct Toot {
#[serde(rename = "id")]
- id: String,
+ pub id: String,
#[serde(rename = "type")]
- toot_type: String,
+ pub toot_type: String,
#[serde(rename = "inReplyTo")]
- in_reply_to: Option<String>,
+ pub in_reply_to: Option<String>,
#[serde(rename = "published")]
- published: DateTime<Utc>,
+ pub published: DateTime<Utc>,
#[serde(rename = "url")]
- url: String,
+ pub url: String,
#[serde(rename = "attributedTo")]
- attributed_to: String,
+ pub attributed_to: String,
#[serde(rename = "to")]
- to: Vec<String>,
+ pub to: Vec<String>,
#[serde(rename = "cc")]
- cc: Vec<String>,
+ pub cc: Vec<String>,
#[serde(rename = "sensitive")]
- sensitive: bool,
+ pub sensitive: bool,
#[serde(rename = "atomUri")]
- atom_uri: String,
+ pub atom_uri: String,
#[serde(rename = "inReplyToAtomUri")]
- in_reply_to_atom_uri: Option<String>,
+ pub in_reply_to_atom_uri: Option<String>,
#[serde(rename = "conversation")]
- conversation: String,
+ pub conversation: String,
#[serde(rename = "content")]
- content: String,
+ pub content: String,
#[serde(rename = "contentMap")]
- content_map: ContentMap,
+ pub content_map: ContentMap,
#[serde(rename = "attachment")]
- attachment: Vec<Attachment>,
+ pub attachment: Vec<Attachment>,
#[serde(rename = "tag")]
- tag: Vec<Tag>,
+ pub tag: Vec<Tag>,
#[serde(rename = "replies")]
- replies: Replies,
+ pub replies: Replies,
+}
+
+impl Toot {
+ pub fn content_text(&self) -> String {
+ html2text::from_read(std::io::Cursor::new(&self.content), 80)
+ }
}
#[derive(Serialize, Deserialize)]
pub struct Tag {
#[serde(rename = "type")]
- tag_type: String,
+ pub tag_type: String,
#[serde(rename = "href")]
- href: String,
+ pub href: String,
#[serde(rename = "name")]
- name: String,
+ pub name: String,
}
#[derive(Serialize, Deserialize)]
pub struct Attachment {
#[serde(rename = "type")]
- attachment_type: String,
+ pub attachment_type: String,
#[serde(rename = "mediaType")]
- media_type: String,
+ pub media_type: String,
#[serde(rename = "url")]
- url: String,
+ pub url: String,
#[serde(rename = "name")]
- name: Option<serde_json::Value>,
+ pub name: Option<String>,
#[serde(rename = "blurhash")]
- blurhash: String,
+ pub blurhash: String,
#[serde(rename = "width")]
- width: i64,
+ pub width: i64,
#[serde(rename = "height")]
- height: i64,
+ pub height: i64,
}
#[derive(Serialize, Deserialize)]
pub struct ContentMap {
#[serde(rename = "en")]
- en: String,
+ pub en: String,
}
#[derive(Serialize, Deserialize)]
pub struct Replies {
#[serde(rename = "id")]
- id: String,
+ pub id: String,
#[serde(rename = "type")]
- replies_type: String,
+ pub replies_type: String,
#[serde(rename = "first")]
- first: Page,
+ pub first: Page,
}
#[derive(Serialize, Deserialize)]
pub struct Page {
#[serde(rename = "type")]
- first_type: String,
+ pub first_type: String,
#[serde(rename = "next")]
- next: String,
+ pub next: String,
#[serde(rename = "partOf")]
- part_of: String,
+ pub part_of: String,
#[serde(rename = "items")]
- items: Vec<String>,
+ pub items: Vec<String>,
}
#[cfg(test)]
diff --git a/src/bin/fetch_mastodon_post.rs b/src/bin/fetch_mastodon_post.rs
new file mode 100644
index 0000000..06faa57
--- /dev/null
+++ b/src/bin/fetch_mastodon_post.rs
@@ -0,0 +1,56 @@
+use color_eyre::Result;
+use sha2::{Digest, Sha256};
+use std::{env, fs};
+use tracing::debug;
+use xesite_types::mastodon::{Toot, User};
+
+#[tokio::main]
+async fn main() -> Result<()> {
+ color_eyre::install()?;
+ tracing_subscriber::fmt::init();
+
+ let args: Vec<String> = env::args().collect();
+ debug!("{args:?}");
+ if args.len() != 2 {
+ eprintln!("Usage: {} <mastodon post URL>", args[0]);
+ }
+
+ let mut post_url = args[1].clone();
+ if !post_url.ends_with(".json") {
+ post_url = format!("{post_url}.json");
+ }
+
+ let toot: Toot = reqwest::get(&post_url)
+ .await?
+ .error_for_status()?
+ .json()
+ .await?;
+
+ debug!("got post by {}", toot.attributed_to);
+
+ fs::create_dir_all("./data/toots")?;
+
+ let post_hash = xesite::hash_string(post_url);
+
+ let mut fout = fs::File::create(&format!("./data/toots/{post_hash}.json"))?;
+ serde_json::to_writer_pretty(&mut fout, &toot)?;
+
+ let user_url = format!("{}.json", toot.attributed_to);
+
+ let user: User = reqwest::get(&user_url)
+ .await?
+ .error_for_status()?
+ .json()
+ .await?;
+
+ fs::create_dir_all("./data/users")?;
+
+ debug!("got user {} ({})", user.name, user.preferred_username);
+
+ let user_hash = xesite::hash_string(user_url);
+
+ let mut fout = fs::File::create(&format!("./data/toots/{user_hash}.json"))?;
+ serde_json::to_writer_pretty(&mut fout, &user)?;
+
+ Ok(())
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..1fc1661
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,7 @@
+use sha2::{Digest, Sha256};
+
+pub fn hash_string(inp: String) -> String {
+ let mut h = Sha256::new();
+ h.update(&inp.as_bytes());
+ hex::encode(h.finalize())
+}