Compare commits
No commits in common. "bd8a224797fd4556e85ba3468a301a70e79db6cb" and "2b5e114926fec8fe96a568804818a5debbd7b977" have entirely different histories.
bd8a224797
...
2b5e114926
10 changed files with 47 additions and 360 deletions
68
Cargo.lock
generated
68
Cargo.lock
generated
|
@ -11,8 +11,6 @@ dependencies = [
|
|||
"dotenvy",
|
||||
"log",
|
||||
"pretty_env_logger",
|
||||
"rand",
|
||||
"regex",
|
||||
"teloxide",
|
||||
"tokio",
|
||||
]
|
||||
|
@ -115,12 +113,6 @@ version = "3.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.8.0"
|
||||
|
@ -1121,15 +1113,6 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_env_logger"
|
||||
version = "0.5.0"
|
||||
|
@ -1182,36 +1165,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rc-box"
|
||||
version = "1.2.0"
|
||||
|
@ -2194,27 +2147,6 @@ dependencies = [
|
|||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.4"
|
||||
|
|
|
@ -11,10 +11,3 @@ tokio = { version = "1.8", features = ["rt-multi-thread", "macros"] }
|
|||
diesel = { version = "2.2.4", features = ["sqlite"] }
|
||||
chrono = "0.4.38"
|
||||
dotenvy = "0.15.7"
|
||||
rand = "0.8.5"
|
||||
regex = "1.11.1"
|
||||
|
||||
[profile.release]
|
||||
debug = false
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# ApollousaBot
|
||||
|
||||
A Telegram bot to remind members in Posthuman-Community to take breaks and exercise.
|
100
db_helper.py
100
db_helper.py
|
@ -1,100 +0,0 @@
|
|||
import sqlite3
|
||||
|
||||
conn = sqlite3.connect("database.db")
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS quotes (
|
||||
ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
msg TEXT NOT NULL
|
||||
)
|
||||
""")
|
||||
|
||||
messages = [
|
||||
"自然が呼んでいる、外に出て歩こう!🌿",
|
||||
"椅子は動けないけど、あなたは動ける!立ってストレッチ!🚀",
|
||||
"宠猫喊你起身活动,来吧喵 🐱",
|
||||
"Your pet cat says it’s time to move, meow! 🐱",
|
||||
"ネコが「動く時間だよ」、ニャー!🐱",
|
||||
"锻炼身体,心情也会变好哦! 🌞",
|
||||
"Exercise your body, uplift your mood! 🌈",
|
||||
"体を動かして、気分もスッキリ!🌞",
|
||||
"别只是动动手指,起来扭扭腰吧! 💃",
|
||||
"Don't only move your fingers, get up and wiggle your waist! 💃",
|
||||
"指だけ動かさないで、腰を振ろう!💃",
|
||||
"起身运动一下,犒劳自己一片小饼干! 🍪",
|
||||
"Move around and reward yourself with a cookie! 🍪",
|
||||
"動いたら、クッキーを自分にご褒美!🍪",
|
||||
"再多努力五分钟,然后起来活动一下吧! ✊",
|
||||
"Work hard for another five minutes, then get up and move! ✊",
|
||||
"あと 5 分頑張って、そして動こう!✊",
|
||||
"用挤牙膏的劲去运动,身体会感谢你! 🏋️",
|
||||
"Squeeze in some exercise like you squeeze toothpaste, your body will thank you! 🏋️",
|
||||
"歯磨き粉を絞るように運動して、体が感謝してくれるよ!🏋️",
|
||||
"会健身的椅子才是好椅子!让你的动起来! 🪑",
|
||||
"A good chair gets some exercise too! Let's move yours! 🪑",
|
||||
"健康な椅子は運動する椅子だ!動かそう!🪑",
|
||||
"保持健康,今天走一万步啦! 💪",
|
||||
"Keep fit, hit 10,000 steps today! 💪",
|
||||
"健康を保つために、今日は 1 万歩歩こう!👟",
|
||||
"左脚,右脚,一步两步,动起来! 🚶",
|
||||
"Left foot, right foot, one two step, let's move! 🚶♀️",
|
||||
"左右の足、一歩二歩、動こう!🚶",
|
||||
"玩个小游戏,站起来跳十次! 🎮",
|
||||
"Play a little game, jump up ten times! 🎮",
|
||||
"ゲームしよう、10 回ジャンプ!🎮",
|
||||
"起来动一动,心情棒棒哒! 🌟",
|
||||
"Get up and move, feel super awesome! 🌟",
|
||||
"立ち上がって動くと、気分が最高!✨",
|
||||
"给自己来个 “动感时刻” 吧! 🕺",
|
||||
"自分に「動の時間」を贈ろう!🕺",
|
||||
"收拾收拾,活动一下筋骨! 🚶",
|
||||
"Tidy up and stretch your muscles! 🚶♂️",
|
||||
"身の回りを整理して、筋肉を伸ばそう!🧹",
|
||||
"休息片刻,能量满满! ✨",
|
||||
"Take a break, feel energized! ✨",
|
||||
"休憩して、エネルギーを補充しよう!🔋",
|
||||
"运动一下,神清气爽! 🌿",
|
||||
"A quick workout, clear mind! 🌿",
|
||||
"少し運動して、頭をリフレッシュ!🍃",
|
||||
"每天一小步,健康一大步! 🤸",
|
||||
"A little step each day, a big leap to health! 🤸",
|
||||
"毎日少し動いて、大きな健康を得よう!🏃♂️",
|
||||
"起身喝口水,再散步五分钟! 🚶",
|
||||
"Stand up, have a sip of water, and take a five-minute walk! 🚶♀️",
|
||||
"立ち上がって水を飲んで、5 分歩こう!🚶♂️",
|
||||
"时间到!该起来动动啦! ⏰",
|
||||
"Time's up! Get up and move around! ⏰",
|
||||
"時間だよ!立ち上がって動こう!⏳",
|
||||
"只需几步,就能解锁健康! 🚶",
|
||||
"Just a few steps to unlock health! 🚶♀️",
|
||||
"健康へのカギは、数歩歩くだけ!🔑",
|
||||
"活动一下,用笑容迎接每一天! 😊",
|
||||
"Move around, greet each day with a smile! 😊",
|
||||
"動いて、毎日を笑顔で迎えよう!😊",
|
||||
"别让自己 “长在” 椅子上,起来动动吧! 🌟",
|
||||
"椅子に「根を張らない」ように、立ち上がって動こう!🌿",
|
||||
"让你的小腿跑一跑,充电完毕!⚡",
|
||||
"Let your legs run a bit, recharge complete! ⚡",
|
||||
"少し足を動かして、充電完了!⚡",
|
||||
"记得活动哦!短暂休息,长久健康! 🚶",
|
||||
"Don't forget to move! Short breaks, long health! 🚶♂️",
|
||||
"動くのを忘れないで!短い休憩、長い健康!🚶♀️",
|
||||
"起身摇摆,工作更自在! 💃",
|
||||
"Stand up and sway, work feels like play! 💃",
|
||||
"立ち上がって揺れよう、仕事が楽しくなるよ!💃 ",
|
||||
"久坐不好,起来活动活动吧! 🚶",
|
||||
"记得起身活动活动,松松背拉拉筋。😊",
|
||||
]
|
||||
|
||||
|
||||
for idx, msg in enumerate(messages, start=1):
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO quotes (ID, msg) VALUES (?, ?)
|
||||
""",
|
||||
(idx, msg),
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
|
@ -2,7 +2,6 @@ use crate::{
|
|||
bot::commands::Command,
|
||||
db::action::{clear_reminder_time, set_reminder_time, set_user_timezone},
|
||||
};
|
||||
use regex::Regex;
|
||||
use teloxide::{adaptors::DefaultParseMode, prelude::*, utils::html};
|
||||
|
||||
use chrono::naive::NaiveTime;
|
||||
|
@ -21,7 +20,7 @@ pub async fn reply(bot: Bot, msg: Message, command: Command) -> ResponseResult<(
|
|||
Command::Help => {
|
||||
bot.send_message(
|
||||
msg.chat.id,
|
||||
format!("Hi, {mentioned_user}, Welcome to the Exercise Reminder Bot! 😉\n\nPlease use <code>/settime HH:MM</code> to set the reminder time. And use <code>/settimezone +01:00</code> <b>(according to your location)</b> to accurate the reminder.\n\nIf you are not sure your timezone, please check this <a href=\"https://en.wikipedia.org/wiki/List_of_UTC_offsets\">page</a>.\n\n<b>Please <code>settime</code> first before <code>settimezone</code></b>.",
|
||||
format!("Hi, {mentioned_user}, Welcome to the Exercise Reminder Bot! 😉\n\nPlease use <code>/settime HH:MM</code> to set the reminder time.\n\nAnd use <code>/settimezone +01:00</code> <b>(according to your location)</b> to accurate the reminder.\n\nIf you are not sure your timezone, please check this <a href=\"https://en.wikipedia.org/wiki/List_of_UTC_offsets\">page</a>.",
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
|
@ -55,28 +54,14 @@ pub async fn reply(bot: Bot, msg: Message, command: Command) -> ResponseResult<(
|
|||
}
|
||||
}
|
||||
Command::SetTimezone(timezone) => {
|
||||
let tz_pattern =
|
||||
Regex::new(r"^(\+|-)\d{2}:\d{2}$").expect("Failed to initialize regex pattern");
|
||||
|
||||
match tz_pattern.is_match(&timezone) {
|
||||
true => {
|
||||
set_user_timezone(conn, user_id, msg.chat.id, &username, timezone.as_str());
|
||||
bot.send_message(
|
||||
msg.chat.id,
|
||||
format!(
|
||||
"Hi, {mentioned_user}, your timezone is set to <code>UTC{timezone}</code>."
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
false => {
|
||||
bot.send_message(
|
||||
msg.chat.id,
|
||||
"Invalid timezone format. Please use the format <code>±HH:MM</code>.",
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
set_user_timezone(conn, user_id, msg.chat.id, timezone.as_str());
|
||||
bot.send_message(
|
||||
msg.chat.id,
|
||||
format!(
|
||||
"Hi, {mentioned_user}, your timezone is set to <code>UTC{timezone}</code>."
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Command::Stop => {
|
||||
clear_reminder_time(conn, msg.chat.id, user_id);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::db::schema::quotes::dsl::*;
|
||||
use crate::db::schema::users::dsl::*;
|
||||
use diesel::prelude::*;
|
||||
use teloxide::types::{ChatId, UserId};
|
||||
|
@ -12,10 +11,6 @@ pub fn set_reminder_time(
|
|||
_username: &str,
|
||||
time: &str,
|
||||
) {
|
||||
println!(
|
||||
"set_reminder_time -> UserId: {}, ChatId: {}, Username: {}, Time: {}",
|
||||
_user_id.0, _chat_id.0, _username, time
|
||||
);
|
||||
diesel::insert_into(users)
|
||||
.values((
|
||||
chat_id.eq(_chat_id.0),
|
||||
|
@ -23,7 +18,7 @@ pub fn set_reminder_time(
|
|||
username.eq(_username),
|
||||
reminder_time.eq(time),
|
||||
))
|
||||
.on_conflict((chat_id, user_id))
|
||||
.on_conflict(chat_id)
|
||||
.do_update()
|
||||
.set(reminder_time.eq(time))
|
||||
.execute(conn)
|
||||
|
@ -34,46 +29,22 @@ pub fn set_user_timezone(
|
|||
conn: &mut SqliteConnection,
|
||||
_user_id: UserId,
|
||||
_chat_id: ChatId,
|
||||
_username: &str,
|
||||
_user_timezone: &str,
|
||||
) {
|
||||
println!(
|
||||
"set_user_timezone -> UserId: {}, ChatId: {}, Username: {}, UserTimezone: {}",
|
||||
_user_id.0, _chat_id.0, _username, _user_timezone
|
||||
"UserId: {}, ChatId: {}, UserTimezone: {}",
|
||||
_user_id.0, _chat_id.0, _user_timezone
|
||||
);
|
||||
let user_exists = users
|
||||
.filter(
|
||||
diesel::update(
|
||||
users.filter(
|
||||
chat_id
|
||||
.eq(_chat_id.0)
|
||||
.and(user_id.eq(i64::try_from(_user_id.0).unwrap())),
|
||||
)
|
||||
.select((chat_id, user_id))
|
||||
.first::<(i64, i64)>(conn)
|
||||
.optional()
|
||||
.expect("Error checking if user exists");
|
||||
|
||||
if user_exists.is_some() {
|
||||
diesel::update(
|
||||
users.filter(
|
||||
chat_id
|
||||
.eq(_chat_id.0)
|
||||
.and(user_id.eq(i64::try_from(_user_id.0).unwrap())),
|
||||
),
|
||||
)
|
||||
.set(tz_offset.eq(_user_timezone))
|
||||
.execute(conn)
|
||||
.expect("Error updating user timezone");
|
||||
} else {
|
||||
diesel::insert_into(users)
|
||||
.values((
|
||||
chat_id.eq(_chat_id.0),
|
||||
user_id.eq(i64::try_from(_user_id.0).unwrap()),
|
||||
username.eq(_username),
|
||||
tz_offset.eq(_user_timezone),
|
||||
))
|
||||
.execute(conn)
|
||||
.expect("Error inserting new user with timezone");
|
||||
}
|
||||
),
|
||||
)
|
||||
.set(tz_offset.eq(_user_timezone))
|
||||
.execute(conn)
|
||||
.expect("Error update user timezone");
|
||||
}
|
||||
|
||||
pub fn clear_reminder_time(conn: &mut SqliteConnection, _chat_id: ChatId, _user_id: UserId) {
|
||||
|
@ -89,17 +60,5 @@ pub fn clear_reminder_time(conn: &mut SqliteConnection, _chat_id: ChatId, _user_
|
|||
}
|
||||
|
||||
pub fn get_user_reminders(conn: &mut SqliteConnection) -> Vec<Users> {
|
||||
// Only work for group members
|
||||
users
|
||||
.select((chat_id, user_id, username, reminder_time, tz_offset))
|
||||
.filter(chat_id.ne(user_id))
|
||||
.load::<Users>(conn)
|
||||
.expect("Error loading user")
|
||||
}
|
||||
|
||||
pub fn get_quotes(conn: &mut SqliteConnection) -> Vec<String> {
|
||||
quotes
|
||||
.select(msg)
|
||||
.load::<String>(conn)
|
||||
.expect("Error loading Quotes")
|
||||
users.load::<Users>(conn).expect("Error loading user")
|
||||
}
|
||||
|
|
|
@ -1,23 +1,13 @@
|
|||
use crate::db::schema::{quotes, users};
|
||||
use crate::db::schema::users;
|
||||
use diesel::prelude::*;
|
||||
|
||||
#[derive(Debug, Queryable, Selectable, QueryableByName, Insertable)]
|
||||
#[derive(Queryable, Selectable)]
|
||||
#[diesel(table_name = users)]
|
||||
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
||||
pub struct Users {
|
||||
pub chat_id: i64,
|
||||
pub user_id: i64,
|
||||
pub username: String,
|
||||
pub reminder_time: Option<String>,
|
||||
pub reminder_time: String,
|
||||
pub tz_offset: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Selectable)]
|
||||
#[diesel(table_name = quotes)]
|
||||
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
||||
pub struct Quotes {
|
||||
#[allow(dead_code)]
|
||||
pub id: i32,
|
||||
#[allow(dead_code)]
|
||||
pub msg: String,
|
||||
}
|
||||
|
|
|
@ -1,23 +1,11 @@
|
|||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
quotes (id) {
|
||||
id -> Integer,
|
||||
msg -> Text,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
users (chat_id, user_id) {
|
||||
users (chat_id) {
|
||||
chat_id -> BigInt,
|
||||
user_id -> BigInt,
|
||||
username -> Text,
|
||||
reminder_time -> Text,
|
||||
tz_offset -> Nullable<Text>,
|
||||
reminder_time -> Nullable<Text>,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
quotes,
|
||||
users,
|
||||
);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::db::action as operator;
|
||||
use crate::db::model::Users;
|
||||
use crate::utils::{get_random_quote, TimezoneOffest};
|
||||
use crate::utils::TimezoneOffest;
|
||||
use chrono::{FixedOffset, Utc};
|
||||
use teloxide::adaptors::DefaultParseMode;
|
||||
use teloxide::prelude::*;
|
||||
|
@ -13,52 +12,32 @@ use crate::db::establish_connection;
|
|||
|
||||
type Bot = DefaultParseMode<teloxide::Bot>;
|
||||
|
||||
async fn handle_user_reminder(
|
||||
user: &Users,
|
||||
bot: &Arc<Bot>,
|
||||
selected_quote: &str,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let tzoffset = user.tz_offset.as_ref().ok_or(format!(
|
||||
"User {} does not have a timezone offset set.",
|
||||
user.username
|
||||
))?;
|
||||
let user_timezone = tzoffset
|
||||
.parse::<TimezoneOffest>()
|
||||
.map_err(|e| format!("Failed to parse timezone offset: {}", e))?;
|
||||
let duration_secs = user_timezone.to_duration();
|
||||
let user_utc_time = FixedOffset::east_opt(duration_secs).map_or(
|
||||
"Invalid timezone offset".to_string(),
|
||||
|offset| {
|
||||
Utc::now()
|
||||
.with_timezone(&offset)
|
||||
.format("%H:%M")
|
||||
.to_string()
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(reminder) = &user.reminder_time {
|
||||
if user_utc_time == *reminder {
|
||||
let _user_id = UserId(u64::try_from(user.user_id)?);
|
||||
let mentioned_user = html::user_mention(_user_id, &user.username);
|
||||
let notification = format!("{mentioned_user} {selected_quote}");
|
||||
bot.send_message(ChatId(user.chat_id), notification).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn schedule_reminders(bot: &Arc<Bot>) {
|
||||
let conn = &mut establish_connection();
|
||||
let users_to_remind = operator::get_user_reminders(conn);
|
||||
|
||||
let all_quotes = operator::get_quotes(conn);
|
||||
let selected_quote =
|
||||
get_random_quote(&all_quotes).unwrap_or("记得起身活动活动,松松背拉拉筋。");
|
||||
|
||||
for user in users_to_remind {
|
||||
if let Err(e) = handle_user_reminder(&user, bot, selected_quote).await {
|
||||
eprintln!("Error handling reminder for user {}: {}", user.username, e);
|
||||
if let Some(tzoffset) = user.tz_offset.as_ref() {
|
||||
let user_timezone: TimezoneOffest = tzoffset.parse().unwrap();
|
||||
|
||||
let duration_secs = user_timezone.to_duration();
|
||||
let user_utc_time = Utc::now()
|
||||
.with_timezone(&FixedOffset::east_opt(duration_secs).unwrap())
|
||||
.format("%H:%M")
|
||||
.to_string();
|
||||
|
||||
// println!("User UTC time: {}", user_utc_time);
|
||||
|
||||
if user_utc_time == user.reminder_time {
|
||||
// println!("{}: {}", user.reminder_time, user.username);
|
||||
let _user_id = UserId(u64::try_from(user.user_id).unwrap());
|
||||
let _username = user.username;
|
||||
let mentioned_user = html::user_mention(_user_id, &_username);
|
||||
let notification = format!("{mentioned_user},记得起身活动活动,松松背拉拉筋。");
|
||||
bot.send_message(ChatId(user.chat_id), notification)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
36
src/utils.rs
36
src/utils.rs
|
@ -1,5 +1,3 @@
|
|||
use rand::Rng;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct TimezoneOffest {
|
||||
offset_hours: i32,
|
||||
|
@ -49,19 +47,6 @@ impl TimezoneOffest {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_random_quote(quotes: &[String]) -> Option<&str> {
|
||||
if !quotes.is_empty() {
|
||||
let length = quotes.len();
|
||||
let mut rng = rand::thread_rng();
|
||||
let random_index = rng.gen_range(0..length);
|
||||
let random_quote = "es[random_index];
|
||||
|
||||
Some(random_quote)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
|
@ -102,25 +87,4 @@ mod tests {
|
|||
let ew_offset = Utc::now().with_timezone(&FixedOffset::east_opt(duration).unwrap());
|
||||
println!("UTC+8:00 -> {}", ew_offset);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_random_quote() {
|
||||
let quotes = vec![
|
||||
String::from("wwww"),
|
||||
String::from("vvvv"),
|
||||
String::from("xxxx"),
|
||||
];
|
||||
|
||||
let random_quote = get_random_quote("es);
|
||||
assert!(random_quote.is_some());
|
||||
|
||||
if let Some(quote) = random_quote {
|
||||
println!("{quote}");
|
||||
}
|
||||
|
||||
let empty_quotes: Vec<String> = vec![];
|
||||
|
||||
let random_quote = get_random_quote(&empty_quotes);
|
||||
assert!(random_quote.is_none());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue