114 lines
4.1 KiB
Rust
114 lines
4.1 KiB
Rust
use reqwest::header;
|
|
use rss::{Channel, ChannelBuilder, ItemBuilder};
|
|
use scraper::{Html, Selector};
|
|
use std::{error::Error, fs::File, io::BufReader};
|
|
|
|
use chrono::prelude::*;
|
|
|
|
const FILE_NAME: &str = "bib.xml";
|
|
|
|
fn get_last_status(title: &str) -> Result<String, Box<dyn Error>> {
|
|
let file = File::open(FILE_NAME);
|
|
let channel = match file {
|
|
Ok(f) => Channel::read_from(BufReader::new(f)),
|
|
Err(_) => {
|
|
let c = ChannelBuilder::default()
|
|
.title("Bib Watcher".to_string())
|
|
.description("Watches availability status of library books".to_string())
|
|
.link("https://phlaym.net".to_string())
|
|
.build();
|
|
c.pretty_write_to(File::create(FILE_NAME)?, b' ', 4)?;
|
|
Ok(c)
|
|
}
|
|
}?;
|
|
Ok(channel
|
|
.items()
|
|
.iter()
|
|
.filter(|i| i.title().unwrap_or("") == title)
|
|
.last()
|
|
.and_then(|i| i.description())
|
|
.unwrap_or("")
|
|
.into())
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
let searches = [(
|
|
"Klufti Affenhitze",
|
|
"https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d"
|
|
)]
|
|
.iter()
|
|
.cloned()
|
|
.collect::<std::collections::HashMap<&str, &str>>();
|
|
for (title, url) in searches {
|
|
search(url, title)?
|
|
}
|
|
/*
|
|
let url = "https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d";
|
|
|
|
if status != "entliehen" {
|
|
Notification::new()
|
|
.summary("Klufti News")
|
|
.body(&format!("Neuer Status: {}", status))
|
|
.show()?;
|
|
}*/
|
|
Ok(())
|
|
}
|
|
|
|
fn search(url: &str, title: &str) -> Result<(), Box<dyn Error>> {
|
|
let mut headers = header::HeaderMap::new();
|
|
headers.append(
|
|
header::ACCEPT,
|
|
header::HeaderValue::from_static(
|
|
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
),
|
|
);
|
|
headers.append(
|
|
header::HOST,
|
|
header::HeaderValue::from_static("webopac.winbiap.de"),
|
|
);
|
|
headers.append(
|
|
header::REFERER,
|
|
header::HeaderValue::from_static("https://webopac.winbiap.de/"),
|
|
);
|
|
let client = reqwest::blocking::Client::builder()
|
|
.default_headers(headers)
|
|
.build()?;
|
|
let request = client.get(url).build()?;
|
|
let response = client.execute(request)?;
|
|
let status = parse(&response.text()?)?;
|
|
let last_status = get_last_status(title)?;
|
|
if status != last_status {
|
|
let file = File::open(FILE_NAME);
|
|
let mut channel = match file {
|
|
Ok(f) => Channel::read_from(BufReader::new(f)),
|
|
Err(_) => Ok(ChannelBuilder::default()
|
|
.title("Bib Watcher".to_string())
|
|
.description("Watches availability status of library books".to_string())
|
|
.link("https://phlaym.net".to_string())
|
|
.build()),
|
|
}?;
|
|
let mut items = channel.clone().into_items();
|
|
items.push(
|
|
ItemBuilder::default()
|
|
.title(Some(title.to_string()))
|
|
.pub_date(Some(Utc::now().to_rfc2822()))
|
|
.link(Some(url.to_string()))
|
|
.description(Some(status))
|
|
.build(),
|
|
);
|
|
channel.set_items(items);
|
|
channel.pretty_write_to(File::create(FILE_NAME)?, b' ', 4)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn parse(html: &str) -> Result<String, Box<dyn Error>> {
|
|
let document = Html::parse_document(html);
|
|
let selector = Selector::parse("#detail-left-wrapper .mediaStatus span")?;
|
|
Ok(document
|
|
.select(&selector)
|
|
.next()
|
|
.map(|r| r.text().collect::<String>())
|
|
.unwrap_or_else(|| "Unknown".into()))
|
|
}
|