WIP Client

This commit is contained in:
Leon Grünewald 2025-01-26 22:12:17 +01:00
parent 8e26b2cb65
commit 467a63b225
5 changed files with 154 additions and 22 deletions

72
Cargo.lock generated
View file

@ -17,6 +17,21 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.95" version = "1.0.95"
@ -89,6 +104,21 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-targets",
]
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.4" version = "0.9.4"
@ -370,6 +400,29 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "iana-time-zone"
version = "0.1.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "icu_collections" name = "icu_collections"
version = "1.5.0" version = "1.5.0"
@ -624,6 +677,15 @@ dependencies = [
"tempfile", "tempfile",
] ]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.7" version = "0.36.7"
@ -885,6 +947,7 @@ name = "rustyfox"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono",
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
@ -1364,6 +1427,15 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets",
]
[[package]] [[package]]
name = "windows-registry" name = "windows-registry"
version = "0.2.0" version = "0.2.0"

View file

@ -5,8 +5,8 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0" anyhow = "1.0"
reqwest = "0.12" reqwest = { version = "0.12", features = ["json"] }
tokio = { version = "1.43", features = ["full", "rt-multi-thread"]} tokio = { version = "1.43", features = ["full", "rt-multi-thread"]}
serde = { version = "1.0", features = ["default", "derive"]} serde = { version = "1.0", features = ["default", "derive"]}
serde_json = { version = "1.0", features = ["default", "std", "alloc"]} serde_json = { version = "1.0", features = ["default", "std", "alloc"]}
chrono = "0.4" chrono = { version = "0.4", features = ["serde"] }

View file

@ -1,24 +1,44 @@
use std::collections::HashMap;
use reqwest::header::HeaderMap; use reqwest::header::HeaderMap;
use crate::models::{CookieRequest, Submission, SubmissionRequest};
const FA_API_BASE_ORIGIN: &str = "https://furaffinity-api.herokuapp.com";
pub struct Client { pub struct Client {
request_client: reqwest::Client request_client: reqwest::Client,
cookies: HashMap<String, String>
} }
impl Client { impl Client {
pub fn new() -> anyhow::Result<Self> { pub fn new(cookies: HashMap<String, String>) -> anyhow::Result<Self> {
let headers = HeaderMap::from_iter(vec![ let headers = HeaderMap::from_iter(vec![
(reqwest::header::CONTENT_TYPE, "application/json".into()) (reqwest::header::ACCEPT, "application/json".try_into()?),
(reqwest::header::CONTENT_TYPE, "application/json".try_into()?)
].into_iter()); ].into_iter());
let request_client = reqwest::ClientBuilder::new() let request_client = reqwest::ClientBuilder::new()
.default_headers(headers) .default_headers(headers)
.build()?; .build()?;
Ok(Self { Ok(Self {
request_client request_client,
cookies
}) })
} }
pub fn get_submission<S>(submission_id: S) where S: Into<String> -> anyhow::Result<> { pub async fn get_submission<S>(&mut self, submission_id: S) -> anyhow::Result<Submission> where S: Into<String> {
todo!(); let url = format!("{FA_API_BASE_ORIGIN}/submission/{}", submission_id.into());
let res = self.request_client
.post(url)
.json(&SubmissionRequest {
cookies: vec![
],
bbcode: false
})
.send().await?;
println!("{:?}", res.status());
//File::create("./out.json")?.write(res.text().await?.as_bytes())?;
let submission: Submission = res.json().await?;
Ok(submission)
} }
} }

9
src/main.rs Normal file
View file

@ -0,0 +1,9 @@
use rustyfox::client::Client;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut client = Client::new()?;
let submission = client.get_submission("59630962").await?;
println!("Submission: {:?}", submission);
Ok(())
}

View file

@ -1,47 +1,78 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CookieRequest {
pub name: String,
pub value: String
}
impl CookieRequest {
pub fn new<S>(name: S, value: S) -> Self where S: Into<String> {
Self { name: name.into(), value: value.into() }
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SubmissionRequest {
pub cookies: Vec<CookieRequest>,
pub bbcode: bool
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Author { pub struct Author {
pub name: String, pub name: String,
pub status: String, pub status: String,
pub title: String, pub title: String,
pub avatar_url: String, pub avatar_url: String,
pub join_date: DateTime<Utc>, // pub join_date: DateTime<Utc>,
pub join_date: String,
} }
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Stats { pub struct Stats {
pub views: i32, pub views: i32,
pub comments: i32, pub comments: i32,
pub favorites: i32, pub favorites: i32,
} }
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct UserFolder { pub struct UserFolder {
pub name: String, pub name: String,
pub url: String, pub url: String,
pub group: String, pub group: String,
} }
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Replies {
id: i32,
author: Author,
text: String,
replies: Vec<Replies>,
reply_to: i32,
edited: bool,
hidden: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Comment { pub struct Comment {
pub id: i32, pub id: i32,
pub author: Author, pub author: Author,
pub date: DateTime<Utc>, // pub date: DateTime<Utc>,
pub date: String,
pub text: String, pub text: String,
pub replies: Vec<String>, pub replies: Vec<Replies>,
pub reply_to: i32, pub reply_to: Option<i32>,
pub edited: bool, pub edited: bool,
pub hidden: bool, pub hidden: bool,
} }
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Submission { pub struct Submission {
pub id: i32, pub id: i32,
pub title: String, pub title: String,
pub author: Author, pub author: Author,
pub date: DateTime<Utc>, // pub date: DateTime<Utc>,
pub date: String,
pub tags: Vec<String>, pub tags: Vec<String>,
pub category: String, pub category: String,
pub species: String, pub species: String,
@ -58,8 +89,8 @@ pub struct Submission {
pub file_url: String, pub file_url: String,
pub thumbnail_url: String, pub thumbnail_url: String,
pub comments: Vec<Comment>, pub comments: Vec<Comment>,
pub prev: i32, pub prev: Option<i32>,
pub next: i32, pub next: Option<i32>,
pub favorite: bool, pub favorite: bool,
pub favorite_toggle_link: String, pub favorite_toggle_link: String,
} }