1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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
|
-
-
+
+
+
+
+
+
+
-
+
+
+
+
-
-
+
+
+
+
+
+
|
use anyhow::{anyhow, bail, Context, Result};
use async_std::task;
use chrono::DateTime;
use lazy_static::lazy_static;
use regex::Regex;
use sqlx::postgres::PgPoolOptions;
use telegram_bot::{
_base::Error as TgrError,
Error as TgError,
};
use thiserror::Error;
use std::{
borrow::Cow,
collections::{
BTreeMap,
HashSet,
},
num::TryFromIntError,
sync::{Arc, Mutex},
sync::{
Arc,
Mutex
},
};
lazy_static! {
static ref RE_DELAY: Regex = Regex::new(r"^Too Many Requests: retry after ([0-9]+)(,.*)?$").unwrap();
#[derive(Error, Debug)]
pub enum RssError {
#[error(transparent)]
Tg(#[from] TgError),
#[error(transparent)]
Int(#[from] TryFromIntError),
}
#[derive(Clone)]
pub struct Core {
owner_chat: telegram_bot::UserId,
pub tg: telegram_bot::Api,
pub my: telegram_bot::User,
|
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
|
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
|
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
|
where S: Into<Cow<'a, str>> {
let mode = mode.unwrap_or(telegram_bot::types::ParseMode::Html);
let target = target.unwrap_or(self.owner_chat);
self.request(telegram_bot::SendMessage::new(target, msg).parse_mode(mode)).await?;
Ok(())
}
pub async fn request<Req: telegram_bot::Request> (&self, req: Req) -> Result<<Req::Response as telegram_bot::ResponseType>::Type> {
pub async fn request<Req: telegram_bot::Request> (&self, req: Req) -> Result<<Req::Response as telegram_bot::ResponseType>::Type, RssError> {
loop {
let res = self.tg.send(&req).await;
match res {
Ok(_) => return Ok(res?),
Err(err) => {
dbg!(&err);
if let Some(caps) = RE_DELAY.captures(err.to_string().as_ref()) {
if let Some(delay) = caps.get(1) {
match &err {
TgError::Raw(TgrError::TelegramError { description: _, parameters: Some(params) }) => {
if let Some(delay) = params.retry_after {
let delay = delay.as_str().parse::<u64>()?;
println!("Throttled, waiting {} senconds.", delay);
task::sleep(std::time::Duration::from_secs(delay)).await;
} else {
println!("Throttled, waiting {} senconds.", delay);
task::sleep(std::time::Duration::from_secs(delay.try_into()?)).await;
} else {
bail!("Can't read throttling message.");
}
} else {
return Err(err.into());
return Err(err.into());
}
},
_ => return Err(err.into()),
}
},
};
}
}
pub async fn check<S>(&self, id: &i32, owner: S, real: bool) -> Result<Cow<'_, str>>
|