mirror of
https://github.com/alexta69/metube.git
synced 2026-06-15 16:20:06 +00:00
add subscriptions; change persistence file format to JSON (closes #901, #76, #113, #170, #242, #444, #503, #555, #566)
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
import { DestroyRef, inject, Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||
import { of, Subject } from 'rxjs';
|
||||
import { catchError, tap } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { MeTubeSocket } from './metube-socket.service';
|
||||
import { SubscriptionRow } from '../interfaces/subscription';
|
||||
import { Status } from '../interfaces';
|
||||
import { AddDownloadPayload } from './downloads.service';
|
||||
|
||||
export interface SubscribePayload extends AddDownloadPayload {
|
||||
checkIntervalMinutes: number;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SubscriptionsService {
|
||||
private http = inject(HttpClient);
|
||||
private socket = inject(MeTubeSocket);
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
subscriptions = new Map<string, SubscriptionRow>();
|
||||
subscriptionsChanged = new Subject<void>();
|
||||
|
||||
private publishList(rows: SubscriptionRow[]) {
|
||||
this.subscriptions.clear();
|
||||
for (const row of rows) {
|
||||
this.subscriptions.set(row.id, row);
|
||||
}
|
||||
this.subscriptionsChanged.next();
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.socket
|
||||
.fromEvent('subscriptions_all')
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((strdata: string) => {
|
||||
const data: SubscriptionRow[] = JSON.parse(strdata);
|
||||
this.publishList(data);
|
||||
});
|
||||
|
||||
this.socket
|
||||
.fromEvent('subscription_added')
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((strdata: string) => {
|
||||
const row: SubscriptionRow = JSON.parse(strdata);
|
||||
this.subscriptions.set(row.id, row);
|
||||
this.subscriptionsChanged.next();
|
||||
});
|
||||
|
||||
this.socket
|
||||
.fromEvent('subscription_updated')
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((strdata: string) => {
|
||||
const row: SubscriptionRow = JSON.parse(strdata);
|
||||
this.subscriptions.set(row.id, row);
|
||||
this.subscriptionsChanged.next();
|
||||
});
|
||||
|
||||
this.socket
|
||||
.fromEvent('subscription_removed')
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((strdata: string) => {
|
||||
const id: string = JSON.parse(strdata);
|
||||
this.subscriptions.delete(id);
|
||||
this.subscriptionsChanged.next();
|
||||
});
|
||||
}
|
||||
|
||||
handleHTTPError(error: HttpErrorResponse) {
|
||||
const msg =
|
||||
error.error instanceof ErrorEvent
|
||||
? error.error.message
|
||||
: typeof error.error === 'string'
|
||||
? error.error
|
||||
: error.error?.msg || error.message || 'Request failed';
|
||||
return of({ status: 'error' as const, msg });
|
||||
}
|
||||
|
||||
subscribe(payload: SubscribePayload) {
|
||||
return this.http
|
||||
.post<Status>('subscribe', {
|
||||
url: payload.url,
|
||||
download_type: payload.downloadType,
|
||||
codec: payload.codec,
|
||||
quality: payload.quality,
|
||||
format: payload.format,
|
||||
folder: payload.folder,
|
||||
custom_name_prefix: payload.customNamePrefix,
|
||||
playlist_item_limit: payload.playlistItemLimit,
|
||||
auto_start: payload.autoStart,
|
||||
split_by_chapters: payload.splitByChapters,
|
||||
chapter_template: payload.chapterTemplate,
|
||||
subtitle_language: payload.subtitleLanguage,
|
||||
subtitle_mode: payload.subtitleMode,
|
||||
check_interval_minutes: payload.checkIntervalMinutes,
|
||||
})
|
||||
.pipe(catchError((err) => this.handleHTTPError(err)));
|
||||
}
|
||||
|
||||
delete(ids: string[]) {
|
||||
return this.http.post('subscriptions/delete', { ids }).pipe(catchError((err) => this.handleHTTPError(err)));
|
||||
}
|
||||
|
||||
update(id: string, changes: Partial<Pick<SubscriptionRow, 'enabled' | 'check_interval_minutes' | 'name'>>) {
|
||||
return this.http
|
||||
.post('subscriptions/update', { id, ...changes })
|
||||
.pipe(catchError((err) => this.handleHTTPError(err)));
|
||||
}
|
||||
|
||||
checkNow(ids?: string[]) {
|
||||
return this.http
|
||||
.post('subscriptions/check', ids?.length ? { ids } : {})
|
||||
.pipe(catchError((err) => this.handleHTTPError(err)));
|
||||
}
|
||||
|
||||
fetchList() {
|
||||
return this.http.get<SubscriptionRow[]>('subscriptions').pipe(catchError(() => of([])));
|
||||
}
|
||||
|
||||
refreshList() {
|
||||
return this.http.get<SubscriptionRow[]>('subscriptions').pipe(
|
||||
tap((rows) => this.publishList(rows)),
|
||||
catchError((err) => this.handleHTTPError(err)),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user