# HG changeset patch # User unC0Rr # Date 1554672041 -7200 # Node ID 5696442fee1c6552bf0b0c7d817adf62866163cd Add new forum topics notificator diff -r 000000000000 -r 5696442fee1c .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sun Apr 07 23:20:41 2019 +0200 @@ -0,0 +1,4 @@ +syntax: glob +forum_notifier/target +*.lock +.idea diff -r 000000000000 -r 5696442fee1c forum_notifier/Cargo.toml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/forum_notifier/Cargo.toml Sun Apr 07 23:20:41 2019 +0200 @@ -0,0 +1,12 @@ +[package] +name = "forum_notifier" +version = "0.1.0" +authors = ["Andrey Korotaev "] +edition = "2018" + +[dependencies] +curl = "0.4.20" +log = "0.4.6" +stderrlog = "0.4.1" +scraper = "0.9.2" +dbus = "0.6.4" diff -r 000000000000 -r 5696442fee1c forum_notifier/src/main.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/forum_notifier/src/main.rs Sun Apr 07 23:20:41 2019 +0200 @@ -0,0 +1,97 @@ +use curl::easy::{Easy, WriteError}; +use curl::Error; +use dbus::{BusType, Connection, Message}; +use log::{debug, info, warn}; +use scraper::{Html, Selector}; +use std::fs; +use std::str; +use std::thread; +use std::time; + +fn inform(url: &str, title: &str, author: &str) { + let c = Connection::get_private(BusType::Session).unwrap(); + let mut m = Message::new_method_call( + "org.kde.konversation", + "/irc", + "org.kde.konversation", + "say", + ) + .unwrap(); + let msg_str = &format!("[{}] {}: {}", url, author, title)[..]; + + info!("Notification: {}", msg_str); + + m.append_items(&["freenode".into(), "#hedgewars".into(), msg_str.into()]); + let r = c.send(m).unwrap(); +} + +fn handle_page(url: &str, data: &[u8]) -> Result { + let page = str::from_utf8(data).unwrap(); + let document = Html::parse_document(page); + + let title_selector = Selector::parse("title").unwrap(); + let mut titles = document.select(&title_selector); + + if let Some(title_str) = titles.next() { + let t = &title_str.inner_html(); + let title = &t[..t.len() - 12]; + //info!("Topic is '{}'", title); + + let author_selector = Selector::parse("div.forum-post-wrapper div.forum-post-panel-sub div.author-pane div.author-pane-inner div.author-pane-name-status.author-pane-section div.author-pane-line.author-name").unwrap(); + let mut authors = document.select(&author_selector); + + if let Some(author_name) = authors.next() { + let author = &author_name.inner_html(); + //info!("Author is '{}'", author); + + inform(url, title, &author[1..author.len() - 1]); + } else { + warn!("Author not found"); + } + } else { + warn!("No title found"); + } + + Ok(data.len()) +} + +fn query(url: &str) -> Result<(), Error> { + let mut easy = Easy::new(); + + easy.url(url)?; + easy.fail_on_error(true); + + let mut transfer = easy.transfer(); + transfer.write_function(|data| handle_page(url, data))?; + transfer.perform() +} + +fn main() { + stderrlog::new() + .verbosity(3) + .timestamp(stderrlog::Timestamp::Second) + .module(module_path!()) + .init() + .unwrap(); + + let short_delay = time::Duration::from_secs(3); + let long_delay = time::Duration::from_secs(7 * 60); + let file_name = "/usr/home/unC0Rr/.local/unC0Rr/forumchecker/node.txt"; + let mut node_id: u32 = fs::read_to_string(file_name).unwrap().parse().unwrap(); + + info!("Starting from node id {}", node_id); + + loop { + debug!("Quering node id {}", node_id); + + let res = query(&format!("https://www.hedgewars.org/node/{}", node_id)); + + if let Ok(_) = res { + node_id += 1; + fs::write(file_name, node_id.to_string()).unwrap(); + thread::sleep(short_delay); + } else { + thread::sleep(long_delay); + } + } +}