enable custom name prefix

This commit is contained in:
hellodword 2023-04-09 11:27:41 +08:00
parent d922970d0c
commit 2ff7b0975a
5 changed files with 34 additions and 22 deletions

View file

@ -94,7 +94,10 @@ async def add(request):
raise web.HTTPBadRequest()
format = post.get('format')
folder = post.get('folder')
status = await dqueue.add(url, quality, format, folder)
custom_name_prefix = post.get('custom_name_prefix')
if custom_name_prefix is None:
custom_name_prefix = ''
status = await dqueue.add(url, quality, format, folder, custom_name_prefix)
return web.Response(text=serializer.encode(status))
@routes.post(config.URL_PREFIX + 'delete')

View file

@ -28,13 +28,14 @@ class DownloadQueueNotifier:
raise NotImplementedError
class DownloadInfo:
def __init__(self, id, title, url, quality, format, folder):
self.id, self.title, self.url = id, title, url
def __init__(self, id, title, url, quality, format, folder, custom_name_prefix):
self.id = id if len(custom_name_prefix) == 0 else f'{custom_name_prefix}.{id}'
self.title = title if len(custom_name_prefix) == 0 else f'{custom_name_prefix}.{title}'
self.url = url
self.quality = quality
self.format = format
self.folder = folder
self.status = self.msg = self.percent = self.speed = self.eta = None
self.filename = None
self.timestamp = time.time_ns()
class Download:
@ -213,7 +214,7 @@ class DownloadQueue:
**self.config.YTDL_OPTIONS,
}).extract_info(url, download=False)
async def __add_entry(self, entry, quality, format, folder, already):
async def __add_entry(self, entry, quality, format, folder, custom_name_prefix, already):
etype = entry.get('_type') or 'video'
if etype == 'playlist':
entries = entry['entries']
@ -226,13 +227,13 @@ class DownloadQueue:
for property in ("id", "title", "uploader", "uploader_id"):
if property in entry:
etr[f"playlist_{property}"] = entry[property]
results.append(await self.__add_entry(etr, quality, format, folder, already))
results.append(await self.__add_entry(etr, quality, format, folder, custom_name_prefix, already))
if any(res['status'] == 'error' for res in results):
return {'status': 'error', 'msg': ', '.join(res['msg'] for res in results if res['status'] == 'error' and 'msg' in res)}
return {'status': 'ok'}
elif etype == 'video' or etype.startswith('url') and 'id' in entry and 'title' in entry:
if not self.queue.exists(entry['id']):
dl = DownloadInfo(entry['id'], entry['title'], entry.get('webpage_url') or entry['url'], quality, format, folder)
dl = DownloadInfo(entry['id'], entry['title'], entry.get('webpage_url') or entry['url'], quality, format, folder, custom_name_prefix)
# Keep consistent with frontend
base_directory = self.config.DOWNLOAD_DIR if (quality != 'audio' and format not in AUDIO_FORMATS) else self.config.AUDIO_DOWNLOAD_DIR
if folder:
@ -248,7 +249,7 @@ class DownloadQueue:
os.makedirs(dldirectory, exist_ok=True)
else:
dldirectory = base_directory
output = self.config.OUTPUT_TEMPLATE
output = self.config.OUTPUT_TEMPLATE if len(custom_name_prefix) == 0 else f'{custom_name_prefix}.{self.config.OUTPUT_TEMPLATE}'
output_chapter = self.config.OUTPUT_TEMPLATE_CHAPTER
for property, value in entry.items():
if property.startswith("playlist"):
@ -258,11 +259,11 @@ class DownloadQueue:
await self.notifier.added(dl)
return {'status': 'ok'}
elif etype.startswith('url'):
return await self.add(entry['url'], quality, format, folder, already)
return await self.add(entry['url'], quality, format, folder, custom_name_prefix, already)
return {'status': 'error', 'msg': f'Unsupported resource "{etype}"'}
async def add(self, url, quality, format, folder, already=None):
log.info(f'adding {url}: {quality=} {format=} {already=} {folder=}')
async def add(self, url, quality, format, folder, custom_name_prefix, already=None):
log.info(f'adding {url}: {quality=} {format=} {already=} {folder=} {custom_name_prefix=}')
already = set() if already is None else already
if url in already:
log.info('recursion detected, skipping')
@ -273,7 +274,7 @@ class DownloadQueue:
entry = await asyncio.get_running_loop().run_in_executor(None, self.__extract_info, url)
except yt_dlp.utils.YoutubeDLError as exc:
return {'status': 'error', 'msg': str(exc)}
return await self.__add_entry(entry, quality, format, folder, already)
return await self.__add_entry(entry, quality, format, folder, custom_name_prefix, already)
async def cancel(self, ids):
for id in ids:

View file

@ -56,9 +56,15 @@
<span class="sr-only">Advanced options</span>
</button>
<div ngbDropdownMenu aria-labelledby="advancedButton" class="dropdown-menu dropdown-menu-end folder-dropdown-menu">
<div class="input-group">
<span class="input-group-text">Download Folder</span>
<ng-select [items]="customDirs$ | async" placeholder="Default" [addTag]="allowCustomDir.bind(this)" addTagText="Create directory" [ngStyle]="{'flex-grow':'1'}" bindLabel="folder" [(ngModel)]="folder" [disabled]="addInProgress || downloads.loading"></ng-select>
<div class="container">
<div class="input-group add-url-component">
<span class="input-group-text">Download Folder</span>
<ng-select [items]="customDirs$ | async" placeholder="Default" [addTag]="allowCustomDir.bind(this)" addTagText="Create directory" [ngStyle]="{'flex-grow':'1'}" bindLabel="folder" [(ngModel)]="folder" [disabled]="addInProgress || downloads.loading"></ng-select>
</div>
<div class="input-group add-url-component">
<span class="input-group-text">Custom Name Prefix</span>
<input type="text" autocomplete="off" spellcheck="false" class="form-control" placeholder="Default" name="customNamePrefix" [(ngModel)]="customNamePrefix" [disabled]="addInProgress || downloads.loading">
</div>
</div>
</div>
</div>

View file

@ -20,6 +20,7 @@ export class AppComponent implements AfterViewInit {
quality: string;
format: string;
folder: string;
customNamePrefix: string;
addInProgress = false;
darkMode: boolean;
customDirs$: Observable<string[]>;
@ -154,15 +155,16 @@ export class AppComponent implements AfterViewInit {
this.quality = exists ? this.quality : 'best'
}
addDownload(url?: string, quality?: string, format?: string, folder?: string) {
addDownload(url?: string, quality?: string, format?: string, folder?: string, customNamePrefix?: string) {
url = url ?? this.addUrl
quality = quality ?? this.quality
format = format ?? this.format
folder = folder ?? this.folder
customNamePrefix = customNamePrefix ?? this.customNamePrefix
console.debug('Downloading: url='+url+' quality='+quality+' format='+format+' folder='+folder);
console.debug('Downloading: url='+url+' quality='+quality+' format='+format+' folder='+folder+' customNamePrefix='+customNamePrefix);
this.addInProgress = true;
this.downloads.add(url, quality, format, folder).subscribe((status: Status) => {
this.downloads.add(url, quality, format, folder, customNamePrefix).subscribe((status: Status) => {
if (status.status === 'error') {
alert(`Error adding URL: ${status.msg}`);
} else {
@ -172,8 +174,8 @@ export class AppComponent implements AfterViewInit {
});
}
retryDownload(key: string, url: string, quality: string, format: string, folder: string) {
this.addDownload(url, quality, format, folder);
retryDownload(key: string, url: string, quality: string, format: string, folder: string, customNamePrefix: string) {
this.addDownload(url, quality, format, folder, customNamePrefix);
this.downloads.delById('done', [key]).subscribe();
}

View file

@ -97,8 +97,8 @@ export class DownloadsService {
return of({status: 'error', msg: msg})
}
public add(url: string, quality: string, format: string, folder: string) {
return this.http.post<Status>('add', {url: url, quality: quality, format: format, folder: folder}).pipe(
public add(url: string, quality: string, format: string, folder: string, customNamePrefix: string) {
return this.http.post<Status>('add', {url: url, quality: quality, format: format, folder: folder, custom_name_prefix: customNamePrefix}).pipe(
catchError(this.handleHTTPError)
);
}