diff --git a/Cargo.lock b/Cargo.lock index 9418d6e..ad0f9cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,6 +170,7 @@ dependencies = [ "futures", "hyper", "hyper-tls", + "json", "scraper", "tokio", ] @@ -552,6 +553,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + [[package]] name = "lazy_static" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index 0116206..c943dd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,6 @@ ego-tree = "0.6.2" futures = "0.3.28" hyper = { version = "0.14.27", features = ["http2", "client", "http1"] } hyper-tls = "0.5.0" +json = "0.12.4" scraper = "0.17.1" tokio = { version = "1.29.1", features = ["rt-multi-thread"] } diff --git a/src/main.rs b/src/main.rs index fc69924..4e5c53d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,9 @@ use scraper::Node; use ego_tree::NodeRef; use tokio::runtime::Runtime; +use json::JsonValue; +use json::stringify; +use json::object; #[derive(Debug, Clone)] struct Question { @@ -24,6 +27,16 @@ struct Question { answer: String, } +impl Question { + fn to_json(&self) -> JsonValue { + //TODO: fix this syntax to match the actual cards + object!{ + question: self.question.clone(), + answer: self.answer.clone(), + } + } +} + struct Anki { uri: Uri, deck_id: String, @@ -40,10 +53,11 @@ fn main() { let rt = Runtime::new().unwrap(); // the window of available data is like today - 15 days or something let for_date = NaiveDate::from_ymd_opt(2023, 7, 27).unwrap(); // TODO: replace with today - let questions = rt.block_on(scrape_questions(for_date)); + //let questions = rt.block_on(scrape_questions(for_date)); let anki = Anki{ uri: Uri::from_static("http://localhost:8765"), deck_id: "lol".to_string()}; - println!("Questions: {:?}", questions); - rt.block_on(ensure_in_anki(&anki, questions.unwrap())); + //println!("Questions: {:?}", questions); + rt.block_on(ensure_in_anki(&anki, vec![])); + //rt.block_on(ensure_in_anki(&anki, questions.unwrap())); } async fn scrape_questions(date: NaiveDate) -> Option> { @@ -91,17 +105,34 @@ fn strip_number_prefix(question: String) -> String { async fn ensure_in_anki(anki: &Anki, questions: Vec) -> Result<(), String> { - upload_to_anki(anki, questions.iter().filter(not_in_anki).collect::>()).await + upload_to_anki(anki, questions.into_iter().filter(not_in_anki).collect::>()).await } //TODO: implement this -fn not_in_anki(_question: &&Question) -> bool { +fn not_in_anki(_question: &Question) -> bool { true } -async fn upload_to_anki(anki: &Anki, questions: Vec<&Question>) -> Result<(), String> { +async fn upload_to_anki(anki: &Anki, questions: Vec) -> Result<(), String> { + let notes = JsonValue::Array(questions.iter().map(Question::to_json).collect()); + let payload = object!{ + //action: "addNotes", + action: "deckNamesAndIds", + version: 6, + params: { + //notes: notes, + }, + }; + let client = Client::new(); let request = Request::builder() .uri(Uri::from_static("http://localhost:8765")) - .body(Body::from("")); + .body(Body::from(json::stringify(payload))).unwrap(); + let response = client.request(request).await.unwrap(); + let body_bytes = hyper::body::to_bytes(response).await.unwrap().to_vec(); + let payload = json::parse(std::str::from_utf8(&body_bytes).unwrap()).unwrap(); + println!("Data: {:?}", payload["result"]); + for (deckName, id) in payload["result"].entries() { + println!("Deck: {} {}", deckName, id.as_u64().unwrap()); + } Ok(()) }