diff --git a/.gitignore b/.gitignore index ea8c4bf..ac0cfd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target +config.json +bib.xml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 9a0c8ac..a5580f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,13 +97,14 @@ checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "bib-watcher" -version = "0.1.0" +version = "0.2.0" dependencies = [ "chrono", "config", "reqwest", "rss", "scraper", + "serde_json", ] [[package]] @@ -1222,18 +1223,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", @@ -1242,9 +1243,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", diff --git a/Cargo.toml b/Cargo.toml index 1fc3617..3338f7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bib-watcher" -version = "0.1.0" +version = "0.2.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -11,3 +11,4 @@ reqwest = { version = "0.11.13", features = ["blocking"]} rss = "2.0.2" scraper = "0.17.1" config = { version = "0.13.1", features = ["json"], default-features = false} +serde_json = "1.0.108" diff --git a/src/main.rs b/src/main.rs index a902bc0..501bf93 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,8 @@ use config::Config; use reqwest::header; use rss::{Channel, ChannelBuilder, ItemBuilder}; use scraper::{Html, Selector}; -use std::{error::Error, fs::File, io::BufReader}; use std::collections::HashMap; +use std::{error::Error, fs::File, io::BufReader}; use chrono::prelude::*; @@ -17,7 +17,7 @@ fn get_last_status(title: &str) -> Result> { let c = ChannelBuilder::default() .title("Bib Watcher".to_string()) .description("Watches availability status of library books".to_string()) - .link("https://phlaym.net".to_string()) + .link("https://feeds.phlaym.net/".to_string() + FILE_NAME) .build(); c.pretty_write_to(File::create(FILE_NAME)?, b' ', 4)?; Ok(c) @@ -38,9 +38,7 @@ fn main() -> Result<(), Box> { .add_source(config::File::with_name("config.json")) .build()?; let books = settings.try_deserialize::>()?; - let searches = books - .iter() - .collect::>(); + let searches = books.iter().collect::>(); for (title, url) in searches { search(url, title)? } @@ -68,7 +66,12 @@ fn search(url: &str, title: &str) -> Result<(), Box> { .build()?; let request = client.get(url).build()?; let response = client.execute(request)?; - let status = parse(&response.text()?)?; + let response_text = response.text()?; + let mut status = parse(&response_text.clone())?; + if status == "online" { + let id = parse_id(&response_text)?; + status = check_ebook_status(id)?; + } let last_status = get_last_status(title)?; if status != last_status { let file = File::open(FILE_NAME); @@ -77,7 +80,7 @@ fn search(url: &str, title: &str) -> Result<(), Box> { Err(_) => Ok(ChannelBuilder::default() .title("Bib Watcher".to_string()) .description("Watches availability status of library books".to_string()) - .link("https://phlaym.net".to_string()) + .link("https://feeds.phlaym.net/".to_string() + FILE_NAME) .build()), }?; let mut items = channel.clone().into_items(); @@ -95,6 +98,23 @@ fn search(url: &str, title: &str) -> Result<(), Box> { Ok(()) } +fn check_ebook_status(ebook_id: u32) -> Result> { + let id_param = ebook_id.to_string(); + let client = reqwest::blocking::Client::new(); // ::builder().build()?; + let request = client + .post("https://webopac.winbiap.de/konstanz/service/ncipservice.ashx") + .form(&HashMap::from([ + ("action", "lookup"), + ("itemId", &id_param), + ])) + .build()?; + let response = client.execute(request)?; + let v: serde_json::Value = serde_json::from_reader(response)?; + let v2: &serde_json::Value = &v["MediaItem"]["Available"]; + let a: bool = serde_json::value::from_value(v2.clone())?; + Ok((if a { "verfügbar" } else { "entliehen" }).into()) +} + fn parse(html: &str) -> Result> { let document = Html::parse_document(html); let selector = Selector::parse("#detail-left-wrapper .mediaStatus span")?; @@ -104,3 +124,16 @@ fn parse(html: &str) -> Result> { .map(|r| r.text().collect::()) .unwrap_or_else(|| "Unknown".into())) } + +fn parse_id(html: &str) -> Result> { + let document = Html::parse_document(html); + let selector = Selector::parse("#hyperlinkDiviBib")?; + + document + .select(&selector) + .next() + .and_then(|r| r.value().attr("data-id")) + .unwrap_or("Unknown") + .parse::() + .map_err(From::from) +}