diff --git a/Cargo.lock b/Cargo.lock index 165aa77..b8a5538 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,9 +445,11 @@ dependencies = [ "axum", "dashmap", "fastrand", + "form_urlencoded", "http", "maud", "reqwest", + "serde_json", "signal-hook", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 2a1cf6f..6f9c6c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,9 @@ axum = {git = "https://github.com/tokio-rs/axum.git", version = "0.6"} tokio = {version = "1", features = ["rt-multi-thread", "macros"]} http = "0.2" fastrand = {version = "2", features = ["std"]} -reqwest = {version = "0.11", default-features = false, features = ["rustls-tls-native-roots"]} +reqwest = {version = "0.11", default-features = false, features = ["rustls-tls-native-roots", "json"]} dashmap = "5" maud = "0.25" -signal-hook = "0.3" \ No newline at end of file +signal-hook = "0.3" +serde_json = "1" +form_urlencoded = "1" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 87612a3..02e55b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ type AppResult = Result; #[derive(Clone)] enum ArtKind { Twitter, + Safebooru, } impl FromStr for ArtKind { @@ -29,6 +30,7 @@ impl FromStr for ArtKind { fn from_str(s: &str) -> Result { match s { "twitter.com" => Ok(Self::Twitter), + "safebooru.org" => Ok(Self::Safebooru), _ => Err("not support website".into()), } } @@ -161,6 +163,7 @@ async fn show_art(state: State) -> AppResult } else { let image_link = match art.kind { ArtKind::Twitter => fetch_twitter_image_link(&state.http, &art.url).await?, + ArtKind::Safebooru => fetch_safebooru_image_link(&state.http, &art.url).await?, }; state .direct_links @@ -199,6 +202,30 @@ fn render_page(art: &Art, image_link: &str) -> Html { Html(content.into_string()) } +async fn fetch_safebooru_image_link(http: &reqwest::Client, url: &Uri) -> AppResult { + let mut id = String::new(); + for (name, value) in form_urlencoded::parse(url.query().unwrap().as_bytes()) { + if name == "id" { + id = value.into_owned(); + } + } + if id.is_empty() { + return Err("no id?".into()); + } + + let url = format!("https://safebooru.org/index.php?page=dapi&s=post&q=index&json=1&id={id}"); + let req = http.get(url).build()?; + let resp = http.execute(req).await?.error_for_status()?; + let data: Vec> = resp.json().await?; + + let image_filename = data[0].get("image").unwrap().as_str().unwrap(); + let image_directory = data[0].get("directory").unwrap().as_str().unwrap(); + + Ok(format!( + "http://safebooru.org/images/{image_directory}/{image_filename}" + )) +} + async fn fetch_twitter_image_link(http: &reqwest::Client, url: &Uri) -> AppResult { let fxurl = Uri::builder() .scheme("https") diff --git a/utils/safebooru-download.sh b/utils/safebooru-download.sh new file mode 100755 index 0000000..c16623f --- /dev/null +++ b/utils/safebooru-download.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +touch all.json +for i in $(seq 0 38); do + curl "https://safebooru.org/index.php?page=dapi&s=post&q=index&tags=project_moon&limit=100&pid=$i&json=1" > temp.json + jq -sr '. | add' temp.json all.json > all.json.temp + mv all.json.temp all.json + rm temp.json +done \ No newline at end of file diff --git a/utils/twitter-filter.sh b/utils/twitter-filter.sh new file mode 100644 index 0000000..2fc28fe --- /dev/null +++ b/utils/twitter-filter.sh @@ -0,0 +1 @@ +jq -r '.messages[] | select(.embeds[0].thumbnail.url | if type == "string" then test("video") else false end | not) | .content | select(test("//twitter.com")) | select(test("@") | not) | select(test("\\|\\|") | not) | select(test("^(https?|ftp):\\/\\/[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,})(:[0-9]+)?(\\/[^ \\t\\r\\n]*)?$")) | split("/") | .[:6] | join("/") | split("?") | .[0]' limb.json > test.txt \ No newline at end of file