mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-04-10 12:01:29 +03:00
Categories will now auto-generate playlists
This commit is contained in:
@@ -79,7 +79,7 @@ const logger = winston.createLogger({
|
|||||||
});
|
});
|
||||||
|
|
||||||
config_api.initialize(logger);
|
config_api.initialize(logger);
|
||||||
auth_api.initialize(users_db, logger);
|
auth_api.initialize(db, users_db, logger);
|
||||||
db_api.initialize(db, users_db, logger);
|
db_api.initialize(db, users_db, logger);
|
||||||
subscriptions_api.initialize(db, users_db, logger, db_api);
|
subscriptions_api.initialize(db, users_db, logger, db_api);
|
||||||
categories_api.initialize(db, users_db, logger, db_api);
|
categories_api.initialize(db, users_db, logger, db_api);
|
||||||
@@ -1215,7 +1215,7 @@ async function downloadFileByURL_exec(url, type, options, sessionID = null) {
|
|||||||
const customPath = options.noRelativePath ? path.dirname(full_file_path).split(path.sep).pop() : null;
|
const customPath = options.noRelativePath ? path.dirname(full_file_path).split(path.sep).pop() : null;
|
||||||
|
|
||||||
// registers file in DB
|
// registers file in DB
|
||||||
file_uid = db_api.registerFileDB(file_path, type, multiUserMode, null, customPath);
|
file_uid = db_api.registerFileDB(file_path, type, multiUserMode, null, customPath, category);
|
||||||
|
|
||||||
if (file_name) file_names.push(file_name);
|
if (file_name) file_names.push(file_name);
|
||||||
}
|
}
|
||||||
@@ -2014,10 +2014,37 @@ app.post('/api/getAllFiles', optionalJwt, async function (req, res) {
|
|||||||
// get basic info depending on multi-user mode being enabled
|
// get basic info depending on multi-user mode being enabled
|
||||||
if (req.isAuthenticated()) {
|
if (req.isAuthenticated()) {
|
||||||
files = auth_api.getUserVideos(req.user.uid);
|
files = auth_api.getUserVideos(req.user.uid);
|
||||||
playlists = auth_api.getUserPlaylists(req.user.uid);
|
playlists = auth_api.getUserPlaylists(req.user.uid, files);
|
||||||
} else {
|
} else {
|
||||||
files = db.get('files').value();
|
files = db.get('files').value();
|
||||||
playlists = db.get('playlists').value();
|
playlists = JSON.parse(JSON.stringify(db.get('playlists').value()));
|
||||||
|
const categories = db.get('categories').value();
|
||||||
|
if (categories) {
|
||||||
|
categories.forEach(category => {
|
||||||
|
const audio_files = files && files.filter(file => file.category && file.category.uid === category.uid && file.isAudio);
|
||||||
|
const video_files = files && files.filter(file => file.category && file.category.uid === category.uid && !file.isAudio);
|
||||||
|
if (audio_files && audio_files.length > 0) {
|
||||||
|
playlists.push({
|
||||||
|
name: category['name'],
|
||||||
|
thumbnailURL: audio_files[0].thumbnailURL,
|
||||||
|
thumbnailPath: audio_files[0].thumbnailPath,
|
||||||
|
fileNames: audio_files.map(file => file.id),
|
||||||
|
type: 'audio',
|
||||||
|
auto: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (video_files && video_files.length > 0) {
|
||||||
|
playlists.push({
|
||||||
|
name: category['name'],
|
||||||
|
thumbnailURL: video_files[0].thumbnailURL,
|
||||||
|
thumbnailPath: video_files[0].thumbnailPath,
|
||||||
|
fileNames: video_files.map(file => file.id),
|
||||||
|
type: 'video',
|
||||||
|
auto: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop through subscriptions and add videos
|
// loop through subscriptions and add videos
|
||||||
|
|||||||
@@ -15,15 +15,16 @@ var JwtStrategy = require('passport-jwt').Strategy,
|
|||||||
|
|
||||||
// other required vars
|
// other required vars
|
||||||
let logger = null;
|
let logger = null;
|
||||||
var users_db = null;
|
let db = null;
|
||||||
|
let users_db = null;
|
||||||
let SERVER_SECRET = null;
|
let SERVER_SECRET = null;
|
||||||
let JWT_EXPIRATION = null;
|
let JWT_EXPIRATION = null;
|
||||||
let opts = null;
|
let opts = null;
|
||||||
let saltRounds = null;
|
let saltRounds = null;
|
||||||
|
|
||||||
exports.initialize = function(input_users_db, input_logger) {
|
exports.initialize = function(input_db, input_users_db, input_logger) {
|
||||||
setLogger(input_logger)
|
setLogger(input_logger)
|
||||||
setDB(input_users_db);
|
setDB(input_db, input_users_db);
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
* Authentication module
|
* Authentication module
|
||||||
@@ -61,7 +62,8 @@ function setLogger(input_logger) {
|
|||||||
logger = input_logger;
|
logger = input_logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDB(input_users_db) {
|
function setDB(input_db, input_users_db) {
|
||||||
|
db = input_db;
|
||||||
users_db = input_users_db;
|
users_db = input_users_db;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,9 +312,39 @@ exports.removePlaylist = function(user_uid, playlistID) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getUserPlaylists = function(user_uid) {
|
exports.getUserPlaylists = function(user_uid, user_files = null) {
|
||||||
const user = users_db.get('users').find({uid: user_uid}).value();
|
const user = users_db.get('users').find({uid: user_uid}).value();
|
||||||
return user['playlists'];
|
const playlists = JSON.parse(JSON.stringify(user['playlists']));
|
||||||
|
const categories = db.get('categories').value();
|
||||||
|
if (categories && user_files) {
|
||||||
|
categories.forEach(category => {
|
||||||
|
const audio_files = user_files && user_files.filter(file => file.category && file.category.uid === category.uid && file.isAudio);
|
||||||
|
const video_files = user_files && user_files.filter(file => file.category && file.category.uid === category.uid && !file.isAudio);
|
||||||
|
if (audio_files && audio_files.length > 0) {
|
||||||
|
playlists.push({
|
||||||
|
name: category['name'],
|
||||||
|
thumbnailURL: audio_files[0].thumbnailURL,
|
||||||
|
thumbnailPath: audio_files[0].thumbnailPath,
|
||||||
|
fileNames: audio_files.map(file => file.id),
|
||||||
|
type: 'audio',
|
||||||
|
uid: user_uid,
|
||||||
|
auto: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (video_files && video_files.length > 0) {
|
||||||
|
playlists.push({
|
||||||
|
name: category['name'],
|
||||||
|
thumbnailURL: video_files[0].thumbnailURL,
|
||||||
|
thumbnailPath: video_files[0].thumbnailPath,
|
||||||
|
fileNames: video_files.map(file => file.id),
|
||||||
|
type: 'video',
|
||||||
|
uid: user_uid,
|
||||||
|
auto: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return playlists;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getUserPlaylist = function(user_uid, playlistID, requireSharing = false) {
|
exports.getUserPlaylist = function(user_uid, playlistID, requireSharing = false) {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export class CustomPlaylistsComponent implements OnInit {
|
|||||||
} else {
|
} else {
|
||||||
localStorage.setItem('player_navigator', this.router.url);
|
localStorage.setItem('player_navigator', this.router.url);
|
||||||
const fileNames = playlist.fileNames;
|
const fileNames = playlist.fileNames;
|
||||||
this.router.navigate(['/player', {fileNames: fileNames.join('|nvr|'), type: type, id: playlistID, uid: playlistID}]);
|
this.router.navigate(['/player', {fileNames: fileNames.join('|nvr|'), type: type, id: playlistID, uid: playlistID, auto: playlist.auto}]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// playlist not found
|
// playlist not found
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export class RecentVideosComponent implements OnInit {
|
|||||||
|
|
||||||
private filterFiles(value: string) {
|
private filterFiles(value: string) {
|
||||||
const filterValue = value.toLowerCase();
|
const filterValue = value.toLowerCase();
|
||||||
this.filtered_files = this.files.filter(option => option.id.toLowerCase().includes(filterValue) || option.category?.toLowerCase().includes(filterValue));
|
this.filtered_files = this.files.filter(option => option.id.toLowerCase().includes(filterValue) || option.category?.name?.toLowerCase().includes(filterValue));
|
||||||
this.pageChangeEvent({pageSize: this.pageSize, pageIndex: this.paginator.pageIndex});
|
this.pageChangeEvent({pageSize: this.pageSize, pageIndex: this.paginator.pageIndex});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<div (mouseover)="elevated=true" (mouseout)="elevated=false" (contextmenu)="onRightClick($event)" style="position: relative; width: fit-content;">
|
<div (mouseover)="elevated=true" (mouseout)="elevated=false" (contextmenu)="onRightClick($event)" style="position: relative; width: fit-content;">
|
||||||
<div *ngIf="!loading" class="download-time"><mat-icon class="audio-video-icon">{{(file_obj.type === 'audio' || file_obj.isAudio) ? 'audiotrack' : 'movie'}}</mat-icon> {{file_obj.registered | date:'shortDate' : undefined : locale.ngID}}</div>
|
<div *ngIf="!loading" class="download-time">
|
||||||
|
<mat-icon class="audio-video-icon">{{(file_obj.type === 'audio' || file_obj.isAudio) ? 'audiotrack' : 'movie'}}</mat-icon>
|
||||||
|
|
||||||
|
<ng-container i18n="Auto-generated label" *ngIf="file_obj.auto">Auto-generated</ng-container>
|
||||||
|
<ng-container *ngIf="!file_obj.auto">{{file_obj.registered | date:'shortDate' : undefined : locale.ngID}}</ng-container>
|
||||||
|
</div>
|
||||||
<div *ngIf="loading" class="download-time" style="width: 75%; margin-top: 5px;"><content-loader [primaryColor]="theme.ghost_primary" [secondaryColor]="theme.ghost_secondary" width="250" height="30"><svg:rect x="0" y="0" rx="3" ry="3" width="250" height="30" /></content-loader></div>
|
<div *ngIf="loading" class="download-time" style="width: 75%; margin-top: 5px;"><content-loader [primaryColor]="theme.ghost_primary" [secondaryColor]="theme.ghost_secondary" width="250" height="30"><svg:rect x="0" y="0" rx="3" ry="3" width="250" height="30" /></content-loader></div>
|
||||||
<!-- The context menu trigger must be kept above the "more info" menu -->
|
<!-- The context menu trigger must be kept above the "more info" menu -->
|
||||||
<div style="visibility: hidden; position: fixed"
|
<div style="visibility: hidden; position: fixed"
|
||||||
@@ -7,7 +12,7 @@
|
|||||||
[style.top]="contextMenuPosition.y"
|
[style.top]="contextMenuPosition.y"
|
||||||
[matMenuTriggerFor]="context_menu">
|
[matMenuTriggerFor]="context_menu">
|
||||||
</div>
|
</div>
|
||||||
<button [disabled]="loading" [matMenuTriggerFor]="action_menu" class="menuButton" mat-icon-button><mat-icon>more_vert</mat-icon></button>
|
<button *ngIf="!file_obj || !file_obj.auto" [disabled]="loading" [matMenuTriggerFor]="action_menu" class="menuButton" mat-icon-button><mat-icon>more_vert</mat-icon></button>
|
||||||
<mat-menu #context_menu>
|
<mat-menu #context_menu>
|
||||||
<ng-container *ngIf="!loading">
|
<ng-container *ngIf="!loading">
|
||||||
<button (click)="navigateToFile($event)" mat-menu-item><mat-icon>open_in_browser</mat-icon><ng-container i18n="Open file button">Open file</ng-container></button>
|
<button (click)="navigateToFile($event)" mat-menu-item><mat-icon>open_in_browser</mat-icon><ng-container i18n="Open file button">Open file</ng-container></button>
|
||||||
|
|||||||
@@ -111,6 +111,11 @@
|
|||||||
top: 1px;
|
top: 1px;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
|
width: calc(100% - 8px);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
display: block;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.audio-video-icon {
|
.audio-video-icon {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<div class="info-item-label"><strong><ng-container i18n="Category property">Category:</ng-container> </strong></div>
|
<div class="info-item-label"><strong><ng-container i18n="Category property">Category:</ng-container> </strong></div>
|
||||||
<div class="info-item-value"><ng-container *ngIf="file.category"><mat-chip-list><mat-chip>{{file.category}}</mat-chip></mat-chip-list></ng-container><ng-container *ngIf="!file.category">N/A</ng-container></div>
|
<div class="info-item-value"><ng-container *ngIf="file.category"><mat-chip-list><mat-chip>{{file.category.name}}</mat-chip></mat-chip-list></ng-container><ng-container *ngIf="!file.category">N/A</ng-container></div>
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
|
||||||
|
|||||||
@@ -207,6 +207,10 @@ export class PlayerComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getPlaylistFiles() {
|
getPlaylistFiles() {
|
||||||
|
if (this.route.snapshot.paramMap.get('auto') === 'true') {
|
||||||
|
this.show_player = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.postsService.getPlaylist(this.id, null, this.uuid).subscribe(res => {
|
this.postsService.getPlaylist(this.id, null, this.uuid).subscribe(res => {
|
||||||
if (res['playlist']) {
|
if (res['playlist']) {
|
||||||
this.db_playlist = res['playlist'];
|
this.db_playlist = res['playlist'];
|
||||||
|
|||||||
Reference in New Issue
Block a user