chore: Upgrade dependencies and fix lint errors
Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
parent
9100ebcb11
commit
99b3d5418d
5 changed files with 898 additions and 628 deletions
1441
Cargo.lock
generated
1441
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
18
Cargo.toml
18
Cargo.toml
|
@ -12,19 +12,19 @@ version = "0.1.0"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4.31"
|
chrono = "0.4.38"
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
grammers-client = "= 0.4.0"
|
grammers-client = "0.6.0"
|
||||||
grammers-session = "= 0.4.0"
|
grammers-session = "0.5.2"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
log = "0.4.20"
|
log = "0.4.21"
|
||||||
pretty_env_logger = "0.5.0"
|
pretty_env_logger = "0.5.0"
|
||||||
promptly = "0.3.1"
|
promptly = "0.3.1"
|
||||||
salvo = {version = "0.58.3", features = ["logging", "affix"]}
|
salvo = {version = "0.67.2", features = ["logging", "affix", "rustls"]}
|
||||||
serde = {version = "1.0.192", features = ["derive"]}
|
serde = {version = "1.0.202", features = ["derive"]}
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.117"
|
||||||
sha256 = "1.4.0"
|
sha256 = "1.5.0"
|
||||||
tokio = {version = "1.34.0", features = ["macros", "rt-multi-thread", "signal"]}
|
tokio = {version = "1.37.0", features = ["macros", "rt-multi-thread", "signal"]}
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
unsafe_code = "forbid"
|
unsafe_code = "forbid"
|
||||||
|
|
23
src/api.rs
23
src/api.rs
|
@ -18,7 +18,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use salvo::{catcher::Catcher, http::HeaderValue, hyper::header, logging::Logger, prelude::*};
|
use salvo::{catcher::Catcher, http::HeaderValue, hyper::header, logging::Logger, prelude::*};
|
||||||
|
|
||||||
use crate::PingList;
|
use crate::{superbot, PingList};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct AppState {
|
pub(crate) struct AppState {
|
||||||
|
@ -61,7 +61,7 @@ impl AppState {
|
||||||
|
|
||||||
impl<'a> MessageSchema<'a> {
|
impl<'a> MessageSchema<'a> {
|
||||||
/// Create new [`Message`] instance with `200 OK` status
|
/// Create new [`Message`] instance with `200 OK` status
|
||||||
fn new(message: &'a str) -> Self {
|
const fn new(message: &'a str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
message,
|
message,
|
||||||
status: true,
|
status: true,
|
||||||
|
@ -78,20 +78,23 @@ impl<'a> MessageSchema<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_json_body(res: &mut Response, json_body: impl serde::Serialize) {
|
fn write_json_body(res: &mut Response, json_body: impl serde::Serialize) {
|
||||||
res.write_body(serde_json::to_string(&json_body).unwrap())
|
res.write_body(serde_json::to_string(&json_body).expect("This should not fail"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[handler]
|
#[handler]
|
||||||
async fn ping(req: &Request, res: &mut Response, depot: &mut Depot) {
|
async fn ping(req: &Request, res: &mut Response, depot: &mut Depot) {
|
||||||
let bot_username = req.param::<String>("bot_username").unwrap().to_lowercase();
|
let bot_username = req
|
||||||
let app_state = depot.obtain::<Arc<AppState>>().unwrap();
|
.param::<String>("bot_username")
|
||||||
|
.expect("The path param is required");
|
||||||
|
let app_state = depot
|
||||||
|
.obtain::<Arc<AppState>>()
|
||||||
|
.expect("The app state is injected");
|
||||||
|
|
||||||
let msg = if !app_state.bots.contains(&bot_username) {
|
let msg = if !app_state.bots.contains(&bot_username) {
|
||||||
MessageSchema::new("Is not authorized to check the status of this bot")
|
MessageSchema::new("Is not authorized to check the status of this bot")
|
||||||
.code(StatusCode::BAD_REQUEST)
|
.code(StatusCode::BAD_REQUEST)
|
||||||
} else if let Ok(telegram_id) =
|
} else if let Ok(telegram_id) = superbot::send_start(&app_state.tg_client, &bot_username).await
|
||||||
crate::superbot::send_start(&app_state.tg_client, &bot_username).await
|
|
||||||
{
|
{
|
||||||
if crate::PINGED_BOTS.check(telegram_id) {
|
if crate::PINGED_BOTS.check(telegram_id) {
|
||||||
MessageSchema::new("Alive")
|
MessageSchema::new("Alive")
|
||||||
|
@ -107,7 +110,7 @@ async fn ping(req: &Request, res: &mut Response, depot: &mut Depot) {
|
||||||
|
|
||||||
#[handler]
|
#[handler]
|
||||||
async fn handle404(res: &mut Response, ctrl: &mut FlowCtrl) {
|
async fn handle404(res: &mut Response, ctrl: &mut FlowCtrl) {
|
||||||
if let Some(StatusCode::NOT_FOUND) = res.status_code {
|
if res.status_code == Some(StatusCode::NOT_FOUND) {
|
||||||
write_json_body(
|
write_json_body(
|
||||||
res,
|
res,
|
||||||
MessageSchema::new("Not Found").code(StatusCode::NOT_FOUND),
|
MessageSchema::new("Not Found").code(StatusCode::NOT_FOUND),
|
||||||
|
@ -129,7 +132,9 @@ async fn handle_server_errors(res: &mut Response, ctrl: &mut FlowCtrl) {
|
||||||
|
|
||||||
#[handler]
|
#[handler]
|
||||||
async fn auth(req: &Request, res: &mut Response, depot: &mut Depot, ctrl: &mut FlowCtrl) {
|
async fn auth(req: &Request, res: &mut Response, depot: &mut Depot, ctrl: &mut FlowCtrl) {
|
||||||
let app_state = depot.obtain::<Arc<AppState>>().unwrap();
|
let app_state = depot
|
||||||
|
.obtain::<Arc<AppState>>()
|
||||||
|
.expect("The app state is injected");
|
||||||
log::info!("New auth request");
|
log::info!("New auth request");
|
||||||
if let Some(token) = req.headers().get("Authorization") {
|
if let Some(token) = req.headers().get("Authorization") {
|
||||||
if let Ok(token) = token.to_str() {
|
if let Ok(token) = token.to_str() {
|
||||||
|
|
35
src/main.rs
35
src/main.rs
|
@ -14,10 +14,12 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0>.
|
||||||
|
|
||||||
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
use std::{env, fs, sync::Mutex};
|
use std::{env, fs, sync::Mutex};
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use salvo::Listener;
|
use salvo::{conn::TcpListener, Listener};
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
mod superbot;
|
mod superbot;
|
||||||
|
@ -40,7 +42,9 @@ impl PingList for Mutex<Vec<PingedBot>> {
|
||||||
fn clear_outdead(&self) {
|
fn clear_outdead(&self) {
|
||||||
log::info!("Clear the dead pings");
|
log::info!("Clear the dead pings");
|
||||||
let dead_time = chrono::Utc::now().timestamp() - 60;
|
let dead_time = chrono::Utc::now().timestamp() - 60;
|
||||||
let mut bots = self.lock().unwrap();
|
let mut bots = self
|
||||||
|
.lock()
|
||||||
|
.expect("Another holder paniced while holding the lock");
|
||||||
*bots = bots
|
*bots = bots
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|b| b.ping_in > dead_time)
|
.filter(|b| b.ping_in > dead_time)
|
||||||
|
@ -50,7 +54,9 @@ impl PingList for Mutex<Vec<PingedBot>> {
|
||||||
|
|
||||||
fn add_new(&self, telegram_id: u64) {
|
fn add_new(&self, telegram_id: u64) {
|
||||||
log::debug!("Adding new bot to the list: {telegram_id}");
|
log::debug!("Adding new bot to the list: {telegram_id}");
|
||||||
self.lock().unwrap().push(PingedBot::new(telegram_id));
|
self.lock()
|
||||||
|
.expect("Another holder paniced while holding the lock")
|
||||||
|
.push(PingedBot::new(telegram_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check(&self, telegram_id: u64) -> bool {
|
fn check(&self, telegram_id: u64) -> bool {
|
||||||
|
@ -58,7 +64,7 @@ impl PingList for Mutex<Vec<PingedBot>> {
|
||||||
self.clear_outdead();
|
self.clear_outdead();
|
||||||
let result = self
|
let result = self
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.expect("Another holder paniced while holding the lock")
|
||||||
.iter()
|
.iter()
|
||||||
.any(|b| b.telegram_id == telegram_id && b.is_response);
|
.any(|b| b.telegram_id == telegram_id && b.is_response);
|
||||||
log::debug!("Response status: {result}");
|
log::debug!("Response status: {result}");
|
||||||
|
@ -67,7 +73,9 @@ impl PingList for Mutex<Vec<PingedBot>> {
|
||||||
|
|
||||||
fn new_res(&self, telegram_id: u64) {
|
fn new_res(&self, telegram_id: u64) {
|
||||||
log::debug!("New res from: {telegram_id}");
|
log::debug!("New res from: {telegram_id}");
|
||||||
let mut bots = self.lock().unwrap();
|
let mut bots = self
|
||||||
|
.lock()
|
||||||
|
.expect("Another holder paniced while holding the lock");
|
||||||
*bots = bots
|
*bots = bots
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -92,12 +100,13 @@ impl PingedBot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_res(mut self) -> Self {
|
pub(crate) const fn new_res(mut self) -> Self {
|
||||||
self.is_response = true;
|
self.is_response = true;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::absolute_paths)]
|
||||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -147,21 +156,11 @@ async fn main() -> Result<()> {
|
||||||
let app_state = api::AppState::new(bots, tokens, client.clone());
|
let app_state = api::AppState::new(bots, tokens, client.clone());
|
||||||
|
|
||||||
let handler_client = client.clone();
|
let handler_client = client.clone();
|
||||||
let acceptor = salvo::conn::TcpListener::new(format!("{host}:{port}"))
|
let acceptor = TcpListener::new(format!("{host}:{port}")).bind().await;
|
||||||
.bind()
|
|
||||||
.await;
|
|
||||||
let client_handler = tokio::spawn(async move { superbot::handler(handler_client).await });
|
let client_handler = tokio::spawn(async move { superbot::handler(handler_client).await });
|
||||||
let server_handler = tokio::spawn(async move {
|
let server_handler = tokio::spawn(async move {
|
||||||
salvo::Server::new(acceptor)
|
salvo::Server::new(acceptor)
|
||||||
.serve_with_graceful_shutdown(
|
.serve(api::service(app_state))
|
||||||
api::service(app_state),
|
|
||||||
async {
|
|
||||||
tokio::signal::ctrl_c()
|
|
||||||
.await
|
|
||||||
.expect("Faild to listen to ctrl_c event");
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
use grammers_client::{Client, Config, InitParams, SignInError, Update};
|
use grammers_client::{Client, Config, InitParams, SignInError, Update};
|
||||||
use grammers_session::Session;
|
use grammers_session::Session;
|
||||||
|
use tokio::{signal, time};
|
||||||
|
|
||||||
use crate::PingList;
|
use crate::PingList;
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ pub(crate) async fn login(api_hash: String, api_id: i32) -> crate::Result<(Clien
|
||||||
if !client.is_authorized().await? {
|
if !client.is_authorized().await? {
|
||||||
println!("Signing in...");
|
println!("Signing in...");
|
||||||
let phone: String = promptly::prompt("Enter your phone number (international format)")?;
|
let phone: String = promptly::prompt("Enter your phone number (international format)")?;
|
||||||
let token = client.request_login_code(&phone, api_id, &api_hash).await?;
|
let token = client.request_login_code(&phone).await?;
|
||||||
let code: String = promptly::prompt("Enter the code you received")?;
|
let code: String = promptly::prompt("Enter the code you received")?;
|
||||||
let signed_in = client.sign_in(&token, &code).await;
|
let signed_in = client.sign_in(&token, &code).await;
|
||||||
match signed_in {
|
match signed_in {
|
||||||
|
@ -47,7 +48,7 @@ pub(crate) async fn login(api_hash: String, api_id: i32) -> crate::Result<(Clien
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => panic!("{e}"),
|
Err(e) => return Err(e.into()),
|
||||||
}
|
}
|
||||||
let me = client.get_me().await?;
|
let me = client.get_me().await?;
|
||||||
println!(
|
println!(
|
||||||
|
@ -82,7 +83,7 @@ fn update_handler(upd: Update) {
|
||||||
pub(crate) async fn handler(client: Client) {
|
pub(crate) async fn handler(client: Client) {
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = tokio::signal::ctrl_c() => {
|
_ = signal::ctrl_c() => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(Some(update)) = client.next_update() => {
|
Ok(Some(update)) = client.next_update() => {
|
||||||
|
@ -101,7 +102,7 @@ pub(crate) async fn send_start(client: &Client, bot_username: &str) -> crate::Re
|
||||||
crate::PINGED_BOTS.add_new(telegram_id);
|
crate::PINGED_BOTS.add_new(telegram_id);
|
||||||
client.send_message(chat, "/start").await?;
|
client.send_message(chat, "/start").await?;
|
||||||
// Sleep, wating the response
|
// Sleep, wating the response
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
|
time::sleep(time::Duration::from_secs(2)).await;
|
||||||
Ok(telegram_id)
|
Ok(telegram_id)
|
||||||
} else {
|
} else {
|
||||||
Err(format!("Invalid username `{bot_username}`").into())
|
Err(format!("Invalid username `{bot_username}`").into())
|
||||||
|
|
Loading…
Reference in a new issue