diff --git a/.env.example b/.env.example index 28b0ebc..ef3935a 100644 --- a/.env.example +++ b/.env.example @@ -18,7 +18,7 @@ CRON_ARCHIVE_SHEETS=true CRON_DELETE_STALE_SHEETS=true DELETE_STALE_SHEETS_DAYS=7 CRON_DELETE_SCHEDULED_ARCHIVES=false -DELETE_SCHEDULED_ARCHIVES_NOTIFY_DAYS=14 +DELETE_SCHEDULED_ARCHIVES_CHECK_EVERY_N_DAYS=14 # observability for prometheus REPEAT_COUNT_METRICS_SECONDS=30 diff --git a/app/shared/settings.py b/app/shared/settings.py index da277f2..866b23a 100644 --- a/app/shared/settings.py +++ b/app/shared/settings.py @@ -43,7 +43,7 @@ class Settings(BaseSettings): CRON_DELETE_STALE_SHEETS: bool = False DELETE_STALE_SHEETS_DAYS: int = 14 CRON_DELETE_SCHEDULED_ARCHIVES: bool = False - DELETE_SCHEDULED_ARCHIVES_NOTIFY_DAYS: int = 14 + DELETE_SCHEDULED_ARCHIVES_CHECK_EVERY_N_DAYS: int = 7 # observability REPEAT_COUNT_METRICS_SECONDS: int = 30 diff --git a/app/web/db/crud.py b/app/web/db/crud.py index e3a78a0..25ef72b 100644 --- a/app/web/db/crud.py +++ b/app/web/db/crud.py @@ -89,7 +89,7 @@ def count_by_user_since(db: Session, seconds_delta: int = 15): .limit(500).all() -async def find_by_store_until(db: AsyncSession, store_until_is_before: datetime) -> dict: +async def find_by_store_until(db: AsyncSession, store_until_is_before: datetime) -> list[models.Archive]: res = await db.execute( select(models.Archive) .filter(models.Archive.deleted == False, models.Archive.store_until < store_until_is_before) diff --git a/app/web/events.py b/app/web/events.py index 101d055..383a210 100644 --- a/app/web/events.py +++ b/app/web/events.py @@ -89,12 +89,12 @@ async def archive_sheets_cronjob(frequency: str, interval: int, current_time_uni # TODO: on exception should logerror but also prometheus counter -DELETE_WINDOW = get_settings().DELETE_SCHEDULED_ARCHIVES_NOTIFY_DAYS * 24 * 60 * 60 +DELETE_WINDOW = get_settings().DELETE_SCHEDULED_ARCHIVES_CHECK_EVERY_N_DAYS * 24 * 60 * 60 @repeat_every(seconds=DELETE_WINDOW, wait_first=180, on_exception=logger.error) async def notify_about_expired_archives(): - notify_from = datetime.datetime.now() + datetime.timedelta(days=get_settings().DELETE_SCHEDULED_ARCHIVES_NOTIFY_DAYS) + notify_from = datetime.datetime.now() + datetime.timedelta(days=get_settings().DELETE_SCHEDULED_ARCHIVES_CHECK_EVERY_N_DAYS) async with get_db_async() as db: scheduled_deletions = await crud.find_by_store_until(db, notify_from) @@ -106,7 +106,7 @@ async def notify_about_expired_archives(): fastmail = FastMail(get_settings().MAIL_CONFIG) # notify users for email in user_archives: - list_of_archives = "\n".join([f'{a.url},{a.id}
' for a in user_archives[email]]) + list_of_archives = "\n".join([f'{a.url}, {a.id}, {a.store_until.isoformat()}
' for a in user_archives[email]]) # TODO: how can users download them in bulk? message = MessageSchema( subject="Auto Archiver: Archives Scheduled for Deletion", @@ -115,11 +115,11 @@ async def notify_about_expired_archives():

Hi {email},

-

Some of your archives will be deleted in the next {get_settings().DELETE_SCHEDULED_ARCHIVES_NOTIFY_DAYS} days, as they are reaching their expiration date according to our retention policy for their groups.

+

Some of your archives will be deleted in the next {get_settings().DELETE_SCHEDULED_ARCHIVES_CHECK_EVERY_N_DAYS} days, as they are reaching their expiration date according to our retention policy for their groups.

If you want to preserve any, make sure to download them now.

Here is a CSV list of URLs:

- url,archive_id
+ url,archive_id,time_of_deletion
{list_of_archives}

Best,
The Auto Archiver team

@@ -135,7 +135,7 @@ async def notify_about_expired_archives(): asyncio.create_task(delete_expired_archives()) -@repeat_every(max_repetitions=1, wait_first=DELETE_WINDOW - (60 * 60), seconds=0, on_exception=logger.error) +@repeat_every(max_repetitions=1, wait_first=10, seconds=0, on_exception=logger.error) async def delete_expired_archives(): async with get_db_async() as db: count_deleted = await crud.soft_delete_expired_archives(db)