Implement DEFAULT_DOWNLOAD_FOLDER and CLEAR_COMPLETED_AFTER features (#875, #869)

Co-authored-by: alexta69 <7450369+alexta69@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-06 15:37:35 +00:00
parent d211f24e00
commit 1f4c4df847
4 changed files with 22 additions and 0 deletions

View File

@@ -36,6 +36,7 @@ Certain values can be set via environment variables, using the `-e` parameter on
* __MAX_CONCURRENT_DOWNLOADS__: Maximum number of simultaneous downloads allowed. For example, if set to `5`, then at most five downloads will run concurrently, and any additional downloads will wait until one of the active downloads completes. Defaults to `3`.
* __DELETE_FILE_ON_TRASHCAN__: if `true`, downloaded files are deleted on the server, when they are trashed from the "Completed" section of the UI. Defaults to `false`.
* __DEFAULT_OPTION_PLAYLIST_ITEM_LIMIT__: Maximum number of playlist items that can be downloaded. Defaults to `0` (no limit).
* __CLEAR_COMPLETED_AFTER__: Number of seconds after which completed (and failed) downloads are automatically removed from the "Completed" list. Defaults to `0` (disabled).
### 📁 Storage & Directories
@@ -43,6 +44,7 @@ Certain values can be set via environment variables, using the `-e` parameter on
* __AUDIO_DOWNLOAD_DIR__: Path to where audio-only downloads will be saved, if you wish to separate them from the video downloads. Defaults to the value of `DOWNLOAD_DIR`.
* __CUSTOM_DIRS__: Whether to enable downloading videos into custom directories within the __DOWNLOAD_DIR__ (or __AUDIO_DOWNLOAD_DIR__). When enabled, a dropdown appears next to the Add button to specify the download directory. Defaults to `true`.
* __CREATE_CUSTOM_DIRS__: Whether to support automatically creating directories within the __DOWNLOAD_DIR__ (or __AUDIO_DOWNLOAD_DIR__) if they do not exist. When enabled, the download directory selector supports free-text input, and the specified directory will be created recursively. Defaults to `true`.
* __DEFAULT_DOWNLOAD_FOLDER__: Default subdirectory within __DOWNLOAD_DIR__ (or __AUDIO_DOWNLOAD_DIR__) to pre-select in the download folder field. Useful when most downloads should go to a specific subfolder. Can be overridden per-download in the UI. Defaults to empty (uses the base download directory).
* __CUSTOM_DIRS_EXCLUDE_REGEX__: Regular expression to exclude some custom directories from the dropdown. Empty regex disables exclusion. Defaults to `(^|/)[.@].*$`, which means directories starting with `.` or `@`.
* __DOWNLOAD_DIRS_INDEXABLE__: If `true`, the download directories (__DOWNLOAD_DIR__ and __AUDIO_DOWNLOAD_DIR__) are indexable on the web server. Defaults to `false`.
* __STATE_DIR__: Path to where the queue persistence files will be saved. Defaults to `/downloads/.metube` in the Docker image, and `.` otherwise.

View File

@@ -60,6 +60,8 @@ class Config:
'OUTPUT_TEMPLATE_PLAYLIST': '%(playlist_title)s/%(title)s.%(ext)s',
'OUTPUT_TEMPLATE_CHANNEL': '%(channel)s/%(title)s.%(ext)s',
'DEFAULT_OPTION_PLAYLIST_ITEM_LIMIT' : '0',
'DEFAULT_DOWNLOAD_FOLDER': '',
'CLEAR_COMPLETED_AFTER': '0',
'YTDL_OPTIONS': '{}',
'YTDL_OPTIONS_FILE': '',
'ROBOTS_TXT': '',

View File

@@ -573,6 +573,20 @@ class DownloadQueue:
else:
self.done.put(download)
asyncio.create_task(self.notifier.completed(download.info))
try:
clear_after = int(self.config.CLEAR_COMPLETED_AFTER)
except ValueError:
log.error(f'CLEAR_COMPLETED_AFTER is set to an invalid value "{self.config.CLEAR_COMPLETED_AFTER}", expected an integer number of seconds')
clear_after = 0
if clear_after > 0:
task = asyncio.create_task(self.__auto_clear_after_delay(download.info.url, clear_after))
task.add_done_callback(lambda t: log.error(f'Auto-clear task failed: {t.exception()}') if not t.cancelled() and t.exception() else None)
async def __auto_clear_after_delay(self, url, delay_seconds):
await asyncio.sleep(delay_seconds)
if self.done.exists(url):
log.debug(f'Auto-clearing completed download: {url}')
await self.clear([url])
def __extract_info(self, url):
debug_logging = logging.getLogger().isEnabledFor(logging.DEBUG)

View File

@@ -315,6 +315,10 @@ export class App implements AfterViewInit, OnInit {
if (!this.chapterTemplate) {
this.chapterTemplate = config['OUTPUT_TEMPLATE_CHAPTER'];
}
// Set default download folder from backend config if not already set
if (!this.folder && config['DEFAULT_DOWNLOAD_FOLDER']) {
this.folder = config['DEFAULT_DOWNLOAD_FOLDER'];
}
}
});
}