Skip to content

Commit

Permalink
feat: set chat action as typing to wait task done
Browse files Browse the repository at this point in the history
  • Loading branch information
eatradish committed Jun 12, 2024
1 parent 03a0fc0 commit 6eb3cd6
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 75 deletions.
2 changes: 1 addition & 1 deletion server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
teloxide = { version = "0.12.2", features = ["macros"] }
timeago = { version = "0.4.2", features = ["chrono"] }
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread", "process", "sync"] }
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread", "process", "sync", "time"] }
console = "0.15.8"
buildit-utils = { path = "../buildit-utils" }
jsonwebtoken = "9.2.0"
Expand Down
216 changes: 142 additions & 74 deletions server/src/bot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,21 @@ use rand::prelude::SliceRandom;
use rand::thread_rng;
use reqwest::ClientBuilder;
use serde::{Deserialize, Serialize};
use std::{borrow::Cow, fmt::Display};
use std::{
borrow::Cow,
fmt::Display,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
time::Duration,
};
use teloxide::{
prelude::*,
types::{ChatAction, ParseMode},
utils::command::BotCommands,
};
use tokio::time::sleep;
use tracing::{warn, Instrument};

#[derive(BotCommands, Clone, Debug)]
Expand Down Expand Up @@ -61,6 +70,37 @@ pub enum Command {
Roll,
}

macro_rules! wait_with_send_typing {
($f:expr,$bot:ident,$id:expr) => {{
let task = $f;

let is_done = Arc::new(AtomicBool::new(false));
let is_done_shared = is_done.clone();
let bot_shared = $bot.clone();
tokio::spawn(async move {
loop {
if is_done_shared.load(Ordering::Relaxed) {
break;
}

bot_shared
.send_chat_action(ChatId($id), ChatAction::Typing)
.send()
.instrument(tracing::info_span!("send_chat_action"))
.await
.ok();

sleep(Duration::from_secs(5)).await;
}
});

let res = task.await;
is_done.store(true, Ordering::Relaxed);

res
}};
}

fn handle_archs_args(archs: Vec<&str>) -> Vec<&str> {
let mut archs = archs;
if archs.contains(&"mainline") {
Expand Down Expand Up @@ -123,17 +163,15 @@ async fn pipeline_new_and_report(
archs: &str,
msg: &Message,
) -> ResponseResult<()> {
match pipeline_new(
pool,
git_branch,
None,
None,
packages,
archs,
&JobSource::Telegram(msg.chat.id.0),
)
.await
{
let id = msg.chat.id.0;
let job_source = JobSource::Telegram(id);
let res = wait_with_send_typing!(
pipeline_new(pool, git_branch, None, None, packages, archs, &job_source,),
bot,
id
);

match res {
Ok(pipeline) => {
bot.send_message(
msg.chat.id,
Expand All @@ -155,6 +193,7 @@ async fn pipeline_new_and_report(
.await?;
}
}

Ok(())
}

Expand Down Expand Up @@ -266,7 +305,14 @@ async fn create_pipeline_from_pr(
msg: &Message,
bot: &Bot,
) -> ResponseResult<()> {
match pipeline_new_pr(pool, pr_number, archs, &JobSource::Telegram(msg.chat.id.0)).await {
let id = msg.chat.id.0;
let job_source = JobSource::Telegram(id);
let res = wait_with_send_typing!(
pipeline_new_pr(pool, pr_number, archs, &job_source),
bot,
id
);
match res {
Ok(pipeline) => {
bot.send_message(
msg.chat.id,
Expand Down Expand Up @@ -299,10 +345,6 @@ async fn create_pipeline_from_pr(

#[tracing::instrument(skip(bot, msg, pool))]
pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> ResponseResult<()> {
bot.send_chat_action(msg.chat.id, ChatAction::Typing)
.send()
.instrument(tracing::info_span!("send_chat_action"))
.await?;
match cmd {
Command::Help => {
bot.send_message(msg.chat.id, Command::descriptions().to_string())
Expand Down Expand Up @@ -374,20 +416,23 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
)
.await?;
}
Command::Status => match status(pool).await {
Ok(status) => {
bot.send_message(msg.chat.id, status)
.parse_mode(ParseMode::MarkdownV2)
Command::Status => {
let res = wait_with_send_typing!(status(pool), bot, msg.chat.id.0);
match res {
Ok(status) => {
bot.send_message(msg.chat.id, status)
.parse_mode(ParseMode::MarkdownV2)
.await?;
}
Err(err) => {
bot.send_message(
msg.chat.id,
truncate(&format!("Failed to get status: {:?}", err)),
)
.await?;
}
}
Err(err) => {
bot.send_message(
msg.chat.id,
truncate(&format!("Failed to get status: {:?}", err)),
)
.await?;
}
},
}
Command::OpenPR(arguments) => {
let (title, mut parts) = split_open_pr_message(&arguments);

Expand Down Expand Up @@ -472,21 +517,25 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
}
};

match buildit_utils::github::open_pr(
app_private_key,
&token,
id,
OpenPRRequest {
git_ref: parts[1].to_owned(),
abbs_path: ARGS.abbs_path.clone(),
packages: parts[2].to_owned(),
title: parts[0].to_string(),
tags: tags.clone(),
archs: archs.clone(),
},
)
.await
{
let res = wait_with_send_typing!(
buildit_utils::github::open_pr(
app_private_key,
&token,
id,
OpenPRRequest {
git_ref: parts[1].to_owned(),
abbs_path: ARGS.abbs_path.clone(),
packages: parts[2].to_owned(),
title: parts[0].to_string(),
tags: tags.clone(),
archs: archs.clone(),
},
),
bot,
msg.chat.id.0
);

match res {
Ok((_id, url)) => {
bot.send_message(msg.chat.id, format!("Successfully opened PR: {url}"))
.await?;
Expand Down Expand Up @@ -518,7 +567,8 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
.await?;
return Ok(());
} else {
let resp = login_github(&msg, arguments).await;
let resp =
wait_with_send_typing!(login_github(&msg, arguments), bot, msg.chat.id.0);

match resp {
Ok(_) => bot.send_message(msg.chat.id, "Login successful!").await?,
Expand Down Expand Up @@ -551,7 +601,9 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
};

// get topic of pr
match crab.pulls("AOSC-Dev", "aosc-os-abbs").get(pr_number).await {
let abbs = crab.pulls("AOSC-Dev", "aosc-os-abbs");
let res = wait_with_send_typing!(abbs.get(pr_number), bot, msg.chat.id.0);
match res {
Ok(pr) => match dickens::topic::report(
pr.head.ref_field.as_str(),
ARGS.local_repo.clone(),
Expand All @@ -560,11 +612,13 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
{
Ok(report) => {
// post report as github comment
match crab
.issues("AOSC-Dev", "aosc-os-abbs")
.create_comment(pr_number, report)
.await
{
let issues = crab.issues("AOSC-Dev", "aosc-os-abbs");
let res = wait_with_send_typing!(
issues.create_comment(pr_number, report),
bot,
msg.chat.id.0
);
match res {
Ok(comment) => {
bot.send_message(
msg.chat.id,
Expand Down Expand Up @@ -617,14 +671,14 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
let arch = parts[0];
let ty = parts[1];
let client = reqwest::Client::new();
match client
let request_task = client
.get(format!(
"https://aosc-packages.cth451.me/{}/{}/stable?type=json&page=all",
ty, arch
))
.send()
.await
{
.send();

match wait_with_send_typing!(request_task, bot, msg.chat.id.0) {
Ok(resp) => match resp.json::<QAResponse>().await {
Ok(qa) => {
for pkg in qa.packages {
Expand Down Expand Up @@ -668,22 +722,24 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
.await?;
}
Command::Restart(arguments) => match str::parse::<i32>(&arguments) {
Ok(job_id) => match job_restart(pool, job_id).await {
Ok(new_job) => {
bot.send_message(
msg.chat.id,
truncate(&format!("Restarted as job #{}", new_job.id)),
)
.await?;
}
Err(err) => {
bot.send_message(
msg.chat.id,
truncate(&format!("Failed to restart job: {err:?}")),
)
.await?;
Ok(job_id) => {
match wait_with_send_typing!(job_restart(pool, job_id), bot, msg.chat.id.0) {
Ok(new_job) => {
bot.send_message(
msg.chat.id,
truncate(&format!("Restarted as job #{}", new_job.id)),
)
.await?;
}
Err(err) => {
bot.send_message(
msg.chat.id,
truncate(&format!("Failed to restart job: {err:?}")),
)
.await?;
}
}
},
}
Err(err) => {
bot.send_message(msg.chat.id, truncate(&format!("Bad job ID: {err:?}")))
.await?;
Expand All @@ -708,7 +764,11 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
}
};

let token = match get_github_token(&msg.chat.id, secret).await {
let token = match wait_with_send_typing!(
get_github_token(&msg.chat.id, secret),
bot,
msg.chat.id.0
) {
Ok(s) => s.access_token,
Err(e) => {
bot.send_message(msg.chat.id, truncate(&format!("Got error: {e:?}")))
Expand All @@ -730,7 +790,11 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
}
};

let user = match get_user(pool.clone(), msg.chat.id, token.clone()).await {
let user = match wait_with_send_typing!(
get_user(pool.clone(), msg.chat.id, token.clone()),
bot,
msg.chat.id.0
) {
Ok(user) => user,
Err(err) => {
bot.send_message(
Expand All @@ -754,7 +818,11 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
}
let coauthor = coauthor_parts.join(" ");

match find_update_and_update_checksum(&package, &ARGS.abbs_path, &coauthor).await {
match wait_with_send_typing!(
find_update_and_update_checksum(&package, &ARGS.abbs_path, &coauthor),
bot,
msg.chat.id.0
) {
Ok(f) => {
match buildit_utils::github::open_pr(
app_private_key,
Expand Down Expand Up @@ -799,7 +867,7 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
}
};
}
Command::Roll => match roll().await {
Command::Roll => match wait_with_send_typing!(roll(), bot, msg.chat.id.0) {
Ok(pkgs) => {
let mut s = String::new();
for i in pkgs {
Expand Down

0 comments on commit 6eb3cd6

Please sign in to comment.