From 0fcf36a8610eff9a87783c9e6aa3d2c73dfad87d Mon Sep 17 00:00:00 2001 From: theBreadCompany Date: Mon, 23 Sep 2024 00:34:38 +0200 Subject: [PATCH] introduce libpixiv library and login via refresh token --- .gitignore | 3 +- Cargo.lock | 261 ++++++++++++++++++++++++++--------- Cargo.toml | 16 +-- fxpixiv/Cargo.toml | 13 ++ {src => fxpixiv/src}/main.rs | 0 libpixiv/Cargo.toml | 12 ++ libpixiv/README.md | 14 ++ libpixiv/src/lib.rs | 99 +++++++++++++ 8 files changed, 344 insertions(+), 74 deletions(-) create mode 100644 fxpixiv/Cargo.toml rename {src => fxpixiv/src}/main.rs (100%) create mode 100644 libpixiv/Cargo.toml create mode 100644 libpixiv/README.md create mode 100644 libpixiv/src/lib.rs diff --git a/.gitignore b/.gitignore index c191f14..22faa77 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -result \ No newline at end of file +result +.vscode \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 0966c19..fc83203 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -39,6 +39,21 @@ dependencies = [ "memchr", ] +[[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 = "async-stream" version = "0.3.5" @@ -101,17 +116,17 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -140,9 +155,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "byteorder" @@ -152,15 +167,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cc" -version = "1.1.16" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "shlex", ] @@ -171,6 +186,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + [[package]] name = "cookie" version = "0.18.1" @@ -326,6 +355,18 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.1.1" @@ -460,6 +501,19 @@ dependencies = [ "byteorder", ] +[[package]] +name = "fxpixiv" +version = "0.1.0" +dependencies = [ + "json", + "maud", + "reqwest", + "rocket", + "rusqlite", + "scraper", + "tl", +] + [[package]] name = "generator" version = "0.7.5" @@ -495,9 +549,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -548,6 +602,18 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown", +] [[package]] name = "hermit-abi" @@ -722,9 +788,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" dependencies = [ "bytes", "futures-channel", @@ -740,6 +806,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 = "idna" version = "0.5.0" @@ -769,9 +858,9 @@ checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "is-terminal" @@ -817,6 +906,27 @@ version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +[[package]] +name = "libpixiv" +version = "0.1.0" +dependencies = [ + "chrono", + "md5", + "reqwest", + "serde_json", + "tokio", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -905,6 +1015,12 @@ dependencies = [ "syn", ] +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memchr" version = "2.7.4" @@ -919,11 +1035,11 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -996,6 +1112,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -1317,18 +1442,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "fxpixiv" -version = "0.1.0" -dependencies = [ - "json", - "maud", - "reqwest", - "rocket", - "scraper", - "tl", -] - [[package]] name = "quote" version = "1.0.37" @@ -1370,9 +1483,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ "bitflags", ] @@ -1580,6 +1693,20 @@ dependencies = [ "uncased", ] +[[package]] +name = "rusqlite" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1588,9 +1715,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.36" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags", "errno", @@ -1601,9 +1728,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "once_cell", "rustls-pki-types", @@ -1630,9 +1757,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.102.7" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -1653,11 +1780,11 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1703,9 +1830,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -1732,18 +1859,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -2046,6 +2173,7 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -2132,9 +2260,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap", "serde", @@ -2264,30 +2392,30 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "untrusted" @@ -2453,6 +2581,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-registry" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 841fba2..3ce39ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,6 @@ -[package] -name = "fxpixiv" -version = "0.1.0" -edition = "2021" +[workspace] -[dependencies] -tl = "0.7.8" -reqwest = "0.12.7" -json = "0.12.4" -rocket = "0.5.1" -scraper = "0.20.0" -maud = "0.26.0" +members = [ + "fxpixiv", + "libpixiv", +] diff --git a/fxpixiv/Cargo.toml b/fxpixiv/Cargo.toml new file mode 100644 index 0000000..1499141 --- /dev/null +++ b/fxpixiv/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "fxpixiv" +version = "0.1.0" +edition = "2021" + +[dependencies] +tl = "0.7.8" +reqwest = "0.12.7" +json = "0.12.4" +rocket = "0.5.1" +scraper = "0.20.0" +maud = "0.26.0" +rusqlite = "0.32.1" diff --git a/src/main.rs b/fxpixiv/src/main.rs similarity index 100% rename from src/main.rs rename to fxpixiv/src/main.rs diff --git a/libpixiv/Cargo.toml b/libpixiv/Cargo.toml new file mode 100644 index 0000000..0602fe4 --- /dev/null +++ b/libpixiv/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "libpixiv" +version = "0.1.0" +edition = "2021" + +[dependencies] +chrono = "0.4.38" +md5 = "0.7.0" +reqwest = "0.12.7" +serde_json = "1.0.128" +tokio = { version = "1.40.0", features = ["full"] } + diff --git a/libpixiv/README.md b/libpixiv/README.md new file mode 100644 index 0000000..ad22d01 --- /dev/null +++ b/libpixiv/README.md @@ -0,0 +1,14 @@ +# libpixiv + +Client library for [pixiv](https://pixiv.net) + +## Usage + +For now, no OAuth2 login will be provided, so please make sure to provide refresh tokens yourself. + +## Testing + +You can run the following command to test existing features: +```bash +PIXIV_REFRESH_TOKEN= cargo test --lib +``` \ No newline at end of file diff --git a/libpixiv/src/lib.rs b/libpixiv/src/lib.rs new file mode 100644 index 0000000..fb46142 --- /dev/null +++ b/libpixiv/src/lib.rs @@ -0,0 +1,99 @@ +extern crate md5; +extern crate reqwest; +extern crate serde_json; + +use chrono::{Local}; +use serde_json::{Value}; +use std::sync::{Arc, Mutex}; +use reqwest::header::{HeaderName, USER_AGENT, CONTENT_TYPE}; + + +struct PixivAppClient { + /// bearer token + access_token: Arc>, + refresh_token: Arc>, + http_client: reqwest::Client, + host: &str, +} + +impl PixivAppClient { + fn new(token: &str) -> Self { + let client = Self { + access_token: Arc::new(Mutex::new(String::new())), + refresh_token: Arc::new(Mutex::new(String::from(token))), + http_client: reqwest::Client::new(), + host: "https://app-api.pixiv.net/" + }; + client + } + + fn md5(input: &str) -> String { + let result = md5::compute(input); + format!("{:02x}", result) + } + + pub async fn refresh_token(&mut self) { + let time = Local::now().format("%y-%m-%dT%H:%m:%s+00:00"); + let time_str = format!("{}", time); + let cloned_refresh_token = Arc::clone(&self.refresh_token); + let cloned_refresh_token_str = &cloned_refresh_token.lock().unwrap(); + + let client_id = "MOBrBDS8blbauoSck0ZfDbtuzpyT"; + let client_secret = "lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj"; + let hash_input = format!("{}{}\n", &time_str, "28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c"); + let hash = PixivAppClient::md5(hash_input.as_str()); + + let req = self.http_client + .post("https://oauth.secure.pixiv.net/auth/token") + .header(CONTENT_TYPE, "application/x-www-form-urlencoded") + .header(USER_AGENT, "PixivAndroidApp/5.0.115 (Android 6.0; PixivBot)") + .header(HeaderName::from_lowercase(b"x-client-time").unwrap(), &time_str) + .header(HeaderName::from_lowercase(b"x-client-hash").unwrap(), hash) + .body(format!("grant_type=refresh_token&client_id={}&refresh_token={}&client_secret={}&get_secure_url=1", client_id, cloned_refresh_token_str, client_secret)) + .build() + .expect("failed to build login request"); + + if let Some(body) = req.body() { + if let Some(bytes) = body.as_bytes() { + println!("Body: {}", String::from_utf8_lossy(bytes)); + } else { + println!("Body: Non-text data or stream"); + } + } + + let r = match self.http_client + .execute(req) + .await { + Ok(r) => r.text().await.unwrap(), + Err(_e) => return + }; + let d: Value = serde_json::from_str(&r).unwrap(); + + assert!(!d["response"]["access_token"].is_null()); + assert!(!d["response"]["refresh_token"].is_null()); + + self.access_token = Arc::new(Mutex::new(String::from(d["response"]["access_token"].as_str().unwrap()))); + self.refresh_token = Arc::new(Mutex::new(String::from(d["response"]["refresh_token"].as_str().unwrap()))); + } +} + + +#[cfg(test)] +mod client_tests { + use super::*; + use std::{assert, panic, env}; + + #[tokio::test] + async fn login() { + let token = env::var("PIXIV_REFRESH_TOKEN"); + let mut client = PixivAppClient::new(&token.expect("expecting PIXIV_REFRESH_TOKEN variable for testing!")); + client.refresh_token().await; + let cloned_access_token = Arc::clone(&client.access_token); + match cloned_access_token.lock() { + Ok(t) => assert!(!t.is_empty()), + Err(_) => panic!("No token received!"), + }; + } + + +} \ No newline at end of file