forum_notifier/src/main.rs
changeset 1 52bbcfcbd850
parent 0 5696442fee1c
equal deleted inserted replaced
0:5696442fee1c 1:52bbcfcbd850
     6 use std::fs;
     6 use std::fs;
     7 use std::str;
     7 use std::str;
     8 use std::thread;
     8 use std::thread;
     9 use std::time;
     9 use std::time;
    10 
    10 
    11 fn inform(url: &str, title: &str, author: &str) {
    11 struct StateInfo {
       
    12     url: String,
       
    13     previous_title: String,
       
    14     previous_author: String,
       
    15 }
       
    16 
       
    17 fn inform(state: &mut StateInfo, title: &str, author: &str) {
       
    18     if state.previous_title == title && state.previous_author == author {
       
    19         return;
       
    20     }
       
    21 
       
    22     state.previous_title = title.to_string();
       
    23     state.previous_author = author.to_string();
       
    24 
    12     let c = Connection::get_private(BusType::Session).unwrap();
    25     let c = Connection::get_private(BusType::Session).unwrap();
    13     let mut m = Message::new_method_call(
    26     let mut m = Message::new_method_call(
    14         "org.kde.konversation",
    27         "org.kde.konversation",
    15         "/irc",
    28         "/irc",
    16         "org.kde.konversation",
    29         "org.kde.konversation",
    17         "say",
    30         "say",
    18     )
    31     )
    19     .unwrap();
    32     .unwrap();
    20     let msg_str = &format!("[{}] {}: {}", url, author, title)[..];
    33     let msg_str = &format!("[{}] {}: {}", state.url, author, title)[..];
    21 
    34 
    22     info!("Notification: {}", msg_str);
    35     info!("Notification: {}", msg_str);
    23 
    36 
    24     m.append_items(&["freenode".into(), "#hedgewars".into(), msg_str.into()]);
    37     m.append_items(&["freenode".into(), "#hedgewars".into(), msg_str.into()]);
    25     let r = c.send(m).unwrap();
    38     let _r = c.send(m).unwrap();
    26 }
    39 }
    27 
    40 
    28 fn handle_page(url: &str, data: &[u8]) -> Result<usize, WriteError> {
    41 fn handle_page(state: &mut StateInfo, data: &[u8]) -> Result<usize, WriteError> {
    29     let page = str::from_utf8(data).unwrap();
    42     let page = str::from_utf8(data).unwrap();
    30     let document = Html::parse_document(page);
    43     let document = Html::parse_document(page);
    31 
    44 
    32     let title_selector = Selector::parse("title").unwrap();
    45     let title_selector = Selector::parse("title").unwrap();
    33     let mut titles = document.select(&title_selector);
    46     let mut titles = document.select(&title_selector);
    42 
    55 
    43         if let Some(author_name) = authors.next() {
    56         if let Some(author_name) = authors.next() {
    44             let author = &author_name.inner_html();
    57             let author = &author_name.inner_html();
    45             //info!("Author is '{}'", author);
    58             //info!("Author is '{}'", author);
    46 
    59 
    47             inform(url, title, &author[1..author.len() - 1]);
    60             inform(state, title, &author[1..author.len() - 1]);
    48         } else {
    61         } else {
    49             warn!("Author not found");
    62             warn!("Author not found");
    50         }
    63         }
    51     } else {
    64     } else {
    52         warn!("No title found");
    65         warn!("No title found");
    53     }
    66     }
    54 
    67 
    55     Ok(data.len())
    68     Ok(data.len())
    56 }
    69 }
    57 
    70 
    58 fn query(url: &str) -> Result<(), Error> {
    71 fn query(state: &mut StateInfo) -> Result<(), Error> {
    59     let mut easy = Easy::new();
    72     let mut easy = Easy::new();
    60 
    73 
    61     easy.url(url)?;
    74     easy.url(&state.url)?;
    62     easy.fail_on_error(true);
    75     easy.fail_on_error(true)?;
    63 
    76 
    64     let mut transfer = easy.transfer();
    77     let mut transfer = easy.transfer();
    65     transfer.write_function(|data| handle_page(url, data))?;
    78     transfer.write_function(|data| handle_page(state, data))?;
    66     transfer.perform()
    79     transfer.perform()
    67 }
    80 }
    68 
    81 
    69 fn main() {
    82 fn main() {
    70     stderrlog::new()
    83     stderrlog::new()
    73         .module(module_path!())
    86         .module(module_path!())
    74         .init()
    87         .init()
    75         .unwrap();
    88         .unwrap();
    76 
    89 
    77     let short_delay = time::Duration::from_secs(3);
    90     let short_delay = time::Duration::from_secs(3);
    78     let long_delay = time::Duration::from_secs(7 * 60);
    91     let long_delay = time::Duration::from_secs(100);
    79     let file_name = "/usr/home/unC0Rr/.local/unC0Rr/forumchecker/node.txt";
    92     let file_name = "/usr/home/unC0Rr/.local/unC0Rr/forumchecker/node.txt";
    80     let mut node_id: u32 = fs::read_to_string(file_name).unwrap().parse().unwrap();
    93     let mut node_id: u32 = fs::read_to_string(file_name).unwrap().parse().unwrap();
       
    94     let mut known_good_id: Option<u32> = None;
       
    95     let mut shift: u32 = 0;
       
    96 
       
    97     let mut state = StateInfo {
       
    98         url: String::new(),
       
    99         previous_title: String::new(),
       
   100         previous_author: String::new()
       
   101     };
    81 
   102 
    82     info!("Starting from node id {}", node_id);
   103     info!("Starting from node id {}", node_id);
    83 
   104 
    84     loop {
   105     loop {
    85         debug!("Quering node id {}", node_id);
   106         let try_id = node_id + shift;
    86 
   107 
    87         let res = query(&format!("https://www.hedgewars.org/node/{}", node_id));
   108         debug!("Quering node id {}", try_id);
       
   109 
       
   110         thread::sleep(short_delay);
       
   111 
       
   112         state.url = format!("https://www.hedgewars.org/node/{}", try_id);
       
   113 
       
   114         let res = query(&mut state);
    88 
   115 
    89         if let Ok(_) = res {
   116         if let Ok(_) = res {
    90             node_id += 1;
   117             if shift > 0 && known_good_id == None {
    91             fs::write(file_name, node_id.to_string()).unwrap();
   118                 known_good_id = Some(try_id);
    92             thread::sleep(short_delay);
   119                 shift = 0;
       
   120             } else {
       
   121                 node_id = try_id + 1;
       
   122                 if Some(node_id) == known_good_id {
       
   123                     node_id += 1;
       
   124                     known_good_id = None;
       
   125                 }
       
   126                 shift = 0;
       
   127                 fs::write(file_name, node_id.to_string()).unwrap();
       
   128             }
    93         } else {
   129         } else {
    94             thread::sleep(long_delay);
   130             if known_good_id == None {
       
   131                 shift = (shift + 1) % 11;
       
   132                 thread::sleep(long_delay);
       
   133             } else if Some(try_id + 1) == known_good_id {
       
   134                 node_id = known_good_id.unwrap() + 1;
       
   135                 known_good_id = None;
       
   136                 shift = 0;
       
   137                 fs::write(file_name, node_id.to_string()).unwrap();
       
   138             } else {
       
   139                 shift += 1;
       
   140             }
    95         }
   141         }
    96     }
   142     }
    97 }
   143 }