FEAT: add auto clear env variable

This commit is contained in:
arabcoders 2025-11-11 22:08:32 +03:00
parent 28207bcd41
commit 4e86729206
5 changed files with 66 additions and 3 deletions

7
FAQ.md
View file

@ -47,6 +47,7 @@ or the `environment:` section in `compose.yaml` file.
| YTP_ALLOW_INTERNAL_URLS | Allow requests to internal URLs | `false` |
| YTP_SIMPLE_MODE | Switch default interface to Simple mode. | `false` |
| YTP_STATIC_UI_PATH | Path to custom static UI files. | `(not_set)` |
| YTP_AUTO_CLEAR_HISTORY_DAYS | Number of days after which completed download history is cleared. | `0` |
> [!NOTE]
> To raise the maximum workers for specific extractor, you need to add a ENV variable that follows the pattern `YTP_MAX_WORKERS_FOR_<EXTRACTOR_NAME>`.
@ -54,8 +55,12 @@ or the `environment:` section in `compose.yaml` file.
> The limit should not exceed the `YTP_MAX_WORKERS` value as it will be ignored.
> [!IMPORTANT]
> The env variable `YTP_SIMPLE_MODE` only control what being displayed for first time visitor, the users can still switch between the two modes via the WebUI settings page.
> The env variable `YTP_SIMPLE_MODE` only control what being displayed for first time visitor, the users can still switch between the two modes via the WebUI settings page.
## Notes about YTP_AUTO_CLEAR_HISTORY_DAYS
- `0` days means no automatic clearing of the download history. lowest value that will trigger the clearing is `1` day.
- This setting will **NOT** delete the downloaded files, it will only clear the history from the database.
# Browser extensions & bookmarklets

View file

@ -140,6 +140,15 @@ class DownloadQueue(metaclass=Singleton):
func=self._check_live,
id=f"{__class__.__name__}.{__class__._check_live.__name__}",
)
if self.config.auto_clear_history_days > 0:
Scheduler.get_instance().add(
# timer="8 */1 * * *",
timer="* * * * *",
func=self._delete_old_history,
id=f"{__class__.__name__}.{__class__._delete_old_history.__name__}",
)
# app.on_shutdown.append(self.on_shutdown)
async def test(self) -> bool:
@ -1262,6 +1271,48 @@ class DownloadQueue(metaclass=Singleton):
LOG.exception(e)
LOG.error(f"Failed to retry item '{item_ref}'. {e!s}")
async def _delete_old_history(self) -> None:
"""
Automatically delete old download history based on user specified days.
0 or negative value disables this feature.
"""
if self.config.auto_clear_history_days < 0 or self.is_paused() or self.done.empty():
return
cutoff_date: datetime = datetime.now(UTC) - timedelta(days=self.config.auto_clear_history_days)
items_to_delete: list[tuple[str, ItemDTO]] = []
for key, download in self.done.items():
info: ItemDTO = download.info
if not info or not info.timestamp:
continue
if "finished" != info.status or not info.filename:
continue
try:
timestamp_seconds: float = info.timestamp / 1e9
item_datetime: datetime = datetime.fromtimestamp(timestamp_seconds, tz=UTC)
if item_datetime < cutoff_date:
items_to_delete.append((key, info))
except (OSError, ValueError, OverflowError) as e:
LOG.error(f"Failed to parse timestamp '{info.timestamp}' for item '{info.title}': {e}")
titles: list[str] = []
for key, info in items_to_delete:
item_name: str = info.title or info.id or info._id
self._notify.emit(
Events.ITEM_DELETED,
data=info,
title="Download Cleared",
message=f"'{item_name}' record removed from history.",
)
titles.append(item_name)
self.done.delete(key)
if titles:
LOG.info(f"Automatically cleared '{', '.join(titles)}' from download history due to age.")
def _handle_task_exception(self, task: asyncio.Task) -> None:
if task.cancelled():
return

View file

@ -482,6 +482,9 @@ def check_id(file: Path) -> bool | str:
id: str | None = match.groupdict().get("id")
try:
if not file.parent.exists():
return False
for f in file.parent.iterdir():
if id not in f.stem:
continue

View file

@ -192,6 +192,9 @@ class Config(metaclass=Singleton):
playlist_items_concurrency: int = 4
"""The number of concurrent playlist items to be processed at same time."""
auto_clear_history_days: int = 0
"""Number of days after which completed download history is automatically cleared. 0 to disable."""
pictures_backends: list[str] = [
"https://unsplash.it/1920/1080?random",
"https://picsum.photos/1920/1080",
@ -230,6 +233,7 @@ class Config(metaclass=Singleton):
"playlist_items_concurrency",
"download_path_depth",
"download_info_expires",
"auto_clear_history_days",
)
"The variables that are integers."

View file

@ -103,7 +103,7 @@
</div>
<div class="navbar-end">
<div class="navbar-item has-dropdown" v-if="config.app.file_logging || config.app.console_enabled">
<div class="navbar-item has-dropdown" v-if="config.app?.file_logging || config.app?.console_enabled">
<a class="navbar-link" @click="(e: MouseEvent) => openMenu(e)">
<span class="icon"><i class="fas fa-tools" /></span>
<span>Other</span>
@ -111,7 +111,7 @@
<div class="navbar-dropdown">
<NuxtLink class="navbar-item" to="/logs" @click.prevent="(e: MouseEvent) => changeRoute(e)"
v-if="config.app.file_logging">
v-if="config.app?.file_logging">
<span class="icon"><i class="fa-solid fa-file-lines" /></span>
<span>Logs</span>
</NuxtLink>