Add new forum topics notificator
authorunC0Rr
Sun, 07 Apr 2019 23:20:41 +0200
changeset 0 5696442fee1c
child 1 52bbcfcbd850
Add new forum topics notificator
.hgignore
forum_notifier/Cargo.toml
forum_notifier/src/main.rs
--- /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
--- /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 <a.korotaev@hedgewars.org>"]
+edition = "2018"
+
+[dependencies]
+curl = "0.4.20"
+log = "0.4.6"
+stderrlog = "0.4.1"
+scraper = "0.9.2"
+dbus = "0.6.4"
--- /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<usize, WriteError> {
+    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);
+        }
+    }
+}