diff --git a/Cargo.lock b/Cargo.lock index 31b729c..bc5c41e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,21 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "anyhow" version = "1.0.95" @@ -89,6 +104,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "core-foundation" version = "0.9.4" @@ -370,6 +400,29 @@ dependencies = [ "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]] name = "icu_collections" version = "1.5.0" @@ -624,6 +677,15 @@ dependencies = [ "tempfile", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "object" version = "0.36.7" @@ -885,6 +947,7 @@ name = "rustyfox" version = "0.1.0" dependencies = [ "anyhow", + "chrono", "reqwest", "serde", "serde_json", @@ -1364,6 +1427,15 @@ dependencies = [ "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]] name = "windows-registry" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index bb7e744..a673bd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,8 @@ edition = "2021" [dependencies] anyhow = "1.0" -reqwest = "0.12" +reqwest = { version = "0.12", features = ["json"] } tokio = { version = "1.43", features = ["full", "rt-multi-thread"]} serde = { version = "1.0", features = ["default", "derive"]} serde_json = { version = "1.0", features = ["default", "std", "alloc"]} -chrono = "0.4" \ No newline at end of file +chrono = { version = "0.4", features = ["serde"] } \ No newline at end of file diff --git a/src/client.rs b/src/client.rs index d5f4e05..b78fec9 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,24 +1,44 @@ +use std::collections::HashMap; use reqwest::header::HeaderMap; +use crate::models::{CookieRequest, Submission, SubmissionRequest}; + +const FA_API_BASE_ORIGIN: &str = "https://furaffinity-api.herokuapp.com"; pub struct Client { - request_client: reqwest::Client + request_client: reqwest::Client, + cookies: HashMap } impl Client { - pub fn new() -> anyhow::Result { + pub fn new(cookies: HashMap) -> anyhow::Result { 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()); let request_client = reqwest::ClientBuilder::new() .default_headers(headers) .build()?; Ok(Self { - request_client + request_client, + cookies }) } - pub fn get_submission(submission_id: S) where S: Into -> anyhow::Result<> { - todo!(); + pub async fn get_submission(&mut self, submission_id: S) -> anyhow::Result where S: Into { + 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) } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..31649c9 --- /dev/null +++ b/src/main.rs @@ -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(()) +} \ No newline at end of file diff --git a/src/models.rs b/src/models.rs index 76ed0c9..57b09d0 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,47 +1,78 @@ 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(name: S, value: S) -> Self where S: Into { + Self { name: name.into(), value: value.into() } + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct SubmissionRequest { + pub cookies: Vec, + pub bbcode: bool +} + +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Author { pub name: String, pub status: String, pub title: String, pub avatar_url: String, - pub join_date: DateTime, + // pub join_date: DateTime, + pub join_date: String, } -#[derive(Clone, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Stats { pub views: i32, pub comments: i32, pub favorites: i32, } -#[derive(Clone, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct UserFolder { pub name: String, pub url: String, pub group: String, } -#[derive(Clone, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Replies { + id: i32, + author: Author, + text: String, + replies: Vec, + reply_to: i32, + edited: bool, + hidden: bool, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Comment { pub id: i32, pub author: Author, - pub date: DateTime, + // pub date: DateTime, + pub date: String, pub text: String, - pub replies: Vec, - pub reply_to: i32, + pub replies: Vec, + pub reply_to: Option, pub edited: bool, pub hidden: bool, } -#[derive(Clone, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Submission { pub id: i32, pub title: String, pub author: Author, - pub date: DateTime, + // pub date: DateTime, + pub date: String, pub tags: Vec, pub category: String, pub species: String, @@ -58,8 +89,8 @@ pub struct Submission { pub file_url: String, pub thumbnail_url: String, pub comments: Vec, - pub prev: i32, - pub next: i32, + pub prev: Option, + pub next: Option, pub favorite: bool, pub favorite_toggle_link: String, } \ No newline at end of file