From c8988f5a55e52b350843cdf9f54d808b8761738d Mon Sep 17 00:00:00 2001 From: iequidoo Date: Fri, 31 Mar 2023 17:31:07 -0300 Subject: [PATCH] maybe_add_time_based_warnings(): Use release date instead of the provider DB update one (#4213) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bjoern wrote: > maybe_add_time_based_warnings() requires some date guaranteed to be in the near past. based on this known date we check if the system clock is wrong (if earlier than known date) and if the used Delta Chat version may be outdated (1 year passed since known date). while this does not catch all situations, it catches quite some errors with comparable few effort. > > figuring out the date guaranteed to be in the near past is a bit tricky. that time, we added get_provider_update_timestamp() for exactly that purpose - it is checked manually by some dev and updated from time to time, usually before a release. > > however, meanwhile, the provider-db gets updated less frequently - things might be settled a bit more - and, get_provider_update_timestamp() was also changed to return the date of the last commit, instead of last run. while that seem to be more on-purpose, we cannot even do an “empty” database update to update the known date. > > as get_provider_update_timestamp() is not used for anything else, maybe we should completely remove that function and replace it by get_last_release_timestamp that is then updated by ./scripts/set_core_version.py - the result of that is reviewed manually anyway, so that seems to be a good place (i prefer manual review here and mistrust further automation as also dev or ci clocks may be wrong :) --- CHANGELOG.md | 1 + release-date.in | 1 + scripts/create-provider-data-rs.py | 2 +- scripts/set_core_version.py | 24 +++++++++--- src/lib.rs | 1 + src/provider.rs | 25 +----------- src/provider/data.rs | 2 +- src/release.rs | 10 +++++ src/tools.rs | 62 ++++++++++++++++++------------ 9 files changed, 72 insertions(+), 56 deletions(-) create mode 100644 release-date.in create mode 100644 src/release.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f12fa4cf..470bd4af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Remove upper limit on the attachment size. #4253 - Update rPGP to 0.10.1. #4236 - Compress `mime_headers` column with HTML emails stored in database +- maybe_add_time_based_warnings(): Use release date instead of the provider DB update one ### Fixes - Fix python bindings README documentation on installing the bindings from source. diff --git a/release-date.in b/release-date.in new file mode 100644 index 000000000..5dc1be6ba --- /dev/null +++ b/release-date.in @@ -0,0 +1 @@ +2023-04-04 \ No newline at end of file diff --git a/scripts/create-provider-data-rs.py b/scripts/create-provider-data-rs.py index 57f92428e..824e3354d 100755 --- a/scripts/create-provider-data-rs.py +++ b/scripts/create-provider-data-rs.py @@ -233,7 +233,7 @@ if __name__ == "__main__": else: now = datetime.datetime.fromisoformat(sys.argv[2]) out_all += ( - "pub static PROVIDER_UPDATED: Lazy = " + "pub static _PROVIDER_UPDATED: Lazy = " "Lazy::new(|| chrono::NaiveDate::from_ymd_opt(" + str(now.year) + ", " diff --git a/scripts/set_core_version.py b/scripts/set_core_version.py index 63e3ec205..cd6303cc9 100755 --- a/scripts/set_core_version.py +++ b/scripts/set_core_version.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import datetime import json import os import pathlib @@ -91,15 +92,25 @@ def main(): ffi_toml = read_toml_version("deltachat-ffi/Cargo.toml") assert core_toml == ffi_toml, (core_toml, ffi_toml) + today = datetime.date.today().isoformat() + if "alpha" not in newversion: - for line in open("CHANGELOG.md"): + changelog_name = "CHANGELOG.md" + changelog_tmpname = changelog_name + ".tmp" + changelog_tmp = open(changelog_tmpname, "w") + found = False + for line in open(changelog_name): ## 1.25.0 - if line.startswith("## [") and line[4:].strip().startswith(newversion): - break - else: + if line == f"## [{newversion}]\n": + line = f"## [{newversion}] - {today}\n" + found = True + changelog_tmp.write(line) + if not found: raise SystemExit( - f"CHANGELOG.md contains no entry for version: {newversion}" + f"{changelog_name} contains no entry for version: {newversion}" ) + changelog_tmp.close() + os.rename(changelog_tmpname, changelog_name) for toml_filename in toml_list: replace_toml_version(toml_filename, newversion) @@ -107,6 +118,9 @@ def main(): for json_filename in json_list: update_package_json(json_filename, newversion) + with open("release-date.in", "w") as f: + f.write(today) + print("running cargo check") subprocess.call(["cargo", "check"]) diff --git a/src/lib.rs b/src/lib.rs index 51a72a1d5..0e25cdd51 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,7 @@ pub mod ephemeral; mod http; mod imap; pub mod imex; +pub mod release; mod scheduler; #[macro_use] mod job; diff --git a/src/provider.rs b/src/provider.rs index 2d37b1347..58e1cd517 100644 --- a/src/provider.rs +++ b/src/provider.rs @@ -3,12 +3,11 @@ mod data; use anyhow::Result; -use chrono::{NaiveDateTime, NaiveTime}; use trust_dns_resolver::{config, AsyncResolver, TokioAsyncResolver}; use crate::config::Config; use crate::context::Context; -use crate::provider::data::{PROVIDER_DATA, PROVIDER_IDS, PROVIDER_UPDATED}; +use crate::provider::data::{PROVIDER_DATA, PROVIDER_IDS}; /// Provider status according to manual testing. #[derive(Debug, Display, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)] @@ -258,22 +257,12 @@ pub fn get_provider_by_id(id: &str) -> Option<&'static Provider> { } } -/// Returns update timestamp as a unix timestamp compatible for comparison with time() and database times. -pub fn get_provider_update_timestamp() -> i64 { - NaiveDateTime::new(*PROVIDER_UPDATED, NaiveTime::from_hms_opt(0, 0, 0).unwrap()) - .timestamp_millis() - / 1_000 -} - #[cfg(test)] mod tests { #![allow(clippy::indexing_slicing)] - use chrono::NaiveDate; - use super::*; use crate::test_utils::TestContext; - use crate::tools::time; #[test] fn test_get_provider_by_domain_unexistant() { @@ -336,18 +325,6 @@ mod tests { ); } - #[test] - fn test_get_provider_update_timestamp() { - let timestamp_past = NaiveDateTime::new( - NaiveDate::from_ymd_opt(2020, 9, 9).unwrap(), - NaiveTime::from_hms_opt(0, 0, 0).unwrap(), - ) - .timestamp_millis() - / 1_000; - assert!(get_provider_update_timestamp() <= time()); - assert!(get_provider_update_timestamp() > timestamp_past); - } - #[test] fn test_get_resolver() -> Result<()> { assert!(get_resolver().is_ok()); diff --git a/src/provider/data.rs b/src/provider/data.rs index 8ca9d91e9..32b1ff465 100644 --- a/src/provider/data.rs +++ b/src/provider/data.rs @@ -1945,5 +1945,5 @@ pub(crate) static PROVIDER_IDS: Lazy> = ]) }); -pub static PROVIDER_UPDATED: Lazy = +pub static _PROVIDER_UPDATED: Lazy = Lazy::new(|| chrono::NaiveDate::from_ymd_opt(2023, 2, 20).unwrap()); diff --git a/src/release.rs b/src/release.rs new file mode 100644 index 000000000..0545079ec --- /dev/null +++ b/src/release.rs @@ -0,0 +1,10 @@ +//! DC release info. + +use chrono::NaiveDate; +use once_cell::sync::Lazy; + +const DATE_STR: &str = include_str!("../release-date.in"); + +/// Last release date. +pub static DATE: Lazy = + Lazy::new(|| NaiveDate::parse_from_str(DATE_STR, "%Y-%m-%d").unwrap()); diff --git a/src/tools.rs b/src/tools.rs index 7ce5eacde..71874cf83 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -13,7 +13,7 @@ use std::time::{Duration, SystemTime}; use anyhow::{bail, Context as _, Result}; use base64::Engine as _; -use chrono::{Local, TimeZone}; +use chrono::{Local, NaiveDateTime, NaiveTime, TimeZone}; use futures::{StreamExt, TryStreamExt}; use mailparse::dateparse; use mailparse::headers::Headers; @@ -26,7 +26,6 @@ use crate::constants::{DC_ELLIPSIS, DC_OUTDATED_WARNING_DAYS}; use crate::context::Context; use crate::events::EventType; use crate::message::{Message, Viewtype}; -use crate::provider::get_provider_update_timestamp; use crate::stock_str; /// Shortens a string to a specified length and adds "[...]" to the @@ -163,12 +162,23 @@ pub(crate) fn create_smeared_timestamps(context: &Context, count: usize) -> i64 context.smeared_timestamp.create_n(now, count as i64) } +/// Returns the last release timestamp as a unix timestamp compatible for comparison with time() and +/// database times. +pub fn get_release_timestamp() -> i64 { + NaiveDateTime::new( + *crate::release::DATE, + NaiveTime::from_hms_opt(0, 0, 0).unwrap(), + ) + .timestamp_millis() + / 1_000 +} + // if the system time is not plausible, once a day, add a device message. // for testing we're using time() as that is also used for message timestamps. // moreover, add a warning if the app is outdated. pub(crate) async fn maybe_add_time_based_warnings(context: &Context) { - if !maybe_warn_on_bad_time(context, time(), get_provider_update_timestamp()).await { - maybe_warn_on_outdated(context, time(), get_provider_update_timestamp()).await; + if !maybe_warn_on_bad_time(context, time(), get_release_timestamp()).await { + maybe_warn_on_outdated(context, time(), get_release_timestamp()).await; } } @@ -1140,17 +1150,17 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; / 1_000; // a correct time must not add a device message - maybe_warn_on_bad_time(&t, timestamp_now, get_provider_update_timestamp()).await; + maybe_warn_on_bad_time(&t, timestamp_now, get_release_timestamp()).await; let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap(); assert_eq!(chats.len(), 0); // we cannot find out if a date in the future is wrong - a device message is not added - maybe_warn_on_bad_time(&t, timestamp_future, get_provider_update_timestamp()).await; + maybe_warn_on_bad_time(&t, timestamp_future, get_release_timestamp()).await; let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap(); assert_eq!(chats.len(), 0); // a date in the past must add a device message - maybe_warn_on_bad_time(&t, timestamp_past, get_provider_update_timestamp()).await; + maybe_warn_on_bad_time(&t, timestamp_past, get_release_timestamp()).await; let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap(); assert_eq!(chats.len(), 1); let device_chat_id = chats.get_chat_id(0).unwrap(); @@ -1158,31 +1168,21 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; assert_eq!(msgs.len(), 1); // the message should be added only once a day - test that an hour later and nearly a day later - maybe_warn_on_bad_time( - &t, - timestamp_past + 60 * 60, - get_provider_update_timestamp(), - ) - .await; + maybe_warn_on_bad_time(&t, timestamp_past + 60 * 60, get_release_timestamp()).await; let msgs = chat::get_chat_msgs(&t, device_chat_id).await.unwrap(); assert_eq!(msgs.len(), 1); maybe_warn_on_bad_time( &t, timestamp_past + 60 * 60 * 24 - 1, - get_provider_update_timestamp(), + get_release_timestamp(), ) .await; let msgs = chat::get_chat_msgs(&t, device_chat_id).await.unwrap(); assert_eq!(msgs.len(), 1); // next day, there should be another device message - maybe_warn_on_bad_time( - &t, - timestamp_past + 60 * 60 * 24, - get_provider_update_timestamp(), - ) - .await; + maybe_warn_on_bad_time(&t, timestamp_past + 60 * 60 * 24, get_release_timestamp()).await; let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap(); assert_eq!(chats.len(), 1); assert_eq!(device_chat_id, chats.get_chat_id(0).unwrap()); @@ -1200,7 +1200,7 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; maybe_warn_on_outdated( &t, timestamp_now + 180 * 24 * 60 * 60, - get_provider_update_timestamp(), + get_release_timestamp(), ) .await; let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap(); @@ -1210,7 +1210,7 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; maybe_warn_on_outdated( &t, timestamp_now + 365 * 24 * 60 * 60, - get_provider_update_timestamp(), + get_release_timestamp(), ) .await; let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap(); @@ -1224,13 +1224,13 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; maybe_warn_on_outdated( &t, timestamp_now + (365 + 1) * 24 * 60 * 60, - get_provider_update_timestamp(), + get_release_timestamp(), ) .await; maybe_warn_on_outdated( &t, timestamp_now + (365 + 2) * 24 * 60 * 60, - get_provider_update_timestamp(), + get_release_timestamp(), ) .await; let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap(); @@ -1245,7 +1245,7 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; maybe_warn_on_outdated( &t, timestamp_now + (365 + 33) * 24 * 60 * 60, - get_provider_update_timestamp(), + get_release_timestamp(), ) .await; let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap(); @@ -1255,6 +1255,18 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; assert_eq!(msgs.len(), test_len + 1); } + #[test] + fn test_get_release_timestamp() { + let timestamp_past = NaiveDateTime::new( + NaiveDate::from_ymd_opt(2020, 9, 9).unwrap(), + NaiveTime::from_hms_opt(0, 0, 0).unwrap(), + ) + .timestamp_millis() + / 1_000; + assert!(get_release_timestamp() <= time()); + assert!(get_release_timestamp() > timestamp_past); + } + #[test] fn test_remove_subject_prefix() { assert_eq!(remove_subject_prefix("Subject"), "Subject");