Add writing to XML
This commit is contained in:
commit
c43a1b5ed3
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
1810
Cargo.lock
generated
Normal file
1810
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "bib-watcher"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
chrono = "0.4.23"
|
||||||
|
reqwest = { version = "0.11.13", features = ["blocking"]}
|
||||||
|
rss = "2.0.2"
|
||||||
|
scraper = "0.14.0"
|
14
bib.xml
Normal file
14
bib.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<rss version="2.0">
|
||||||
|
<channel>
|
||||||
|
<title>Bib Watcher</title>
|
||||||
|
<link>https://phlaym.net</link>
|
||||||
|
<description>Watches availability status of library books</description>
|
||||||
|
<item>
|
||||||
|
<title>Klufti Affenhitze</title>
|
||||||
|
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
|
||||||
|
<description><![CDATA[entliehen]]></description>
|
||||||
|
<pubDate>Tue, 17 Jan 2023 19:45:23 +0000</pubDate>
|
||||||
|
</item>
|
||||||
|
</channel>
|
||||||
|
</rss>
|
113
src/main.rs
Normal file
113
src/main.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
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()))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user