diff --git a/backend/downloader.js b/backend/downloader.js
index e0b2778..0843a78 100644
--- a/backend/downloader.js
+++ b/backend/downloader.js
@@ -15,12 +15,6 @@ const utils = require('./utils');
let db_api = null;
-const STEP_INDEX_TO_LABEL = {
- 0: 'Creating download',
- 1: 'Getting info',
- 2: 'Downloading file'
-}
-
const archivePath = path.join(__dirname, 'appdata', 'archives');
function setDB(input_db_api) { db_api = input_db_api }
@@ -62,7 +56,7 @@ async function checkDownloads() {
logger.verbose('Checking downloads');
const downloads = await db_api.getRecords('download_queue');
downloads.sort((download1, download2) => download1.timestamp_start - download2.timestamp_start);
- const running_downloads = downloads.filter(download => !download.paused);
+ const running_downloads = downloads.filter(download => !download['paused'] && download['finished_step']);
for (let i = 0; i < running_downloads.length; i++) {
const running_download = running_downloads[i];
if (i === 5/*config_api.getConfigItem('ytdl_max_concurrent_downloads')*/) break;
@@ -259,7 +253,7 @@ async function downloadQueuedFile(download_uid) {
}
const file_uids = file_objs.map(file_obj => file_obj.uid);
- await db_api.updateRecord('download_queue', {uid: download_uid}, {finished_step: true, finished: true, percent_complete: 100, file_uids: file_uids, container: container});
+ await db_api.updateRecord('download_queue', {uid: download_uid}, {finished_step: true, finished: true, step_index: 3, percent_complete: 100, file_uids: file_uids, container: container});
resolve();
}
});
diff --git a/src/app/components/downloads/downloads.component.html b/src/app/components/downloads/downloads.component.html
index c6870b5..41fdb9d 100644
--- a/src/app/components/downloads/downloads.component.html
+++ b/src/app/components/downloads/downloads.component.html
@@ -1,27 +1,57 @@
-
-
-
2">
-
- Session ID: {{session_downloads['session_id']}}
- (current)
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ Date
+ {{element.timestamp_start | date: 'short'}}
+
+
+
+
+ Title
+
+
+ {{element.container.title ? element?.container.title : element.container.name}}
+
+
+
+
+
+
+ Stage
+ {{STEP_INDEX_TO_LABEL[element.step_index]}}
+
+
+
+
+ Progress
+ {{+(element.percent_complete) > 100 ? '100' : element.percent_complete}}%
+
-
-
No downloads available!
-
+
+
+ Actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/downloads/downloads.component.scss b/src/app/components/downloads/downloads.component.scss
index e69de29..a6df223 100644
--- a/src/app/components/downloads/downloads.component.scss
+++ b/src/app/components/downloads/downloads.component.scss
@@ -0,0 +1,9 @@
+mat-header-cell, mat-cell {
+ justify-content: center;
+}
+
+.one-line {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
\ No newline at end of file
diff --git a/src/app/components/downloads/downloads.component.ts b/src/app/components/downloads/downloads.component.ts
index 1539448..643c21b 100644
--- a/src/app/components/downloads/downloads.component.ts
+++ b/src/app/components/downloads/downloads.component.ts
@@ -1,7 +1,9 @@
-import { Component, OnInit, ViewChildren, QueryList, ElementRef, OnDestroy } from '@angular/core';
+import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { PostsService } from 'app/posts.services';
import { trigger, transition, animateChild, stagger, query, style, animate } from '@angular/animations';
import { Router } from '@angular/router';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatTableDataSource } from '@angular/material/table';
@Component({
selector: 'app-downloads',
@@ -36,12 +38,24 @@ export class DownloadsComponent implements OnInit, OnDestroy {
downloads_check_interval = 1000;
downloads = [];
+ finished_downloads = [];
interval_id = null;
keys = Object.keys;
valid_sessions_length = 0;
+ STEP_INDEX_TO_LABEL = {
+ 0: 'Creating download',
+ 1: 'Getting info',
+ 2: 'Downloading file'
+ }
+
+ displayedColumns: string[] = ['date', 'title', 'stage', 'progress', 'actions'];
+ dataSource = null; // new MatTableDataSource
();
+
+ @ViewChild(MatPaginator) paginator: MatPaginator;
+
sort_downloads = (a, b) => {
const result = b.value.timestamp_start - a.value.timestamp_start;
return result;
@@ -64,108 +78,37 @@ export class DownloadsComponent implements OnInit, OnDestroy {
});
}
- ngOnDestroy() {
+ ngOnDestroy(): void {
if (this.interval_id) { clearInterval(this.interval_id) }
}
- getCurrentDownloads() {
+ getCurrentDownloads(): void {
this.postsService.getCurrentDownloads().subscribe(res => {
- if (res['downloads']) {
- this.assignNewValues(res['downloads']);
+ if (res['downloads'] !== null
+ && res['downloads'] !== undefined
+ && JSON.stringify(this.downloads) !== JSON.stringify(res['downloads'])) {
+ this.downloads = res['downloads'];
+ this.dataSource = new MatTableDataSource(this.downloads);
+ this.dataSource.paginator = this.paginator;
} else {
// failed to get downloads
}
});
}
- clearDownload(session_id, download_uid) {
- this.postsService.clearDownloads(false, session_id, download_uid).subscribe(res => {
- if (res['success']) {
- // this.downloads = res['downloads'];
- } else {
- }
- });
- }
-
- clearDownloads(session_id) {
- this.postsService.clearDownloads(false, session_id).subscribe(res => {
+ clearFinishedDownloads(): void {
+ this.postsService.clearDownloads(false).subscribe(res => {
if (res['success']) {
this.downloads = res['downloads'];
- } else {
}
});
}
- clearAllDownloads() {
- this.postsService.clearDownloads(true).subscribe(res => {
- if (res['success']) {
- this.downloads = res['downloads'];
- } else {
- }
- });
- }
-
- assignNewValues(new_downloads_by_session) {
- const session_keys = Object.keys(new_downloads_by_session);
-
- // remove missing session IDs
- const current_session_ids = Object.keys(this.downloads);
- const missing_session_ids = current_session_ids.filter(session => session_keys.indexOf(session) === -1)
-
- for (const missing_session_id of missing_session_ids) {
- delete this.downloads[missing_session_id];
- }
-
- // loop through sessions
- for (let i = 0; i < session_keys.length; i++) {
- const session_id = session_keys[i];
- const session_downloads_by_id = new_downloads_by_session[session_id];
- const session_download_ids = Object.keys(session_downloads_by_id);
-
- if (this.downloads[session_id]) {
- // remove missing download IDs
- const current_download_ids = Object.keys(this.downloads[session_id]);
- const missing_download_ids = current_download_ids.filter(download => session_download_ids.indexOf(download) === -1)
-
- for (const missing_download_id of missing_download_ids) {
- console.log('removing missing download id');
- delete this.downloads[session_id][missing_download_id];
- }
- }
-
- if (!this.downloads[session_id]) {
- this.downloads[session_id] = session_downloads_by_id;
- } else {
- for (let j = 0; j < session_download_ids.length; j++) {
- if (session_download_ids[j] === 'session_id' || session_download_ids[j] === '_id') continue;
- const download_id = session_download_ids[j];
- const download = new_downloads_by_session[session_id][download_id]
- if (!this.downloads[session_id][download_id]) {
- this.downloads[session_id][download_id] = download;
- } else {
- const download_to_update = this.downloads[session_id][download_id];
- download_to_update['percent_complete'] = download['percent_complete'];
- download_to_update['complete'] = download['complete'];
- download_to_update['timestamp_end'] = download['timestamp_end'];
- download_to_update['downloading'] = download['downloading'];
- download_to_update['error'] = download['error'];
- }
- }
- }
- }
- }
-
- downloadsValid() {
- let valid = false;
- for (let i = 0; i < this.downloads.length; i++) {
- const session_downloads = this.downloads[i];
- if (!session_downloads) continue;
- if (this.keys(session_downloads).length > 2) {
- valid = true;
- break;
- }
- }
- return valid;
- }
-
}
+
+export interface Download {
+ timestamp_start: number;
+ title: string;
+ step_index: number;
+ progress: string;
+}
\ No newline at end of file