Use timezones wherever possible.
Replace uses of NaiveDateTime with DateTime<Utc>. Use timezones in postman to update days correctly. Use chrono::Months to update months rather than using MySQL query.
This commit is contained in:
		
							
								
								
									
										34
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										34
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -56,9 +56,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "aho-corasick"
 | 
					name = "aho-corasick"
 | 
				
			||||||
version = "0.7.19"
 | 
					version = "0.7.20"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
 | 
					checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -225,15 +225,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "bytes"
 | 
					name = "bytes"
 | 
				
			||||||
version = "1.2.1"
 | 
					version = "1.3.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
 | 
					checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "cc"
 | 
					name = "cc"
 | 
				
			||||||
version = "1.0.76"
 | 
					version = "1.0.77"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f"
 | 
					checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "cfg-if"
 | 
					name = "cfg-if"
 | 
				
			||||||
@@ -417,9 +417,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "crossbeam-queue"
 | 
					name = "crossbeam-queue"
 | 
				
			||||||
version = "0.3.7"
 | 
					version = "0.3.8"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "ebb3d1683412e9be6a15533314f00ec223c0762c522a3f77f048b265aab4470c"
 | 
					checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "crossbeam-utils",
 | 
					 "crossbeam-utils",
 | 
				
			||||||
@@ -427,9 +427,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "crossbeam-utils"
 | 
					name = "crossbeam-utils"
 | 
				
			||||||
version = "0.8.13"
 | 
					version = "0.8.14"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa"
 | 
					checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -1911,9 +1911,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "poise"
 | 
					name = "poise"
 | 
				
			||||||
version = "0.3.0"
 | 
					version = "0.4.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "f6c01d22dcda434b0dfe956c60f6ac9b0352c4c2f4af852afb3155a971cd306d"
 | 
					checksum = "aee439543df35482730552e7c9ed0c45a5f1d521548e6c0249967c4ba8828f60"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "async-trait",
 | 
					 "async-trait",
 | 
				
			||||||
 "derivative",
 | 
					 "derivative",
 | 
				
			||||||
@@ -1930,9 +1930,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "poise_macros"
 | 
					name = "poise_macros"
 | 
				
			||||||
version = "0.3.0"
 | 
					version = "0.4.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "52ff861b6a52ec47bc54eb17424c025feeb040e82836036276c25dda045a8a0c"
 | 
					checksum = "53d21213ff7aeef5ab69729a5cddfb351a84a9bf3dadf9f470032440d43746c2"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "darling",
 | 
					 "darling",
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
@@ -2133,7 +2133,7 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "reminder_rs"
 | 
					name = "reminder_rs"
 | 
				
			||||||
version = "1.6.7"
 | 
					version = "1.6.8"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "base64",
 | 
					 "base64",
 | 
				
			||||||
 "chrono",
 | 
					 "chrono",
 | 
				
			||||||
@@ -2518,9 +2518,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde_json"
 | 
					name = "serde_json"
 | 
				
			||||||
version = "1.0.88"
 | 
					version = "1.0.89"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7"
 | 
					checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "itoa 1.0.4",
 | 
					 "itoa 1.0.4",
 | 
				
			||||||
 "ryu",
 | 
					 "ryu",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,11 @@
 | 
				
			|||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "reminder_rs"
 | 
					name = "reminder_rs"
 | 
				
			||||||
version = "1.6.8"
 | 
					version = "1.6.9"
 | 
				
			||||||
authors = ["jellywx <judesouthworth@pm.me>"]
 | 
					authors = ["jellywx <judesouthworth@pm.me>"]
 | 
				
			||||||
edition = "2018"
 | 
					edition = "2018"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
poise = "0.3"
 | 
					poise = "0.4"
 | 
				
			||||||
dotenv = "0.15"
 | 
					dotenv = "0.15"
 | 
				
			||||||
tokio = { version = "1", features = ["process", "full"] }
 | 
					tokio = { version = "1", features = ["process", "full"] }
 | 
				
			||||||
reqwest = "0.11"
 | 
					reqwest = "0.11"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
use chrono::{DateTime, Days, Duration};
 | 
					use chrono::{DateTime, Days, Duration, Months, TimeZone};
 | 
				
			||||||
use chrono_tz::Tz;
 | 
					use chrono_tz::Tz;
 | 
				
			||||||
use lazy_static::lazy_static;
 | 
					use lazy_static::lazy_static;
 | 
				
			||||||
use log::{error, info, warn};
 | 
					use log::{error, info, warn};
 | 
				
			||||||
@@ -62,18 +62,23 @@ pub fn substitute(string: &str) -> String {
 | 
				
			|||||||
        let format = caps.name("format").map(|m| m.as_str());
 | 
					        let format = caps.name("format").map(|m| m.as_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if let (Some(final_time), Some(format)) = (final_time, format) {
 | 
					        if let (Some(final_time), Some(format)) = (final_time, format) {
 | 
				
			||||||
            let dt = NaiveDateTime::from_timestamp(final_time, 0);
 | 
					            match NaiveDateTime::from_timestamp_opt(final_time, 0) {
 | 
				
			||||||
            let now = Utc::now().naive_utc();
 | 
					                Some(dt) => {
 | 
				
			||||||
 | 
					                    let now = Utc::now().naive_utc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let difference = {
 | 
					                    let difference = {
 | 
				
			||||||
                if now < dt {
 | 
					                        if now < dt {
 | 
				
			||||||
                    dt - Utc::now().naive_utc()
 | 
					                            dt - Utc::now().naive_utc()
 | 
				
			||||||
                } else {
 | 
					                        } else {
 | 
				
			||||||
                    Utc::now().naive_utc() - dt
 | 
					                            Utc::now().naive_utc() - dt
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    fmt_displacement(format, difference.num_seconds() as u64)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fmt_displacement(format, difference.num_seconds() as u64)
 | 
					                None => String::new(),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            String::new()
 | 
					            String::new()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -243,10 +248,10 @@ pub struct Reminder {
 | 
				
			|||||||
    attachment: Option<Vec<u8>>,
 | 
					    attachment: Option<Vec<u8>>,
 | 
				
			||||||
    attachment_name: Option<String>,
 | 
					    attachment_name: Option<String>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    utc_time: NaiveDateTime,
 | 
					    utc_time: DateTime<Utc>,
 | 
				
			||||||
    timezone: String,
 | 
					    timezone: String,
 | 
				
			||||||
    restartable: bool,
 | 
					    restartable: bool,
 | 
				
			||||||
    expires: Option<NaiveDateTime>,
 | 
					    expires: Option<DateTime<Utc>>,
 | 
				
			||||||
    interval_seconds: Option<u32>,
 | 
					    interval_seconds: Option<u32>,
 | 
				
			||||||
    interval_months: Option<u32>,
 | 
					    interval_months: Option<u32>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -330,9 +335,7 @@ WHERE
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async fn reset_webhook(&self, pool: impl Executor<'_, Database = Database> + Copy) {
 | 
					    async fn reset_webhook(&self, pool: impl Executor<'_, Database = Database> + Copy) {
 | 
				
			||||||
        let _ = sqlx::query!(
 | 
					        let _ = sqlx::query!(
 | 
				
			||||||
            "
 | 
					            "UPDATE channels SET webhook_id = NULL, webhook_token = NULL WHERE channel = ?",
 | 
				
			||||||
UPDATE channels SET webhook_id = NULL, webhook_token = NULL WHERE channel = ?
 | 
					 | 
				
			||||||
            ",
 | 
					 | 
				
			||||||
            self.channel_id
 | 
					            self.channel_id
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        .execute(pool)
 | 
					        .execute(pool)
 | 
				
			||||||
@@ -341,44 +344,25 @@ UPDATE channels SET webhook_id = NULL, webhook_token = NULL WHERE channel = ?
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async fn refresh(&self, pool: impl Executor<'_, Database = Database> + Copy) {
 | 
					    async fn refresh(&self, pool: impl Executor<'_, Database = Database> + Copy) {
 | 
				
			||||||
        if self.interval_seconds.is_some() || self.interval_months.is_some() {
 | 
					        if self.interval_seconds.is_some() || self.interval_months.is_some() {
 | 
				
			||||||
            let now = Utc::now().naive_local();
 | 
					            let now = Utc::now();
 | 
				
			||||||
            let mut updated_reminder_time = self.utc_time;
 | 
					            let mut updated_reminder_time =
 | 
				
			||||||
 | 
					                self.utc_time.with_timezone(&self.timezone.parse().unwrap_or(Tz::UTC));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if let Some(interval) = self.interval_months {
 | 
					            if let Some(interval) = self.interval_months {
 | 
				
			||||||
                match sqlx::query!(
 | 
					                updated_reminder_time = updated_reminder_time
 | 
				
			||||||
                    // use the second date_add to force return value to datetime
 | 
					                    .checked_add_months(Months::new(interval))
 | 
				
			||||||
                    "SELECT DATE_ADD(DATE_ADD(?, INTERVAL ? MONTH), INTERVAL 0 SECOND) AS new_time",
 | 
					                    .unwrap_or_else(|| {
 | 
				
			||||||
                    updated_reminder_time,
 | 
					                        warn!("Could not add months to a reminder");
 | 
				
			||||||
                    interval
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                .fetch_one(pool)
 | 
					 | 
				
			||||||
                .await
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Ok(row) => match row.new_time {
 | 
					 | 
				
			||||||
                        Some(datetime) => {
 | 
					 | 
				
			||||||
                            updated_reminder_time = datetime;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        None => {
 | 
					 | 
				
			||||||
                            warn!("Could not update interval by months: got NULL");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            updated_reminder_time += Duration::days(30);
 | 
					                        updated_reminder_time
 | 
				
			||||||
                        }
 | 
					                    });
 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    Err(e) => {
 | 
					 | 
				
			||||||
                        warn!("Could not update interval by months: {:?}", e);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        // naively fallback to adding 30 days
 | 
					 | 
				
			||||||
                        updated_reminder_time += Duration::days(30);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fn increment_days(
 | 
					            fn increment_days<T: TimeZone>(
 | 
				
			||||||
                now: NaiveDateTime,
 | 
					                now: DateTime<Utc>,
 | 
				
			||||||
                mut new_time: NaiveDateTime,
 | 
					                mut new_time: DateTime<T>,
 | 
				
			||||||
                interval: u32,
 | 
					                interval: u32,
 | 
				
			||||||
            ) -> Option<NaiveDateTime> {
 | 
					            ) -> Option<DateTime<T>> {
 | 
				
			||||||
                while new_time < now {
 | 
					                while new_time < now {
 | 
				
			||||||
                    new_time = new_time.checked_add_days(Days::new((interval / 86400).into()))?;
 | 
					                    new_time = new_time.checked_add_days(Days::new((interval / 86400).into()))?;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -403,16 +387,12 @@ UPDATE channels SET webhook_id = NULL, webhook_token = NULL WHERE channel = ?
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if self.expires.map_or(false, |expires| {
 | 
					            if self.expires.map_or(false, |expires| updated_reminder_time > expires) {
 | 
				
			||||||
                NaiveDateTime::from_timestamp(updated_reminder_time.timestamp(), 0) > expires
 | 
					 | 
				
			||||||
            }) {
 | 
					 | 
				
			||||||
                self.force_delete(pool).await;
 | 
					                self.force_delete(pool).await;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                sqlx::query!(
 | 
					                sqlx::query!(
 | 
				
			||||||
                    "
 | 
					                    "UPDATE reminders SET `utc_time` = ? WHERE `id` = ?",
 | 
				
			||||||
UPDATE reminders SET `utc_time` = ? WHERE `id` = ?
 | 
					                    updated_reminder_time.with_timezone(&Utc),
 | 
				
			||||||
                    ",
 | 
					 | 
				
			||||||
                    updated_reminder_time,
 | 
					 | 
				
			||||||
                    self.id
 | 
					                    self.id
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                .execute(pool)
 | 
					                .execute(pool)
 | 
				
			||||||
@@ -425,15 +405,10 @@ UPDATE reminders SET `utc_time` = ? WHERE `id` = ?
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn force_delete(&self, pool: impl Executor<'_, Database = Database> + Copy) {
 | 
					    async fn force_delete(&self, pool: impl Executor<'_, Database = Database> + Copy) {
 | 
				
			||||||
        sqlx::query!(
 | 
					        sqlx::query!("DELETE FROM reminders WHERE `id` = ?", self.id)
 | 
				
			||||||
            "
 | 
					            .execute(pool)
 | 
				
			||||||
DELETE FROM reminders WHERE `id` = ?
 | 
					            .await
 | 
				
			||||||
            ",
 | 
					            .expect(&format!("Could not delete Reminder {}", self.id));
 | 
				
			||||||
            self.id
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        .execute(pool)
 | 
					 | 
				
			||||||
        .await
 | 
					 | 
				
			||||||
        .expect(&format!("Could not delete Reminder {}", self.id));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn pin_message<M: Into<u64>>(&self, message_id: M, http: impl AsRef<Http>) {
 | 
					    async fn pin_message<M: Into<u64>>(&self, message_id: M, http: impl AsRef<Http>) {
 | 
				
			||||||
@@ -571,9 +546,7 @@ DELETE FROM reminders WHERE `id` = ?
 | 
				
			|||||||
                    .map_or(true, |inner| inner >= Utc::now().naive_local()))
 | 
					                    .map_or(true, |inner| inner >= Utc::now().naive_local()))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            let _ = sqlx::query!(
 | 
					            let _ = sqlx::query!(
 | 
				
			||||||
                "
 | 
					                "UPDATE `channels` SET paused = 0, paused_until = NULL WHERE `channel` = ?",
 | 
				
			||||||
UPDATE `channels` SET paused = 0, paused_until = NULL WHERE `channel` = ?
 | 
					 | 
				
			||||||
                ",
 | 
					 | 
				
			||||||
                self.channel_id
 | 
					                self.channel_id
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            .execute(pool)
 | 
					            .execute(pool)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,6 @@
 | 
				
			|||||||
use std::{
 | 
					use std::{collections::HashSet, string::ToString};
 | 
				
			||||||
    collections::HashSet,
 | 
					 | 
				
			||||||
    string::ToString,
 | 
					 | 
				
			||||||
    time::{SystemTime, UNIX_EPOCH},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
use chrono::NaiveDateTime;
 | 
					use chrono::{DateTime, NaiveDateTime, Utc};
 | 
				
			||||||
use chrono_tz::Tz;
 | 
					use chrono_tz::Tz;
 | 
				
			||||||
use num_integer::Integer;
 | 
					use num_integer::Integer;
 | 
				
			||||||
use poise::{
 | 
					use poise::{
 | 
				
			||||||
@@ -60,18 +56,27 @@ pub async fn pause(
 | 
				
			|||||||
            let parsed = natural_parser(&until, &timezone.to_string()).await;
 | 
					            let parsed = natural_parser(&until, &timezone.to_string()).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if let Some(timestamp) = parsed {
 | 
					            if let Some(timestamp) = parsed {
 | 
				
			||||||
                let dt = NaiveDateTime::from_timestamp(timestamp, 0);
 | 
					                match NaiveDateTime::from_timestamp_opt(timestamp, 0) {
 | 
				
			||||||
 | 
					                    Some(dt) => {
 | 
				
			||||||
 | 
					                        channel.paused = true;
 | 
				
			||||||
 | 
					                        channel.paused_until = Some(dt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                channel.paused = true;
 | 
					                        channel.commit_changes(&ctx.data().database).await;
 | 
				
			||||||
                channel.paused_until = Some(dt);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                channel.commit_changes(&ctx.data().database).await;
 | 
					                        ctx.say(format!(
 | 
				
			||||||
 | 
					                            "Reminders in this channel have been silenced until **<t:{}:D>**",
 | 
				
			||||||
 | 
					                            timestamp
 | 
				
			||||||
 | 
					                        ))
 | 
				
			||||||
 | 
					                        .await?;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                ctx.say(format!(
 | 
					                    None => {
 | 
				
			||||||
                    "Reminders in this channel have been silenced until **<t:{}:D>**",
 | 
					                        ctx.say(format!(
 | 
				
			||||||
                    timestamp
 | 
					                            "Time processed could not be interpreted as `DateTime`. Please write the time as clearly as possible",
 | 
				
			||||||
                ))
 | 
					                        ))
 | 
				
			||||||
                .await?;
 | 
					                        .await?;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                ctx.say(
 | 
					                ctx.say(
 | 
				
			||||||
                    "Time could not be processed. Please write the time as clearly as possible",
 | 
					                    "Time could not be processed. Please write the time as clearly as possible",
 | 
				
			||||||
@@ -432,11 +437,8 @@ pub fn show_delete_page(reminders: &[Reminder], page: usize, timezone: Tz) -> Cr
 | 
				
			|||||||
    reply
 | 
					    reply
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn time_difference(start_time: NaiveDateTime) -> String {
 | 
					fn time_difference(start_time: DateTime<Utc>) -> String {
 | 
				
			||||||
    let unix_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64;
 | 
					    let delta = (Utc::now() - start_time).num_seconds();
 | 
				
			||||||
    let now = NaiveDateTime::from_timestamp(unix_time, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let delta = (now - start_time).num_seconds();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let (minutes, seconds) = delta.div_rem(&60);
 | 
					    let (minutes, seconds) = delta.div_rem(&60);
 | 
				
			||||||
    let (hours, minutes) = minutes.div_rem(&60);
 | 
					    let (hours, minutes) = minutes.div_rem(&60);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -175,17 +175,15 @@ impl<'a> MultiReminderBuilder<'a> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn time<T: Into<i64>>(mut self, time: T) -> Self {
 | 
					    pub fn time<T: Into<i64>>(mut self, time: T) -> Self {
 | 
				
			||||||
        self.utc_time = NaiveDateTime::from_timestamp(time.into(), 0);
 | 
					        if let Some(utc_time) = NaiveDateTime::from_timestamp_opt(time.into(), 0) {
 | 
				
			||||||
 | 
					            self.utc_time = utc_time;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn expires<T: Into<i64>>(mut self, time: Option<T>) -> Self {
 | 
					    pub fn expires<T: Into<i64>>(mut self, time: Option<T>) -> Self {
 | 
				
			||||||
        if let Some(t) = time {
 | 
					        self.expires = time.map(|t| NaiveDateTime::from_timestamp_opt(t.into(), 0)).flatten();
 | 
				
			||||||
            self.expires = Some(NaiveDateTime::from_timestamp(t.into(), 0));
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            self.expires = None;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ pub mod look_flags;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use std::hash::{Hash, Hasher};
 | 
					use std::hash::{Hash, Hasher};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use chrono::{NaiveDateTime, TimeZone};
 | 
					use chrono::{DateTime, NaiveDateTime, Utc};
 | 
				
			||||||
use chrono_tz::Tz;
 | 
					use chrono_tz::Tz;
 | 
				
			||||||
use poise::serenity_prelude::{
 | 
					use poise::serenity_prelude::{
 | 
				
			||||||
    model::id::{ChannelId, GuildId, UserId},
 | 
					    model::id::{ChannelId, GuildId, UserId},
 | 
				
			||||||
@@ -24,7 +24,7 @@ pub struct Reminder {
 | 
				
			|||||||
    pub id: u32,
 | 
					    pub id: u32,
 | 
				
			||||||
    pub uid: String,
 | 
					    pub uid: String,
 | 
				
			||||||
    pub channel: u64,
 | 
					    pub channel: u64,
 | 
				
			||||||
    pub utc_time: NaiveDateTime,
 | 
					    pub utc_time: DateTime<Utc>,
 | 
				
			||||||
    pub interval_seconds: Option<u32>,
 | 
					    pub interval_seconds: Option<u32>,
 | 
				
			||||||
    pub interval_months: Option<u32>,
 | 
					    pub interval_months: Option<u32>,
 | 
				
			||||||
    pub expires: Option<NaiveDateTime>,
 | 
					    pub expires: Option<NaiveDateTime>,
 | 
				
			||||||
@@ -310,16 +310,15 @@ WHERE
 | 
				
			|||||||
            count + 1,
 | 
					            count + 1,
 | 
				
			||||||
            self.display_content(),
 | 
					            self.display_content(),
 | 
				
			||||||
            self.channel,
 | 
					            self.channel,
 | 
				
			||||||
            timezone.timestamp(self.utc_time.timestamp(), 0).format("%Y-%m-%d %H:%M:%S")
 | 
					            self.utc_time.with_timezone(timezone).format("%Y-%m-%d %H:%M:%S")
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn display(&self, flags: &LookFlags, timezone: &Tz) -> String {
 | 
					    pub fn display(&self, flags: &LookFlags, timezone: &Tz) -> String {
 | 
				
			||||||
        let time_display = match flags.time_display {
 | 
					        let time_display = match flags.time_display {
 | 
				
			||||||
            TimeDisplayType::Absolute => timezone
 | 
					            TimeDisplayType::Absolute => {
 | 
				
			||||||
                .timestamp(self.utc_time.timestamp(), 0)
 | 
					                self.utc_time.with_timezone(timezone).format("%Y-%m-%d %H:%M:%S").to_string()
 | 
				
			||||||
                .format("%Y-%m-%d %H:%M:%S")
 | 
					            }
 | 
				
			||||||
                .to_string(),
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            TimeDisplayType::Relative => format!("<t:{}:R>", self.utc_time.timestamp()),
 | 
					            TimeDisplayType::Relative => format!("<t:{}:R>", self.utc_time.timestamp()),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
use chrono::NaiveDateTime;
 | 
					use chrono::{DateTime, Utc};
 | 
				
			||||||
use sqlx::MySqlPool;
 | 
					use sqlx::MySqlPool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Timer {
 | 
					pub struct Timer {
 | 
				
			||||||
    pub name: String,
 | 
					    pub name: String,
 | 
				
			||||||
    pub start_time: NaiveDateTime,
 | 
					    pub start_time: DateTime<Utc>,
 | 
				
			||||||
    pub owner: u64,
 | 
					    pub owner: u64,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user