mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-04-12 08:51:30 +03:00
Compare commits
5 Commits
downloader
...
kodi-integ
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a623012901 | ||
|
|
95e53b9549 | ||
|
|
46ed0fe992 | ||
|
|
082252ab1e | ||
|
|
5eccaa13e5 |
@@ -26,6 +26,9 @@ function registerFileDB(file_path, type, multiUserMode = null, sub = null) {
|
|||||||
|
|
||||||
utils.fixVideoMetadataPerms(file_id, type, multiUserMode && multiUserMode.file_path);
|
utils.fixVideoMetadataPerms(file_id, type, multiUserMode && multiUserMode.file_path);
|
||||||
|
|
||||||
|
// creates XML if kodi support is enabled
|
||||||
|
if (true) utils.generateNFOFile(file_id, type, multiUserMode && multiUserMode.file_path);
|
||||||
|
|
||||||
// add thumbnail path
|
// add thumbnail path
|
||||||
file_object['thumbnailPath'] = utils.getDownloadedThumbnail(file_id, type, multiUserMode && multiUserMode.file_path);
|
file_object['thumbnailPath'] = utils.getDownloadedThumbnail(file_id, type, multiUserMode && multiUserMode.file_path);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
var fs = require('fs-extra')
|
var fs = require('fs-extra')
|
||||||
var path = require('path')
|
var path = require('path')
|
||||||
const config_api = require('./config');
|
const config_api = require('./config');
|
||||||
|
const { create } = require('xmlbuilder2');
|
||||||
|
|
||||||
const is_windows = process.platform === 'win32';
|
const is_windows = process.platform === 'win32';
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ function getDownloadedFilesByType(basePath, type) {
|
|||||||
var located_files = recFindByExt(basePath, ext);
|
var located_files = recFindByExt(basePath, ext);
|
||||||
for (let i = 0; i < located_files.length; i++) {
|
for (let i = 0; i < located_files.length; i++) {
|
||||||
let file = located_files[i];
|
let file = located_files[i];
|
||||||
var file_path = path.basename(file);
|
var file_path = file.substring(basePath.includes('\\') ? basePath.length+1 : basePath.length, file.length);
|
||||||
|
|
||||||
var stats = fs.statSync(file);
|
var stats = fs.statSync(file);
|
||||||
|
|
||||||
@@ -145,6 +146,35 @@ function fixVideoMetadataPerms(name, type, customPath = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateNFOFile(file_id, type, customPath = null) {
|
||||||
|
if (!customPath) customPath = type === 'audio' ? config_api.getConfigItem('ytdl_audio_folder_path')
|
||||||
|
: config_api.getConfigItem('ytdl_video_folder_path');
|
||||||
|
|
||||||
|
const file_obj = getJSONByType(type, file_id, customPath);
|
||||||
|
|
||||||
|
const target_dir = path.dirname(file_obj['_filename']);
|
||||||
|
|
||||||
|
const file_name = path.basename(file_obj['_filename']);
|
||||||
|
const target_file_name = file_name.substring(0, file_name.length-4) + '.nfo';
|
||||||
|
|
||||||
|
const xml_obj = {
|
||||||
|
episodedetails: {
|
||||||
|
title: file_obj['fulltitle'],
|
||||||
|
episode: file_obj['playlist_index'] ? file_obj['playlist_index'] : undefined,
|
||||||
|
premiered: file_obj['upload_date'],
|
||||||
|
plot: `${file_obj['uploader_url']}\n${file_obj['description']}\n${file_obj['playlist_title']}`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const generated_xml = create(xml_obj).end({prettyPrint: true});
|
||||||
|
|
||||||
|
const xml_parts = generated_xml.split('\n');
|
||||||
|
xml_parts[0] = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
|
||||||
|
const final_xml = xml_parts.join('\n');
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(target_dir, target_file_name), final_xml);
|
||||||
|
}
|
||||||
|
|
||||||
function deleteJSONFile(name, type, customPath = null) {
|
function deleteJSONFile(name, type, customPath = null) {
|
||||||
if (!customPath) customPath = type === 'audio' ? config_api.getConfigItem('ytdl_audio_folder_path')
|
if (!customPath) customPath = type === 'audio' ? config_api.getConfigItem('ytdl_audio_folder_path')
|
||||||
: config_api.getConfigItem('ytdl_video_folder_path');
|
: config_api.getConfigItem('ytdl_video_folder_path');
|
||||||
@@ -204,6 +234,7 @@ module.exports = {
|
|||||||
getDownloadedThumbnail: getDownloadedThumbnail,
|
getDownloadedThumbnail: getDownloadedThumbnail,
|
||||||
getExpectedFileSize: getExpectedFileSize,
|
getExpectedFileSize: getExpectedFileSize,
|
||||||
fixVideoMetadataPerms: fixVideoMetadataPerms,
|
fixVideoMetadataPerms: fixVideoMetadataPerms,
|
||||||
|
generateNFOFile: generateNFOFile,
|
||||||
deleteJSONFile: deleteJSONFile,
|
deleteJSONFile: deleteJSONFile,
|
||||||
getDownloadedFilesByType: getDownloadedFilesByType,
|
getDownloadedFilesByType: getDownloadedFilesByType,
|
||||||
recFindByExt: recFindByExt,
|
recFindByExt: recFindByExt,
|
||||||
|
|||||||
@@ -38,15 +38,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="sidenav-container" style="height: calc(100% - 64px)">
|
<div class="sidenav-container" style="height: calc(100% - 64px)">
|
||||||
<mat-sidenav-container style="height: 100%">
|
<mat-sidenav-container style="height: 100%">
|
||||||
<mat-sidenav [opened]="postsService.sidepanel_mode === 'side' && router.url === '/home'" [mode]="postsService.sidepanel_mode" #sidenav>
|
<mat-sidenav [opened]="postsService.sidepanel_mode === 'side' && !window.location.href.includes('/player')" [mode]="postsService.sidepanel_mode" #sidenav>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<a *ngIf="postsService.config && (!postsService.config.Advanced.multi_user_mode || postsService.isLoggedIn)" mat-list-item (click)="sidenav.close()" routerLink='/home'><ng-container i18n="Navigation menu Home Page title">Home</ng-container></a>
|
<a *ngIf="postsService.config && (!postsService.config.Advanced.multi_user_mode || postsService.isLoggedIn)" mat-list-item (click)="postsService.sidepanel_mode === 'over' ? sidenav.close() : null" routerLink='/home'><ng-container i18n="Navigation menu Home Page title">Home</ng-container></a>
|
||||||
<a *ngIf="postsService.config && postsService.config.Advanced.multi_user_mode && !postsService.isLoggedIn" mat-list-item (click)="sidenav.close()" routerLink='/login'><ng-container i18n="Navigation menu Login Page title">Login</ng-container></a>
|
<a *ngIf="postsService.config && postsService.config.Advanced.multi_user_mode && !postsService.isLoggedIn" mat-list-item (click)="sidenav.close()" routerLink='/login'><ng-container i18n="Navigation menu Login Page title">Login</ng-container></a>
|
||||||
<a *ngIf="postsService.config && allowSubscriptions && (!postsService.config.Advanced.multi_user_mode || (postsService.isLoggedIn && postsService.permissions.includes('subscriptions')))" mat-list-item (click)="sidenav.close()" routerLink='/subscriptions'><ng-container i18n="Navigation menu Subscriptions Page title">Subscriptions</ng-container></a>
|
<a *ngIf="postsService.config && allowSubscriptions && (!postsService.config.Advanced.multi_user_mode || (postsService.isLoggedIn && postsService.permissions.includes('subscriptions')))" mat-list-item (click)="postsService.sidepanel_mode === 'over' ? sidenav.close() : null" routerLink='/subscriptions'><ng-container i18n="Navigation menu Subscriptions Page title">Subscriptions</ng-container></a>
|
||||||
<a *ngIf="postsService.config && enableDownloadsManager && (!postsService.config.Advanced.multi_user_mode || (postsService.isLoggedIn && postsService.permissions.includes('downloads_manager')))" mat-list-item (click)="sidenav.close()" routerLink='/downloads'><ng-container i18n="Navigation menu Downloads Page title">Downloads</ng-container></a>
|
<a *ngIf="postsService.config && enableDownloadsManager && (!postsService.config.Advanced.multi_user_mode || (postsService.isLoggedIn && postsService.permissions.includes('downloads_manager')))" mat-list-item (click)="postsService.sidepanel_mode === 'over' ? sidenav.close() : null" routerLink='/downloads'><ng-container i18n="Navigation menu Downloads Page title">Downloads</ng-container></a>
|
||||||
<ng-container *ngIf="postsService.config && allowSubscriptions && postsService.subscriptions && (!postsService.config.Advanced.multi_user_mode || (postsService.isLoggedIn && postsService.permissions.includes('subscriptions')))">
|
<ng-container *ngIf="postsService.config && allowSubscriptions && postsService.subscriptions && (!postsService.config.Advanced.multi_user_mode || (postsService.isLoggedIn && postsService.permissions.includes('subscriptions')))">
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<a *ngFor="let subscription of postsService.subscriptions" mat-list-item (click)="sidenav.close()" [routerLink]="['/subscription', { id: subscription.id }]"><ngx-avatar [style.margin-right]="'10px'" size="32" [name]="subscription.name"></ngx-avatar><ng-container i18n="Navigation menu Downloads Page title">{{subscription.name}}</ng-container></a>
|
<a *ngFor="let subscription of postsService.subscriptions" mat-list-item (click)="postsService.sidepanel_mode === 'over' ? sidenav.close() : null" [routerLink]="['/subscription', { id: subscription.id }]"><ngx-avatar [style.margin-right]="'10px'" size="32" [name]="subscription.name"></ngx-avatar><ng-container i18n="Navigation menu Downloads Page title">{{subscription.name}}</ng-container></a>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
</mat-sidenav>
|
</mat-sidenav>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, ElementRef, ViewChild, HostBinding } from '@angular/core';
|
import { Component, OnInit, ElementRef, ViewChild, HostBinding, AfterViewInit } from '@angular/core';
|
||||||
import {PostsService} from './posts.services';
|
import {PostsService} from './posts.services';
|
||||||
import {FileCardComponent} from './file-card/file-card.component';
|
import {FileCardComponent} from './file-card/file-card.component';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
@@ -30,11 +30,13 @@ import { SetDefaultAdminDialogComponent } from './dialogs/set-default-admin-dial
|
|||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
@HostBinding('class') componentCssClass;
|
@HostBinding('class') componentCssClass;
|
||||||
THEMES_CONFIG = THEMES_CONFIG;
|
THEMES_CONFIG = THEMES_CONFIG;
|
||||||
|
|
||||||
|
window = window;
|
||||||
|
|
||||||
// config items
|
// config items
|
||||||
topBarTitle = 'Youtube Downloader';
|
topBarTitle = 'Youtube Downloader';
|
||||||
defaultTheme = null;
|
defaultTheme = null;
|
||||||
@@ -69,6 +71,29 @@ export class AppComponent implements OnInit {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
if (localStorage.getItem('theme')) {
|
||||||
|
this.setTheme(localStorage.getItem('theme'));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.postsService.open_create_default_admin_dialog.subscribe(open => {
|
||||||
|
if (open) {
|
||||||
|
const dialogRef = this.dialog.open(SetDefaultAdminDialogComponent);
|
||||||
|
dialogRef.afterClosed().subscribe(success => {
|
||||||
|
if (success) {
|
||||||
|
if (this.router.url !== '/login') { this.router.navigate(['/login']); }
|
||||||
|
} else {
|
||||||
|
console.error('Failed to create default admin account. See logs for details.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
this.postsService.sidenav = this.sidenav;
|
||||||
|
}
|
||||||
|
|
||||||
toggleSidenav() {
|
toggleSidenav() {
|
||||||
this.sidenav.toggle();
|
this.sidenav.toggle();
|
||||||
}
|
}
|
||||||
@@ -122,9 +147,9 @@ export class AppComponent implements OnInit {
|
|||||||
this.postsService.setTheme(theme);
|
this.postsService.setTheme(theme);
|
||||||
|
|
||||||
this.onSetTheme(this.THEMES_CONFIG[theme]['css_label'], old_theme ? this.THEMES_CONFIG[old_theme]['css_label'] : old_theme);
|
this.onSetTheme(this.THEMES_CONFIG[theme]['css_label'], old_theme ? this.THEMES_CONFIG[old_theme]['css_label'] : old_theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSetTheme(theme, old_theme) {
|
onSetTheme(theme, old_theme) {
|
||||||
if (old_theme) {
|
if (old_theme) {
|
||||||
document.body.classList.remove(old_theme);
|
document.body.classList.remove(old_theme);
|
||||||
this.overlayContainer.getContainerElement().classList.remove(old_theme);
|
this.overlayContainer.getContainerElement().classList.remove(old_theme);
|
||||||
@@ -146,27 +171,6 @@ onSetTheme(theme, old_theme) {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
if (localStorage.getItem('theme')) {
|
|
||||||
this.setTheme(localStorage.getItem('theme'));
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
this.postsService.open_create_default_admin_dialog.subscribe(open => {
|
|
||||||
if (open) {
|
|
||||||
const dialogRef = this.dialog.open(SetDefaultAdminDialogComponent);
|
|
||||||
dialogRef.afterClosed().subscribe(success => {
|
|
||||||
if (success) {
|
|
||||||
if (this.router.url !== '/login') { this.router.navigate(['/login']); }
|
|
||||||
} else {
|
|
||||||
console.error('Failed to create default admin account. See logs for details.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
getSubscriptions() {
|
getSubscriptions() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, HostListener, EventEmitter, OnDestroy } from '@angular/core';
|
import { Component, OnInit, HostListener, EventEmitter, OnDestroy, AfterViewInit } from '@angular/core';
|
||||||
import { VgAPI } from 'ngx-videogular';
|
import { VgAPI } from 'ngx-videogular';
|
||||||
import { PostsService } from 'app/posts.services';
|
import { PostsService } from 'app/posts.services';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
@@ -20,7 +20,7 @@ export interface IMedia {
|
|||||||
templateUrl: './player.component.html',
|
templateUrl: './player.component.html',
|
||||||
styleUrls: ['./player.component.css']
|
styleUrls: ['./player.component.css']
|
||||||
})
|
})
|
||||||
export class PlayerComponent implements OnInit, OnDestroy {
|
export class PlayerComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||||
|
|
||||||
playlist: Array<IMedia> = [];
|
playlist: Array<IMedia> = [];
|
||||||
original_playlist: string = null;
|
original_playlist: string = null;
|
||||||
@@ -95,6 +95,10 @@ export class PlayerComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
this.postsService.sidenav.close();
|
||||||
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
// prevents volume save feature from running in the background
|
// prevents volume save feature from running in the background
|
||||||
clearInterval(this.save_volume_timer);
|
clearInterval(this.save_volume_timer);
|
||||||
|
|||||||
@@ -15,16 +15,14 @@ import * as Fingerprint2 from 'fingerprintjs2';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class PostsService implements CanActivate {
|
export class PostsService implements CanActivate {
|
||||||
path = '';
|
path = '';
|
||||||
audioFolder = '';
|
|
||||||
videoFolder = '';
|
// local settings
|
||||||
startPath = null; // 'http://localhost:17442/';
|
|
||||||
startPathSSL = null; // 'https://localhost:17442/'
|
|
||||||
handShakeComplete = false;
|
|
||||||
THEMES_CONFIG = THEMES_CONFIG;
|
THEMES_CONFIG = THEMES_CONFIG;
|
||||||
theme;
|
theme;
|
||||||
card_size = 'medium';
|
card_size = 'medium';
|
||||||
sidepanel_mode = 'over';
|
sidepanel_mode = 'over';
|
||||||
settings_changed = new BehaviorSubject<boolean>(false);
|
|
||||||
|
// auth
|
||||||
auth_token = '4241b401-7236-493e-92b5-b72696b9d853';
|
auth_token = '4241b401-7236-493e-92b5-b72696b9d853';
|
||||||
session_id = null;
|
session_id = null;
|
||||||
httpOptions = null;
|
httpOptions = null;
|
||||||
@@ -41,20 +39,24 @@ export class PostsService implements CanActivate {
|
|||||||
|
|
||||||
available_permissions = null;
|
available_permissions = null;
|
||||||
|
|
||||||
|
// behavior subjects
|
||||||
reload_config = new BehaviorSubject<boolean>(false);
|
reload_config = new BehaviorSubject<boolean>(false);
|
||||||
config_reloaded = new BehaviorSubject<boolean>(false);
|
config_reloaded = new BehaviorSubject<boolean>(false);
|
||||||
service_initialized = new BehaviorSubject<boolean>(false);
|
service_initialized = new BehaviorSubject<boolean>(false);
|
||||||
initialized = false;
|
settings_changed = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
open_create_default_admin_dialog = new BehaviorSubject<boolean>(false);
|
open_create_default_admin_dialog = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
|
// app status
|
||||||
|
initialized = false;
|
||||||
|
|
||||||
|
// global vars
|
||||||
config = null;
|
config = null;
|
||||||
subscriptions = null;
|
subscriptions = null;
|
||||||
|
sidenav = null;
|
||||||
|
|
||||||
constructor(private http: HttpClient, private router: Router, @Inject(DOCUMENT) private document: Document,
|
constructor(private http: HttpClient, private router: Router, @Inject(DOCUMENT) private document: Document,
|
||||||
public snackBar: MatSnackBar) {
|
public snackBar: MatSnackBar) {
|
||||||
console.log('PostsService Initialized...');
|
console.log('PostsService Initialized...');
|
||||||
// this.startPath = window.location.href + '/api/';
|
|
||||||
// this.startPathSSL = window.location.href + '/api/';
|
|
||||||
this.path = this.document.location.origin + '/api/';
|
this.path = this.document.location.origin + '/api/';
|
||||||
|
|
||||||
if (isDevMode()) {
|
if (isDevMode()) {
|
||||||
@@ -152,14 +154,6 @@ export class PostsService implements CanActivate {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoFolder() {
|
|
||||||
return this.http.get(this.startPath + 'videofolder');
|
|
||||||
}
|
|
||||||
|
|
||||||
getAudioFolder() {
|
|
||||||
return this.http.get(this.startPath + 'audiofolder');
|
|
||||||
}
|
|
||||||
|
|
||||||
// tslint:disable-next-line: max-line-length
|
// tslint:disable-next-line: max-line-length
|
||||||
makeMP3(url: string, selectedQuality: string, customQualityConfiguration: string, customArgs: string = null, customOutput: string = null, youtubeUsername: string = null, youtubePassword: string = null, ui_uid = null) {
|
makeMP3(url: string, selectedQuality: string, customQualityConfiguration: string, customArgs: string = null, customOutput: string = null, youtubeUsername: string = null, youtubePassword: string = null, ui_uid = null) {
|
||||||
return this.http.post(this.path + 'tomp3', {url: url,
|
return this.http.post(this.path + 'tomp3', {url: url,
|
||||||
|
|||||||
Reference in New Issue
Block a user