- Add check for skipped page ids default tip
authorunc0rr
Sun, 05 May 2019 00:06:52 +0200
changeset 1 52bbcfcbd850
parent 0 5696442fee1c
- Add check for skipped page ids - Silence spam with repeated author/title pair
forum_notifier/src/main.rs
--- a/forum_notifier/src/main.rs	Sun Apr 07 23:20:41 2019 +0200
+++ b/forum_notifier/src/main.rs	Sun May 05 00:06:52 2019 +0200
@@ -8,7 +8,20 @@
 use std::thread;
 use std::time;
 
-fn inform(url: &str, title: &str, author: &str) {
+struct StateInfo {
+    url: String,
+    previous_title: String,
+    previous_author: String,
+}
+
+fn inform(state: &mut StateInfo, title: &str, author: &str) {
+    if state.previous_title == title && state.previous_author == author {
+        return;
+    }
+
+    state.previous_title = title.to_string();
+    state.previous_author = author.to_string();
+
     let c = Connection::get_private(BusType::Session).unwrap();
     let mut m = Message::new_method_call(
         "org.kde.konversation",
@@ -17,15 +30,15 @@
         "say",
     )
     .unwrap();
-    let msg_str = &format!("[{}] {}: {}", url, author, title)[..];
+    let msg_str = &format!("[{}] {}: {}", state.url, author, title)[..];
 
     info!("Notification: {}", msg_str);
 
     m.append_items(&["freenode".into(), "#hedgewars".into(), msg_str.into()]);
-    let r = c.send(m).unwrap();
+    let _r = c.send(m).unwrap();
 }
 
-fn handle_page(url: &str, data: &[u8]) -> Result<usize, WriteError> {
+fn handle_page(state: &mut StateInfo, data: &[u8]) -> Result<usize, WriteError> {
     let page = str::from_utf8(data).unwrap();
     let document = Html::parse_document(page);
 
@@ -44,7 +57,7 @@
             let author = &author_name.inner_html();
             //info!("Author is '{}'", author);
 
-            inform(url, title, &author[1..author.len() - 1]);
+            inform(state, title, &author[1..author.len() - 1]);
         } else {
             warn!("Author not found");
         }
@@ -55,14 +68,14 @@
     Ok(data.len())
 }
 
-fn query(url: &str) -> Result<(), Error> {
+fn query(state: &mut StateInfo) -> Result<(), Error> {
     let mut easy = Easy::new();
 
-    easy.url(url)?;
-    easy.fail_on_error(true);
+    easy.url(&state.url)?;
+    easy.fail_on_error(true)?;
 
     let mut transfer = easy.transfer();
-    transfer.write_function(|data| handle_page(url, data))?;
+    transfer.write_function(|data| handle_page(state, data))?;
     transfer.perform()
 }
 
@@ -75,23 +88,56 @@
         .unwrap();
 
     let short_delay = time::Duration::from_secs(3);
-    let long_delay = time::Duration::from_secs(7 * 60);
+    let long_delay = time::Duration::from_secs(100);
     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();
+    let mut known_good_id: Option<u32> = None;
+    let mut shift: u32 = 0;
+
+    let mut state = StateInfo {
+        url: String::new(),
+        previous_title: String::new(),
+        previous_author: String::new()
+    };
 
     info!("Starting from node id {}", node_id);
 
     loop {
-        debug!("Quering node id {}", node_id);
+        let try_id = node_id + shift;
+
+        debug!("Quering node id {}", try_id);
 
-        let res = query(&format!("https://www.hedgewars.org/node/{}", node_id));
+        thread::sleep(short_delay);
+
+        state.url = format!("https://www.hedgewars.org/node/{}", try_id);
+
+        let res = query(&mut state);
 
         if let Ok(_) = res {
-            node_id += 1;
-            fs::write(file_name, node_id.to_string()).unwrap();
-            thread::sleep(short_delay);
+            if shift > 0 && known_good_id == None {
+                known_good_id = Some(try_id);
+                shift = 0;
+            } else {
+                node_id = try_id + 1;
+                if Some(node_id) == known_good_id {
+                    node_id += 1;
+                    known_good_id = None;
+                }
+                shift = 0;
+                fs::write(file_name, node_id.to_string()).unwrap();
+            }
         } else {
-            thread::sleep(long_delay);
+            if known_good_id == None {
+                shift = (shift + 1) % 11;
+                thread::sleep(long_delay);
+            } else if Some(try_id + 1) == known_good_id {
+                node_id = known_good_id.unwrap() + 1;
+                known_good_id = None;
+                shift = 0;
+                fs::write(file_name, node_id.to_string()).unwrap();
+            } else {
+                shift += 1;
+            }
         }
     }
 }