mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-10 23:00:57 +03:00
Fixed bug that caused normal archive to be used in multi-user mode Updated login logic when username is not found or user file is missing Fixed bug that prevented playlist sharing from working Added ability to use timestamps when sharing videos
488 lines
18 KiB
TypeScript
488 lines
18 KiB
TypeScript
import {Injectable, isDevMode, Inject} from '@angular/core';
|
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
|
import 'rxjs/add/operator/map';
|
|
import 'rxjs/add/operator/map';
|
|
import 'rxjs/add/operator/catch';
|
|
import 'rxjs/add/observable/throw';
|
|
import { THEMES_CONFIG } from '../themes';
|
|
import { Router, CanActivate } from '@angular/router';
|
|
import { DOCUMENT } from '@angular/common';
|
|
import { BehaviorSubject } from 'rxjs';
|
|
import { v4 as uuid } from 'uuid';
|
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
import * as Fingerprint2 from 'fingerprintjs2';
|
|
|
|
@Injectable()
|
|
export class PostsService implements CanActivate {
|
|
path = '';
|
|
audioFolder = '';
|
|
videoFolder = '';
|
|
startPath = null; // 'http://localhost:17442/';
|
|
startPathSSL = null; // 'https://localhost:17442/'
|
|
handShakeComplete = false;
|
|
THEMES_CONFIG = THEMES_CONFIG;
|
|
theme;
|
|
settings_changed = new BehaviorSubject<boolean>(false);
|
|
auth_token = '4241b401-7236-493e-92b5-b72696b9d853';
|
|
session_id = null;
|
|
httpOptions = null;
|
|
http_params: string = null;
|
|
unauthorized = false;
|
|
|
|
debugMode = false;
|
|
|
|
// must be reset after logout
|
|
isLoggedIn = false;
|
|
token = null;
|
|
user = null;
|
|
permissions = null;
|
|
|
|
available_permissions = null;
|
|
|
|
reload_config = new BehaviorSubject<boolean>(false);
|
|
config_reloaded = new BehaviorSubject<boolean>(false);
|
|
service_initialized = new BehaviorSubject<boolean>(false);
|
|
initialized = false;
|
|
|
|
open_create_default_admin_dialog = new BehaviorSubject<boolean>(false);
|
|
|
|
config = null;
|
|
constructor(private http: HttpClient, private router: Router, @Inject(DOCUMENT) private document: Document,
|
|
public snackBar: MatSnackBar) {
|
|
console.log('PostsService Initialized...');
|
|
// this.startPath = window.location.href + '/api/';
|
|
// this.startPathSSL = window.location.href + '/api/';
|
|
this.path = this.document.location.origin + '/api/';
|
|
|
|
if (isDevMode()) {
|
|
this.debugMode = true;
|
|
this.path = 'http://localhost:17442/api/';
|
|
}
|
|
|
|
this.http_params = `apiKey=${this.auth_token}`
|
|
|
|
this.httpOptions = {
|
|
params: new HttpParams({
|
|
fromString: this.http_params
|
|
}),
|
|
};
|
|
|
|
Fingerprint2.get(components => {
|
|
// set identity as user id doesn't necessarily exist
|
|
this.session_id = Fingerprint2.x64hash128(components.map(function (pair) { return pair.value; }).join(), 31);
|
|
this.httpOptions.params = this.httpOptions.params.set('sessionID', this.session_id);
|
|
});
|
|
|
|
// get config
|
|
this.loadNavItems().subscribe(res => {
|
|
const result = !this.debugMode ? res['config_file'] : res;
|
|
if (result) {
|
|
this.config = result['YoutubeDLMaterial'];
|
|
if (this.config['Advanced']['multi_user_mode']) {
|
|
// login stuff
|
|
if (localStorage.getItem('jwt_token')) {
|
|
this.token = localStorage.getItem('jwt_token');
|
|
this.httpOptions.params = this.httpOptions.params.set('jwt', this.token);
|
|
|
|
this.jwtAuth();
|
|
} else {
|
|
this.sendToLogin();
|
|
}
|
|
} else {
|
|
this.setInitialized();
|
|
}
|
|
}
|
|
});
|
|
|
|
this.reload_config.subscribe(yes_reload => {
|
|
if (yes_reload) { this.reloadConfig(); }
|
|
});
|
|
}
|
|
canActivate(route, state): Promise<boolean> {
|
|
return new Promise(resolve => {
|
|
resolve(true);
|
|
})
|
|
console.log(route);
|
|
throw new Error('Method not implemented.');
|
|
}
|
|
|
|
setTheme(theme) {
|
|
this.theme = this.THEMES_CONFIG[theme];
|
|
}
|
|
|
|
startHandshake(url: string) {
|
|
return this.http.get(url + 'geturl');
|
|
}
|
|
|
|
startHandshakeSSL(url: string) {
|
|
return this.http.get(url + 'geturl');
|
|
}
|
|
|
|
reloadConfig() {
|
|
this.loadNavItems().subscribe(res => {
|
|
const result = !this.debugMode ? res['config_file'] : res;
|
|
if (result) {
|
|
this.config = result['YoutubeDLMaterial'];
|
|
this.config_reloaded.next(true);
|
|
}
|
|
});
|
|
}
|
|
|
|
getVideoFolder() {
|
|
return this.http.get(this.startPath + 'videofolder');
|
|
}
|
|
|
|
getAudioFolder() {
|
|
return this.http.get(this.startPath + 'audiofolder');
|
|
}
|
|
|
|
// 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) {
|
|
return this.http.post(this.path + 'tomp3', {url: url,
|
|
maxBitrate: selectedQuality,
|
|
customQualityConfiguration: customQualityConfiguration,
|
|
customArgs: customArgs,
|
|
customOutput: customOutput,
|
|
youtubeUsername: youtubeUsername,
|
|
youtubePassword: youtubePassword,
|
|
ui_uid: ui_uid}, this.httpOptions);
|
|
}
|
|
|
|
// tslint:disable-next-line: max-line-length
|
|
makeMP4(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 + 'tomp4', {url: url,
|
|
selectedHeight: selectedQuality,
|
|
customQualityConfiguration: customQualityConfiguration,
|
|
customArgs: customArgs,
|
|
customOutput: customOutput,
|
|
youtubeUsername: youtubeUsername,
|
|
youtubePassword: youtubePassword,
|
|
ui_uid: ui_uid}, this.httpOptions);
|
|
}
|
|
|
|
getFileStatusMp3(name: string) {
|
|
return this.http.post(this.path + 'fileStatusMp3', {name: name}, this.httpOptions);
|
|
}
|
|
|
|
getFileStatusMp4(name: string) {
|
|
return this.http.post(this.path + 'fileStatusMp4', {name: name}, this.httpOptions);
|
|
}
|
|
|
|
loadNavItems() {
|
|
if (isDevMode()) {
|
|
return this.http.get('./assets/default.json');
|
|
} else {
|
|
return this.http.get(this.path + 'config', this.httpOptions);
|
|
}
|
|
}
|
|
|
|
loadAsset(name) {
|
|
return this.http.get(`./assets/${name}`);
|
|
}
|
|
|
|
setConfig(config) {
|
|
return this.http.post(this.path + 'setConfig', {new_config_file: config}, this.httpOptions);
|
|
}
|
|
|
|
deleteFile(uid: string, isAudio: boolean, blacklistMode = false) {
|
|
if (isAudio) {
|
|
return this.http.post(this.path + 'deleteMp3', {uid: uid, blacklistMode: blacklistMode}, this.httpOptions);
|
|
} else {
|
|
return this.http.post(this.path + 'deleteMp4', {uid: uid, blacklistMode: blacklistMode}, this.httpOptions);
|
|
}
|
|
}
|
|
|
|
getMp3s() {
|
|
return this.http.get(this.path + 'getMp3s', this.httpOptions);
|
|
}
|
|
|
|
getMp4s() {
|
|
return this.http.get(this.path + 'getMp4s', this.httpOptions);
|
|
}
|
|
|
|
getFile(uid, type, uuid = null) {
|
|
return this.http.post(this.path + 'getFile', {uid: uid, type: type, uuid: uuid}, this.httpOptions);
|
|
}
|
|
|
|
downloadFileFromServer(fileName, type, outputName = null, fullPathProvided = null, subscriptionName = null, subPlaylist = null,
|
|
uid = null, uuid = null) {
|
|
return this.http.post(this.path + 'downloadFile', {fileNames: fileName,
|
|
type: type,
|
|
zip_mode: Array.isArray(fileName),
|
|
outputName: outputName,
|
|
fullPathProvided: fullPathProvided,
|
|
subscriptionName: subscriptionName,
|
|
subPlaylist: subPlaylist,
|
|
uuid: uuid,
|
|
uid: uid
|
|
},
|
|
{responseType: 'blob', params: this.httpOptions.params});
|
|
}
|
|
|
|
downloadArchive(sub) {
|
|
return this.http.post(this.path + 'downloadArchive', {sub: sub}, {responseType: 'blob', params: this.httpOptions.params});
|
|
}
|
|
|
|
getFileInfo(fileNames, type, urlMode) {
|
|
return this.http.post(this.path + 'getVideoInfos', {fileNames: fileNames, type: type, urlMode: urlMode}, this.httpOptions);
|
|
}
|
|
|
|
isPinSet() {
|
|
return this.http.post(this.path + 'isPinSet', {}, this.httpOptions);
|
|
}
|
|
|
|
setPin(unhashed_pin) {
|
|
return this.http.post(this.path + 'setPin', {pin: unhashed_pin}, this.httpOptions);
|
|
}
|
|
|
|
checkPin(unhashed_pin) {
|
|
return this.http.post(this.path + 'checkPin', {input_pin: unhashed_pin}, this.httpOptions);
|
|
}
|
|
|
|
generateNewAPIKey() {
|
|
return this.http.post(this.path + 'generateNewAPIKey', {}, this.httpOptions);
|
|
}
|
|
|
|
enableSharing(uid, type, is_playlist) {
|
|
return this.http.post(this.path + 'enableSharing', {uid: uid, type: type, is_playlist: is_playlist}, this.httpOptions);
|
|
}
|
|
|
|
disableSharing(uid, type, is_playlist) {
|
|
return this.http.post(this.path + 'disableSharing', {uid: uid, type: type, is_playlist: is_playlist}, this.httpOptions);
|
|
}
|
|
|
|
createPlaylist(playlistName, fileNames, type, thumbnailURL) {
|
|
return this.http.post(this.path + 'createPlaylist', {playlistName: playlistName,
|
|
fileNames: fileNames,
|
|
type: type,
|
|
thumbnailURL: thumbnailURL}, this.httpOptions);
|
|
}
|
|
|
|
getPlaylist(playlistID, type, uuid = null) {
|
|
return this.http.post(this.path + 'getPlaylist', {playlistID: playlistID,
|
|
type: type, uuid: uuid}, this.httpOptions);
|
|
}
|
|
|
|
updatePlaylist(playlistID, fileNames, type) {
|
|
return this.http.post(this.path + 'updatePlaylist', {playlistID: playlistID,
|
|
fileNames: fileNames,
|
|
type: type}, this.httpOptions);
|
|
}
|
|
|
|
removePlaylist(playlistID, type) {
|
|
return this.http.post(this.path + 'deletePlaylist', {playlistID: playlistID, type: type}, this.httpOptions);
|
|
}
|
|
|
|
createSubscription(url, name, timerange = null, streamingOnly = false) {
|
|
return this.http.post(this.path + 'subscribe', {url: url, name: name, timerange: timerange, streamingOnly: streamingOnly},
|
|
this.httpOptions);
|
|
}
|
|
|
|
unsubscribe(sub, deleteMode = false) {
|
|
return this.http.post(this.path + 'unsubscribe', {sub: sub, deleteMode: deleteMode}, this.httpOptions)
|
|
}
|
|
|
|
deleteSubscriptionFile(sub, file, deleteForever) {
|
|
return this.http.post(this.path + 'deleteSubscriptionFile', {sub: sub, file: file, deleteForever: deleteForever}, this.httpOptions)
|
|
}
|
|
|
|
getSubscription(id) {
|
|
return this.http.post(this.path + 'getSubscription', {id: id}, this.httpOptions);
|
|
}
|
|
|
|
getAllSubscriptions() {
|
|
return this.http.post(this.path + 'getAllSubscriptions', {}, this.httpOptions);
|
|
}
|
|
|
|
// current downloads
|
|
getCurrentDownloads() {
|
|
return this.http.get(this.path + 'downloads', this.httpOptions);
|
|
}
|
|
|
|
// current download
|
|
getCurrentDownload(session_id, download_id) {
|
|
return this.http.post(this.path + 'download', {download_id: download_id, session_id: session_id}, this.httpOptions);
|
|
}
|
|
|
|
// clear downloads. download_id is optional, if it exists only 1 download will be cleared
|
|
clearDownloads(delete_all = false, session_id = null, download_id = null) {
|
|
return this.http.post(this.path + 'clearDownloads', {delete_all: delete_all,
|
|
download_id: download_id,
|
|
session_id: session_id ? session_id : this.session_id}, this.httpOptions);
|
|
}
|
|
|
|
// updates the server to the latest version
|
|
updateServer(tag) {
|
|
return this.http.post(this.path + 'updateServer', {tag: tag}, this.httpOptions);
|
|
}
|
|
|
|
getUpdaterStatus() {
|
|
return this.http.get(this.path + 'updaterStatus', this.httpOptions);
|
|
}
|
|
|
|
// gets tag of the latest version of youtubedl-material
|
|
getLatestGithubRelease() {
|
|
return this.http.get('https://api.github.com/repos/tzahi12345/youtubedl-material/releases/latest');
|
|
}
|
|
|
|
getAvailableRelease() {
|
|
return this.http.get('https://api.github.com/repos/tzahi12345/youtubedl-material/releases');
|
|
}
|
|
|
|
afterLogin(user, token, permissions, available_permissions) {
|
|
this.isLoggedIn = true;
|
|
this.user = user;
|
|
this.permissions = permissions;
|
|
this.available_permissions = available_permissions;
|
|
this.token = token;
|
|
this.setInitialized();
|
|
|
|
localStorage.setItem('jwt_token', this.token);
|
|
|
|
this.httpOptions.params = this.httpOptions.params.set('jwt', this.token);
|
|
|
|
// needed to re-initialize parts of app after login
|
|
this.config_reloaded.next(true);
|
|
|
|
if (this.router.url === '/login') {
|
|
this.router.navigate(['/home']);
|
|
}
|
|
}
|
|
|
|
// user methods
|
|
login(username, password) {
|
|
const call = this.http.post(this.path + 'auth/login', {userid: username, password: password}, this.httpOptions);
|
|
call.subscribe(res => {
|
|
if (res['token']) {
|
|
this.afterLogin(res['user'], res['token'], res['permissions'], res['available_permissions']);
|
|
}
|
|
});
|
|
return call;
|
|
}
|
|
|
|
// user methods
|
|
jwtAuth() {
|
|
const call = this.http.post(this.path + 'auth/jwtAuth', {}, this.httpOptions);
|
|
call.subscribe(res => {
|
|
if (res['token']) {
|
|
this.afterLogin(res['user'], res['token'], res['permissions'], res['available_permissions']);
|
|
}
|
|
}, err => {
|
|
if (err.status === 401) {
|
|
this.sendToLogin();
|
|
}
|
|
});
|
|
return call;
|
|
}
|
|
|
|
logout() {
|
|
this.user = null;
|
|
this.permissions = null;
|
|
this.isLoggedIn = false;
|
|
localStorage.setItem('jwt_token', null);
|
|
if (this.router.url !== '/login') {
|
|
this.router.navigate(['/login']);
|
|
}
|
|
|
|
// resets http params
|
|
this.http_params = `apiKey=${this.auth_token}&sessionID=${this.session_id}`
|
|
|
|
this.httpOptions = {
|
|
params: new HttpParams({
|
|
fromString: this.http_params
|
|
}),
|
|
};
|
|
}
|
|
|
|
// user methods
|
|
register(username, password) {
|
|
const call = this.http.post(this.path + 'auth/register', {userid: username,
|
|
username: username,
|
|
password: password}, this.httpOptions);
|
|
/*call.subscribe(res => {
|
|
console.log(res['user']);
|
|
if (res['user']) {
|
|
// this.afterRegistration(res['user']);
|
|
}
|
|
});*/
|
|
return call;
|
|
}
|
|
|
|
sendToLogin() {
|
|
this.checkAdminCreationStatus();
|
|
if (this.router.url === '/login') {
|
|
return;
|
|
}
|
|
|
|
this.router.navigate(['/login']);
|
|
|
|
// send login notification
|
|
this.openSnackBar('You must log in to access this page!');
|
|
}
|
|
|
|
setInitialized() {
|
|
this.service_initialized.next(true);
|
|
this.initialized = true;
|
|
this.config_reloaded.next(true);
|
|
}
|
|
|
|
adminExists() {
|
|
return this.http.post(this.path + 'auth/adminExists', {}, this.httpOptions);
|
|
}
|
|
|
|
createAdminAccount(password) {
|
|
return this.http.post(this.path + 'auth/register', {userid: 'admin',
|
|
username: 'admin',
|
|
password: password}, this.httpOptions);
|
|
}
|
|
|
|
checkAdminCreationStatus(skip_check = false) {
|
|
if (!skip_check && !this.config['Advanced']['multi_user_mode']) {
|
|
return;
|
|
}
|
|
this.adminExists().subscribe(res => {
|
|
if (!res['exists']) {
|
|
// must create admin account
|
|
this.open_create_default_admin_dialog.next(true);
|
|
}
|
|
});
|
|
}
|
|
|
|
changeUser(change_obj) {
|
|
return this.http.post(this.path + 'changeUser', {change_object: change_obj}, this.httpOptions);
|
|
}
|
|
|
|
deleteUser(uid) {
|
|
return this.http.post(this.path + 'deleteUser', {uid: uid}, this.httpOptions);
|
|
}
|
|
|
|
changeUserPassword(user_uid, new_password) {
|
|
return this.http.post(this.path + 'auth/changePassword', {user_uid: user_uid, new_password: new_password}, this.httpOptions);
|
|
}
|
|
|
|
getUsers() {
|
|
return this.http.post(this.path + 'getUsers', {}, this.httpOptions);
|
|
}
|
|
|
|
getRoles() {
|
|
return this.http.post(this.path + 'getRoles', {}, this.httpOptions);
|
|
}
|
|
|
|
setUserPermission(user_uid, permission, new_value) {
|
|
return this.http.post(this.path + 'changeUserPermissions', {user_uid: user_uid, permission: permission, new_value: new_value},
|
|
this.httpOptions);
|
|
}
|
|
|
|
setRolePermission(role_name, permission, new_value) {
|
|
return this.http.post(this.path + 'changeRolePermissions', {role: role_name, permission: permission, new_value: new_value},
|
|
this.httpOptions);
|
|
}
|
|
|
|
public openSnackBar(message: string, action: string = '') {
|
|
this.snackBar.open(message, action, {
|
|
duration: 2000,
|
|
});
|
|
}
|
|
|
|
}
|