Handle ebooks
This commit is contained in:
parent
97d97f9f22
commit
c110ed0aed
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
|
config.json
|
||||||
|
bib.xml
|
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -97,13 +97,14 @@ checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bib-watcher"
|
name = "bib-watcher"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"config",
|
"config",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rss",
|
"rss",
|
||||||
"scraper",
|
"scraper",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1222,18 +1223,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.188"
|
version = "1.0.192"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.188"
|
version = "1.0.192"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1242,9 +1243,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.107"
|
version = "1.0.108"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
|
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bib-watcher"
|
name = "bib-watcher"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# 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"
|
rss = "2.0.2"
|
||||||
scraper = "0.17.1"
|
scraper = "0.17.1"
|
||||||
config = { version = "0.13.1", features = ["json"], default-features = false}
|
config = { version = "0.13.1", features = ["json"], default-features = false}
|
||||||
|
serde_json = "1.0.108"
|
||||||
|
47
src/main.rs
47
src/main.rs
@ -2,8 +2,8 @@ use config::Config;
|
|||||||
use reqwest::header;
|
use reqwest::header;
|
||||||
use rss::{Channel, ChannelBuilder, ItemBuilder};
|
use rss::{Channel, ChannelBuilder, ItemBuilder};
|
||||||
use scraper::{Html, Selector};
|
use scraper::{Html, Selector};
|
||||||
use std::{error::Error, fs::File, io::BufReader};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::{error::Error, fs::File, io::BufReader};
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ fn get_last_status(title: &str) -> Result<String, Box<dyn Error>> {
|
|||||||
let c = ChannelBuilder::default()
|
let c = ChannelBuilder::default()
|
||||||
.title("Bib Watcher".to_string())
|
.title("Bib Watcher".to_string())
|
||||||
.description("Watches availability status of library books".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();
|
.build();
|
||||||
c.pretty_write_to(File::create(FILE_NAME)?, b' ', 4)?;
|
c.pretty_write_to(File::create(FILE_NAME)?, b' ', 4)?;
|
||||||
Ok(c)
|
Ok(c)
|
||||||
@ -38,9 +38,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
.add_source(config::File::with_name("config.json"))
|
.add_source(config::File::with_name("config.json"))
|
||||||
.build()?;
|
.build()?;
|
||||||
let books = settings.try_deserialize::<HashMap<String, String>>()?;
|
let books = settings.try_deserialize::<HashMap<String, String>>()?;
|
||||||
let searches = books
|
let searches = books.iter().collect::<HashMap<&String, &String>>();
|
||||||
.iter()
|
|
||||||
.collect::<HashMap<&String,&String>>();
|
|
||||||
for (title, url) in searches {
|
for (title, url) in searches {
|
||||||
search(url, title)?
|
search(url, title)?
|
||||||
}
|
}
|
||||||
@ -68,7 +66,12 @@ fn search(url: &str, title: &str) -> Result<(), Box<dyn Error>> {
|
|||||||
.build()?;
|
.build()?;
|
||||||
let request = client.get(url).build()?;
|
let request = client.get(url).build()?;
|
||||||
let response = client.execute(request)?;
|
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)?;
|
let last_status = get_last_status(title)?;
|
||||||
if status != last_status {
|
if status != last_status {
|
||||||
let file = File::open(FILE_NAME);
|
let file = File::open(FILE_NAME);
|
||||||
@ -77,7 +80,7 @@ fn search(url: &str, title: &str) -> Result<(), Box<dyn Error>> {
|
|||||||
Err(_) => Ok(ChannelBuilder::default()
|
Err(_) => Ok(ChannelBuilder::default()
|
||||||
.title("Bib Watcher".to_string())
|
.title("Bib Watcher".to_string())
|
||||||
.description("Watches availability status of library books".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()),
|
.build()),
|
||||||
}?;
|
}?;
|
||||||
let mut items = channel.clone().into_items();
|
let mut items = channel.clone().into_items();
|
||||||
@ -95,6 +98,23 @@ fn search(url: &str, title: &str) -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_ebook_status(ebook_id: u32) -> Result<String, Box<dyn Error>> {
|
||||||
|
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<String, Box<dyn Error>> {
|
fn parse(html: &str) -> Result<String, Box<dyn Error>> {
|
||||||
let document = Html::parse_document(html);
|
let document = Html::parse_document(html);
|
||||||
let selector = Selector::parse("#detail-left-wrapper .mediaStatus span")?;
|
let selector = Selector::parse("#detail-left-wrapper .mediaStatus span")?;
|
||||||
@ -104,3 +124,16 @@ fn parse(html: &str) -> Result<String, Box<dyn Error>> {
|
|||||||
.map(|r| r.text().collect::<String>())
|
.map(|r| r.text().collect::<String>())
|
||||||
.unwrap_or_else(|| "Unknown".into()))
|
.unwrap_or_else(|| "Unknown".into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_id(html: &str) -> Result<u32, Box<dyn Error>> {
|
||||||
|
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::<u32>()
|
||||||
|
.map_err(From::from)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user