youtube-dl refactor (#956)

* Consolidated all youtube-dl calls into one function
* Downloads can now be cancelled and better "paused"
* Removed node-youtube-dl dependency
* Added ability to manually check a subscription, and to cancel a subscription check

---------

Co-authored-by: Dedy Martadinata S <dedyms@proton.me>
This commit is contained in:
Tzahi12345
2023-11-27 12:55:53 -05:00
committed by GitHub
parent 99c5cf590e
commit 0565cf24a6
23 changed files with 653 additions and 332 deletions

View File

@@ -14,6 +14,7 @@ export type { ChangeRolePermissionsRequest } from './models/ChangeRolePermission
export type { ChangeUserPermissionsRequest } from './models/ChangeUserPermissionsRequest';
export type { CheckConcurrentStreamRequest } from './models/CheckConcurrentStreamRequest';
export type { CheckConcurrentStreamResponse } from './models/CheckConcurrentStreamResponse';
export type { CheckSubscriptionRequest } from './models/CheckSubscriptionRequest';
export type { ClearDownloadsRequest } from './models/ClearDownloadsRequest';
export type { ConcurrentStream } from './models/ConcurrentStream';
export type { Config } from './models/Config';

View File

@@ -0,0 +1,7 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type CheckSubscriptionRequest = {
sub_id: string;
};

View File

@@ -8,6 +8,7 @@ export type Download = {
running: boolean;
finished: boolean;
paused: boolean;
cancelled?: boolean;
finished_step: boolean;
url: string;
type: string;

View File

@@ -11,9 +11,12 @@ export type Subscription = {
type: FileType;
user_uid: string | null;
isPlaylist: boolean;
child_process?: any;
archive?: string;
timerange?: string;
custom_args?: string;
custom_output?: string;
downloading?: boolean;
paused?: boolean;
videos: Array<any>;
};

View File

@@ -2,10 +2,8 @@
/* tslint:disable */
/* eslint-disable */
import type { SubscriptionRequestData } from './SubscriptionRequestData';
export type UnsubscribeRequest = {
sub: SubscriptionRequestData;
sub_id: string;
/**
* Defaults to false
*/

View File

@@ -69,8 +69,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
tooltip: $localize`Pause`,
action: (download: Download) => this.pauseDownload(download),
show: (download: Download) => !download.finished && (!download.paused || !download.finished_step),
icon: 'pause',
loading: (download: Download) => download.paused && !download.finished_step
icon: 'pause'
},
{
tooltip: $localize`Resume`,
@@ -81,7 +80,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
{
tooltip: $localize`Cancel`,
action: (download: Download) => this.cancelDownload(download),
show: (download: Download) => false && !download.finished && !download.paused, // TODO: add possibility to cancel download
show: (download: Download) => !download.finished && !download.paused && !download.cancelled,
icon: 'cancel'
},
{

View File

@@ -2,6 +2,7 @@ import { Component, OnInit, Inject } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { PostsService } from 'app/posts.services';
import { ConfirmDialogComponent } from '../confirm-dialog/confirm-dialog.component';
import { Subscription } from 'api-types';
@Component({
selector: 'app-subscription-info-dialog',
@@ -10,7 +11,7 @@ import { ConfirmDialogComponent } from '../confirm-dialog/confirm-dialog.compone
})
export class SubscriptionInfoDialogComponent implements OnInit {
sub = null;
sub: Subscription = null;
unsubbedEmitter = null;
constructor(public dialogRef: MatDialogRef<SubscriptionInfoDialogComponent>,
@@ -41,7 +42,7 @@ export class SubscriptionInfoDialogComponent implements OnInit {
}
unsubscribe() {
this.postsService.unsubscribe(this.sub, true).subscribe(res => {
this.postsService.unsubscribe(this.sub.id, true).subscribe(res => {
this.unsubbedEmitter.emit(true);
this.dialogRef.close();
});

View File

@@ -169,6 +169,8 @@ export class MainComponent implements OnInit {
argsChangedSubject: Subject<boolean> = new Subject<boolean>();
simulatedOutput = '';
interval_id = null;
constructor(public postsService: PostsService, private youtubeSearch: YoutubeSearchService, public snackBar: MatSnackBar,
private router: Router, public dialog: MatDialog, private platform: Platform, private route: ActivatedRoute) {
this.audioOnly = false;
@@ -232,11 +234,12 @@ export class MainComponent implements OnInit {
}
// get downloads routine
setInterval(() => {
if (this.interval_id) { clearInterval(this.interval_id) }
this.interval_id = setInterval(() => {
if (this.current_download) {
this.getCurrentDownload();
}
}, 500);
}, 1000);
return true;
}
@@ -294,6 +297,10 @@ export class MainComponent implements OnInit {
}
}
ngOnDestroy(): void {
if (this.interval_id) { clearInterval(this.interval_id) }
}
// download helpers
downloadHelper(container: DatabaseFile | Playlist, type: string, is_playlist = false, force_view = false, navigate_mode = false): void {
this.downloadingfile = false;

View File

@@ -113,7 +113,8 @@ import {
Archive,
Subscription,
RestartDownloadResponse,
TaskType
TaskType,
CheckSubscriptionRequest
} from '../api-types';
import { isoLangs } from './dialogs/user-profile-dialog/locales_list';
import { Title } from '@angular/platform-browser';
@@ -566,8 +567,18 @@ export class PostsService implements CanActivate {
return this.http.post<SuccessObject>(this.path + 'updateSubscription', {subscription: subscription}, this.httpOptions);
}
unsubscribe(sub: SubscriptionRequestData, deleteMode = false) {
const body: UnsubscribeRequest = {sub: sub, deleteMode: deleteMode};
checkSubscription(sub_id: string) {
const body: CheckSubscriptionRequest = {sub_id: sub_id};
return this.http.post<SuccessObject>(this.path + 'checkSubscription', body, this.httpOptions);
}
cancelCheckSubscription(sub_id: string) {
const body: CheckSubscriptionRequest = {sub_id: sub_id};
return this.http.post<SuccessObject>(this.path + 'cancelCheckSubscription', body, this.httpOptions);
}
unsubscribe(sub_id: string, deleteMode = false) {
const body: UnsubscribeRequest = {sub_id: sub_id, deleteMode: deleteMode};
return this.http.post<UnsubscribeResponse>(this.path + 'unsubscribe', body, this.httpOptions)
}

View File

@@ -3,6 +3,7 @@
<div style="margin-bottom: 15px;">
<h2 style="text-align: center;" *ngIf="subscription">
{{subscription.name}}&nbsp;<ng-container *ngIf="subscription.paused" i18n="Paused suffix">(Paused)</ng-container>
<button class="edit-button" (click)="editSubscription()" [disabled]="downloading" matTooltip="Edit" i18n-matTooltip="Edit" mat-icon-button><mat-icon class="save-icon">edit</mat-icon></button>
</h2>
<mat-progress-bar style="width: 80%; margin: 0 auto; margin-top: 15px;" *ngIf="subscription && subscription.downloading" mode="indeterminate"></mat-progress-bar>
</div>
@@ -13,7 +14,14 @@
<div style="margin-bottom: 100px;" *ngIf="subscription">
<app-recent-videos #recentVideos [sub_id]="subscription.id"></app-recent-videos>
</div>
<button class="edit-button" color="primary" (click)="editSubscription()" [disabled]="downloading" matTooltip="Edit" i18n-matTooltip="Edit" mat-fab><mat-icon class="save-icon">edit</mat-icon></button>
<div class="check-button">
<ng-container *ngIf="subscription.downloading">
<button color="primary" (click)="cancelCheckSubscription()" [disabled]="cancel_clicked" matTooltip="Cancel subscription check" i18n-matTooltip="Cancel subscription check" mat-fab><mat-icon class="save-icon">cancel</mat-icon></button>
</ng-container>
<ng-container *ngIf="!subscription.downloading">
<button color="primary" (click)="checkSubscription()" [disabled]="check_clicked" matTooltip="Check subscription" i18n-matTooltip="Check subscription" mat-fab><mat-icon class="save-icon">youtube_searched_for</mat-icon></button>
</ng-container>
</div>
<button class="watch-button" color="primary" (click)="watchSubscription()" matTooltip="Play all" i18n-matTooltip="Play all" mat-fab><mat-icon class="save-icon">video_library</mat-icon></button>
<button class="save-button" color="primary" (click)="downloadContent()" [disabled]="downloading" matTooltip="Download zip" i18n-matTooltip="Download zip" mat-fab><mat-icon class="save-icon">save</mat-icon><mat-spinner *ngIf="downloading" class="spinner" [diameter]="50"></mat-spinner></button>
</div>

View File

@@ -58,13 +58,19 @@
bottom: 25px;
}
.edit-button {
.check-button {
left: 25px;
position: fixed;
bottom: 25px;
z-index: 99999;
}
.edit-button {
right: 35px;
position: fixed;
z-index: 99999;
}
.save-icon {
bottom: 1px;
position: relative;

View File

@@ -3,6 +3,7 @@ import { PostsService } from 'app/posts.services';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { EditSubscriptionDialogComponent } from 'app/dialogs/edit-subscription-dialog/edit-subscription-dialog.component';
import { Subscription } from 'api-types';
@Component({
selector: 'app-subscription',
@@ -12,11 +13,13 @@ import { EditSubscriptionDialogComponent } from 'app/dialogs/edit-subscription-d
export class SubscriptionComponent implements OnInit, OnDestroy {
id = null;
subscription = null;
subscription: Subscription = null;
use_youtubedl_archive = false;
descendingMode = true;
downloading = false;
sub_interval = null;
check_clicked = false;
cancel_clicked = false;
constructor(private postsService: PostsService, private route: ActivatedRoute, private router: Router, private dialog: MatDialog) { }
@@ -90,4 +93,34 @@ export class SubscriptionComponent implements OnInit, OnDestroy {
this.router.navigate(['/player', {sub_id: this.subscription.id}])
}
checkSubscription(): void {
this.check_clicked = true;
this.postsService.checkSubscription(this.subscription.id).subscribe(res => {
this.check_clicked = false;
if (!res['success']) {
this.postsService.openSnackBar('Failed to check subscription!');
return;
}
}, err => {
console.error(err);
this.check_clicked = false;
this.postsService.openSnackBar('Failed to check subscription!');
});
}
cancelCheckSubscription(): void {
this.cancel_clicked = true;
this.postsService.cancelCheckSubscription(this.subscription.id).subscribe(res => {
this.cancel_clicked = false;
if (!res['success']) {
this.postsService.openSnackBar('Failed to cancel check subscription!');
return;
}
}, err => {
console.error(err);
this.cancel_clicked = false;
this.postsService.openSnackBar('Failed to cancel check subscription!');
});
}
}