1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
extern crate curl;
extern crate rss;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate toml;
use std::cmp::Ordering;
use std::fs::File;
use std::io::prelude::*;
use std::error;
use std::thread;
use std::time::Duration;
use std::sync::mpsc::{self, TryRecvError};
use rss::Channel;
use curl::easy::Easy;
pub use notification::Notification;
mod notification;
pub use subscription::Subscription;
mod subscription;
pub use config::Config;
mod config;
pub fn run(config: Config) -> Result<(), Box<error::Error>> {
let subscriptions = config.subscriptions();
let mut threads = vec![];
for subscription in subscriptions.iter() {
let sub_clone = subscription.clone();
threads.push(thread::spawn(move || {
if let Err(e) = main_loop(sub_clone) {
println!("Thread error{}", e);
}
}));
}
for thread in threads {
let _ = thread.join();
}
Ok(())
}
fn main_loop(subscription: Subscription) -> Result<(), Box<error::Error>> {
loop {
let channel = Channel::from_url(subscription.rss_url()).unwrap();
let items = channel.items();
let items_iter = items.iter();
let mut f = File::open(subscription.last_guid_file().as_ref().unwrap())?;
let mut contents = String::new();
f.read_to_string(&mut contents)?;
let mut last_guid: u64 = 0;
for line in contents.lines() {
last_guid = line.parse::<u64>().unwrap();
}
let mut notifications: Vec<Notification> = Vec::new();
for val in items_iter {
if val.guid().unwrap().value().parse::<u64>().unwrap() > last_guid {
notifications.push(Notification::new(
String::from(val.title().unwrap()),
val.guid().unwrap().value().parse::<u64>().unwrap(),
));
}
}
notifications.sort();
for val in notifications.iter() {
send_update(val.text(), subscription.bot_token(), subscription.chat_id());
let mut f = File::create(subscription.last_guid_file().as_ref().unwrap())?;
f.write(val.guid().to_string().as_bytes())?;
println!("{:?}", val.text());
}
thread::sleep(Duration::from_secs(10));
}
}
fn send_update(data: &String, bot_token: &String, chat_id: &String) {
let address = format!(
"{}{}{}",
"https://api.telegram.org/bot",
bot_token,
"/sendMessage"
);
let data = format!("{}{}{}{}", "chat_id=", chat_id, "&text=", data);
let mut data = data.as_bytes();
let mut easy = Easy::new();
easy.url(&address).unwrap();
easy.post(true).unwrap();
easy.post_field_size(data.len() as u64).unwrap();
let mut transfer = easy.transfer();
transfer
.read_function(|buf| Ok(data.read(buf).unwrap_or(0)))
.unwrap();
transfer.perform().unwrap();
}