|
|
|
@ -18,7 +18,7 @@ use ego_tree::NodeRef; |
|
|
|
|
|
|
|
use tokio::runtime::Runtime;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
struct Question {
|
|
|
|
question: String,
|
|
|
|
answer: String,
|
|
|
|
@ -41,8 +41,9 @@ fn main() { |
|
|
|
// 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 anki = Anki{ uri: Uri::from_static("http://localhost:8765"), deck_id: "lol".to_string()};
|
|
|
|
println!("Questions: {:?}", questions);
|
|
|
|
rt.block_on(upload_to_anki(questions));
|
|
|
|
rt.block_on(ensure_in_anki(&anki, questions.unwrap()));
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn scrape_questions(date: NaiveDate) -> Option<Vec<Question>> {
|
|
|
|
@ -54,7 +55,6 @@ async fn scrape_questions(date: NaiveDate) -> Option<Vec<Question>> { |
|
|
|
.unwrap();
|
|
|
|
let client = Client::builder().build::<_, hyper::Body>(HttpsConnector::new());
|
|
|
|
let resp = client.get(uri).await.unwrap();
|
|
|
|
println!("Status: {:?}", resp.status());
|
|
|
|
let page_contents = hyper::body::to_bytes(resp).await.unwrap();
|
|
|
|
// We have page contents, now parse out the bits we care about
|
|
|
|
let document = Html::parse_document(std::str::from_utf8(&page_contents).unwrap());
|
|
|
|
@ -71,7 +71,7 @@ fn parse_question(element: ElementRef) -> Option<Question> { |
|
|
|
let question_end_selector = Selector::parse("div.answer-box").unwrap();
|
|
|
|
let answer_selector = Selector::parse(".answer").unwrap();
|
|
|
|
let question_end = element.select(&question_end_selector).next();
|
|
|
|
let question = element.children()
|
|
|
|
let prefixed_question = element.children()
|
|
|
|
.take_while(|x| ElementRef::wrap(*x) != question_end)
|
|
|
|
.map(|node| match node.value() {
|
|
|
|
Node::Text(text) => String::from(text.text.trim()),
|
|
|
|
@ -79,15 +79,29 @@ fn parse_question(element: ElementRef) -> Option<Question> { |
|
|
|
_ => panic!("fresh peach heart shower"),
|
|
|
|
})
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join(""); //TODO: remove number prefix here
|
|
|
|
.join("");
|
|
|
|
let question = strip_number_prefix(prefixed_question);
|
|
|
|
let answer = element.select(&answer_selector).next().unwrap().inner_html();
|
|
|
|
Some(Question{question, answer})
|
|
|
|
}
|
|
|
|
|
|
|
|
//async fn upload_to_anki(client: &Client<hyper::Body>, questions: &dyn Iterator<Item = Question>) {
|
|
|
|
// let request = Request::builder()
|
|
|
|
// .uri(Uri::from_static("http://localhost:8765"))
|
|
|
|
// .body(Body::from(""))
|
|
|
|
// .build();
|
|
|
|
// let resp = client.request(request).await.unwrap();
|
|
|
|
//}
|
|
|
|
fn strip_number_prefix(question: String) -> String {
|
|
|
|
question[question.find('.').unwrap()+1..].to_string()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async fn ensure_in_anki(anki: &Anki, questions: Vec<Question>) -> Result<(), String> {
|
|
|
|
upload_to_anki(anki, questions.iter().filter(not_in_anki).collect::<Vec<_>>()).await
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: implement this
|
|
|
|
fn not_in_anki(_question: &&Question) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn upload_to_anki(anki: &Anki, questions: Vec<&Question>) -> Result<(), String> {
|
|
|
|
let request = Request::builder()
|
|
|
|
.uri(Uri::from_static("http://localhost:8765"))
|
|
|
|
.body(Body::from(""));
|
|
|
|
Ok(())
|
|
|
|
}
|