Skip to content

Commit

Permalink
Merge pull request #25 from irohalab/download-directly
Browse files Browse the repository at this point in the history
download directly support
  • Loading branch information
EverettSummer authored Nov 12, 2023
2 parents f167fed + ba16535 commit 2e75b3d
Show file tree
Hide file tree
Showing 14 changed files with 321 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mira-ui",
"version": "2.5.4",
"version": "2.6.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
Expand Down
7 changes: 5 additions & 2 deletions src/app/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import { VertexGraphComponent } from './video-process-job-detail/vertex-graph/ve
import { StreamLogViewerComponent } from './video-process-job-detail/stream-log-viewer/stream-log-viewer.component';
import { VertexInfoPanelComponent } from './video-process-job-detail/vertex-info-panel/vertex-info-panel.component';
import { DownloadJobDetailComponent } from './download-manager/download-job-detail/download-job-detail.component';
import { DownloadEditorComponent } from './bangumi-detail/universal-builder/download-editor/download-editor.component';


@NgModule({
Expand Down Expand Up @@ -112,7 +113,8 @@ import { DownloadJobDetailComponent } from './download-manager/download-job-deta
VertexGraphComponent,
StreamLogViewerComponent,
VertexInfoPanelComponent,
DownloadJobDetailComponent
DownloadJobDetailComponent,
DownloadEditorComponent
],
providers: [
AdminService,
Expand Down Expand Up @@ -156,7 +158,8 @@ import { DownloadJobDetailComponent } from './download-manager/download-job-deta
VideoProcessRuleEditorComponent,
FileMappingListComponent,
VertexInfoPanelComponent,
DownloadJobDetailComponent
DownloadJobDetailComponent,
DownloadEditorComponent
]
})
export class AdminModule {
Expand Down
8 changes: 8 additions & 0 deletions src/app/admin/admin.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,12 @@ export class AdminService extends BaseService {
return this.http.put<any>(`${this.baseUrl}/video-file/${videoFile.id}`, videoFile).pipe(
catchError(this.handleError),);
}

downloadDirectly(bangumi_id: string,
urlEpsList: {download_url: string, eps_no: number, file_path: string, file_name: string}[]): Observable<any> {
return this.http.post<any>(`${this.baseUrl}/download-directly`, {
bangumi_id,
url_eps_list: urlEpsList
}).pipe(catchError(this.handleError),);
}
}
30 changes: 20 additions & 10 deletions src/app/admin/bangumi-detail/bangumi-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Title } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router';
import { UIDialog, UIToast, UIToastComponent, UIToastRef } from '@irohalab/deneb-ui';
import { Subscription } from 'rxjs';
import { filter, mergeMap } from 'rxjs/operators';
import { filter, mergeMap, tap } from 'rxjs/operators';
import { BaseError } from '../../../helpers/error';
import { Bangumi, Episode } from '../../entity';
import { Announce } from '../../entity/announce';
Expand Down Expand Up @@ -227,16 +227,26 @@ export class BangumiDetail implements OnInit, OnDestroy {
filter((result: any) => !!result),
mergeMap((result: any) => {
this.isLoading = true;
this.bangumi.universal = JSON.stringify(result.result);
return this._adminService.updateBangumi(this.bangumi);
if (result.result === UniversalBuilderComponent.DIALOG_RESULT_DOWNLOAD_DIRECTLY) {
return this._adminService.getBangumi(this.bangumi.id)
.pipe(tap((bangumi) => {
this.bangumi = bangumi;
}));
} else {
this.bangumi.universal = JSON.stringify(result.data);
return this._adminService.updateBangumi(this.bangumi);
}
}),)
.subscribe(() => {
this.isLoading = false;
this._toastRef.show('更新成功');
this.updateAvailableModeCount();
}, (error) => {
this.isLoading = false;
this._toastRef.show(error.message);
.subscribe({
next: () => {
this.isLoading = false;
this._toastRef.show('更新成功');
this.updateAvailableModeCount();
},
error: (error) => {
this.isLoading = false;
this._toastRef.show(error.message);
}
})
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/admin/bangumi-detail/feed.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class FeedService extends BaseService {
catchError(this.handleError),);
}

queryUniversal<T>(mode: string, keyword: string): Observable<Array<Item>> {
queryUniversal<T>(mode: string, keyword: string): Observable<Item[]> {
return this.http.post<{data: Array<Item>, status: number}>(`${this.baseUrl}/universal`, {mode, keyword}).pipe(
map(res => res.data),
catchError(this.handleError),);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { MediaFile } from '../../../../entity/MediaFile';
import { UIDialogRef, UIToast, UIToastComponent, UIToastRef } from '@irohalab/deneb-ui';
import { Subscription } from 'rxjs';
import { AdminService } from '../../../admin.service';
import { Item } from '../../../../entity/item';
import { copyElementValueToClipboard } from '../../../../../helpers/clipboard';

@Component({
selector: 'download-editor',
templateUrl: './download-editor.html',
styleUrls: ['./download-editor.less']
})
export class DownloadEditorComponent implements OnDestroy {
private _subscription = new Subscription();
private _toastRef: UIToastRef<UIToastComponent>;

torrentTitle: string;
downloadUrl: string;

files: MediaFile[];

eps_mapping: {eps_no: number, format: string, selected: boolean}[];

bangumi_id: string;

@ViewChild('downloadUrlTextBox', {static: true}) _downloadUrlTextBoxRef: ElementRef;

constructor(private _adminService: AdminService,
private _dialogRef: UIDialogRef<DownloadEditorComponent>,
toast: UIToast) {
this._toastRef = toast.makeText();
}
copyDownloadUrlToClipboard(): void {
const downloadUrlInput = this._downloadUrlTextBoxRef.nativeElement;
copyElementValueToClipboard(downloadUrlInput)
this._toastRef.show('已经复制到剪贴板');
}
download(): void {
this._subscription.add(
this._adminService.downloadDirectly(
this.bangumi_id,
this.eps_mapping.filter(mapping => mapping.selected).map((mapping, idx) => {
return {
download_url: this.downloadUrl,
eps_no: mapping.eps_no,
file_path: this.files[idx].path,
file_name: this.files[idx].name
};
}))
.subscribe({
next: () => {
this._dialogRef.close(true);
},
error: (error) => {
this._toastRef.show(error?.message);
}
})
);
}

cancel(): void {
this._dialogRef.close(false);
}

ngOnDestroy(): void {
this._subscription.unsubscribe();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<div class="download-editor-container">
<div class="torrent-info-wrapper">
<h3 class="torrent-name">{{torrentTitle}}</h3>
<div class="download-url-wrapper ui mini fluid icon input">
<input class="download-url" type="text" [value]="downloadUrl" #downloadUrlTextBox />
<i class="copy outline link icon" (click)="copyDownloadUrlToClipboard()"></i>
</div>
</div>
<div class="file-list-wrapper">
<table class="file-list-table ui striped table">
<thead>
<tr>
<th>File Path</th>
<th>Size</th>
<th>Episode</th>
<th>Select</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let file of files; index as i">
<td>{{file.path}}</td>
<td>{{file.size | readableUnit:'byte':2}}</td>
<td class="episode-number"><input type="number" [(ngModel)]="eps_mapping[i].eps_no" /></td>
<td>
<div class="ui checkbox">
<input type="checkbox" [(ngModel)]="eps_mapping[i].selected">
<label></label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="footer">
<button class="ui button" (click)="cancel()">取消</button>
<button class="ui primary button" (click)="download()">下载</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
.download-editor-container {
text-align: left;
@media(max-width: 767px) {
width: 100%;
}
@media(min-width: 768px) and (max-width: 991px) {
width: 723px;
}
@media(min-width: 992px) and (max-width: 1200px) {
width: 933px;
}
@media(min-width: 1201px) and (max-width: 1599px){
width: 1127px;
}
@media(min-width: 1601px) {
width: 1600px;
}
@media(min-height: 700px) {
height: 80%;
}
@media(max-height: 639px) {
height: 100%;
}
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
position: absolute;
border-radius: 4px;
background-color: #fff;
overflow: hidden;
padding-top: 5rem;
.ui.dropdown .menu {
z-index: 310;
}
}

.torrent-info-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 5rem;
border-bottom: 1px solid #cccccc;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
background-color: #ffffff;
.torrent-name {
margin: 0.5rem 0.6rem;
}
.download-url-wrapper {
margin-left: 0.6rem;
margin-right: 0.6rem;
}
}

.file-list-wrapper {
position: relative;
height: 100%;
width: 100%;
padding-bottom: 5rem;
overflow-y: scroll;
overflow-x: auto;

td.episode-number > input[type=number] {
width: 4.5em;
}
}

.footer {
position: absolute;
width: 100%;
height: 5rem;
left: 0;
bottom: 0;
padding-right: 1rem;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
border-top: 1px solid #e2e2e2;
background-color: #fff;
z-index: 220;
> .ui.button {
margin-right: 2rem;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { UIDialogRef, UIToast, UIToastComponent, UIToastRef } from '@irohalab/deneb-ui';
import { UIDialog, UIDialogRef, UIToast, UIToastComponent, UIToastRef } from '@irohalab/deneb-ui';
import { Subscription } from 'rxjs';
import { Bangumi } from '../../../entity';
import { Bangumi, Episode } from '../../../entity';
import { Item } from '../../../entity/item';
import { FeedService } from '../feed.service';
import { DownloadEditorComponent } from './download-editor/download-editor.component';

@Component({
selector: 'universal-builder',
Expand All @@ -26,7 +27,8 @@ export class UniversalBuilderComponent implements OnInit, OnDestroy {
@Input()
mode: string;

itemList: Array<Item>;
tableItemList: Item[];
itemList: Item[];

keywordControl: FormControl;

Expand All @@ -35,8 +37,13 @@ export class UniversalBuilderComponent implements OnInit, OnDestroy {
isSearching: boolean;
noResultFound: boolean;

static DIALOG_RESULT_UPDATE_BANGUMI = 'update_bangumi';
static DIALOG_RESULT_DOWNLOAD_DIRECTLY = 'download_directly';
static DIALOG_RESULT_DELETE = 'delete';

constructor(private _feedService: FeedService,
private _dialogRef: UIDialogRef<UniversalBuilderComponent>,
private _uiDialog: UIDialog,
toast: UIToast) {
this._toastRef = toast.makeText();
}
Expand All @@ -53,7 +60,7 @@ export class UniversalBuilderComponent implements OnInit, OnDestroy {
break;
}
}
this._dialogRef.close({result: universalList});
this._dialogRef.close({result: UniversalBuilderComponent.DIALOG_RESULT_DELETE, data: universalList});
}

ngOnDestroy(): void {
Expand Down Expand Up @@ -111,7 +118,7 @@ export class UniversalBuilderComponent implements OnInit, OnDestroy {
} else {
universalList.push(result);
}
this._dialogRef.close({result: universalList});
this._dialogRef.close({result: UniversalBuilderComponent.DIALOG_RESULT_UPDATE_BANGUMI, data: universalList});
}

selectMode(mode: string): void {
Expand All @@ -138,4 +145,30 @@ export class UniversalBuilderComponent implements OnInit, OnDestroy {
})
);
}

downloadItemDirectly(index: number, item: Item): void {
const dialogRef = this._uiDialog.open(DownloadEditorComponent, {stickyDialog: true, backdrop: true});
dialogRef.componentInstance.files = item.files
dialogRef.componentInstance.eps_mapping = item.eps_no_list.map(entry => {
const episode = this.bangumi.episodes.find(eps => {
return eps.episode_no === entry.eps_no;
})
return {
eps_no: entry.eps_no,
format: entry.format,
selected: episode ? episode.status === Episode.STATUS_NOT_DOWNLOADED : false};
});
dialogRef.componentInstance.downloadUrl = item.magnet_uri;
dialogRef.componentInstance.bangumi_id = this.bangumi.id;
dialogRef.componentInstance.torrentTitle = item.title;

this._subscription.add(dialogRef.afterClosed().subscribe({
next: (result: boolean) => {
if (result) {
this._toastRef.show('已添加下载');
this._dialogRef.close({result: UniversalBuilderComponent.DIALOG_RESULT_DOWNLOAD_DIRECTLY});
}
}
}));
}
}
Loading

0 comments on commit 2e75b3d

Please sign in to comment.