mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-31 00:50:59 +03:00
Compare commits
25 Commits
tasks-and-
...
angular-13
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ded160775 | ||
|
|
2ee64c7a65 | ||
|
|
2ec7efa1ac | ||
|
|
4d51384ce6 | ||
|
|
aa616af118 | ||
|
|
feebe3e2ba | ||
|
|
02e90fe818 | ||
|
|
a4cfafe63c | ||
|
|
63e2e6dd3c | ||
|
|
5a44229e24 | ||
|
|
5025b235b7 | ||
|
|
5d540fc52a | ||
|
|
55dfc17d62 | ||
|
|
2459403b22 | ||
|
|
ed5f910c33 | ||
|
|
468e7153e4 | ||
|
|
1bd713fe17 | ||
|
|
3df377a260 | ||
|
|
8314ab8fce | ||
|
|
0f4f5293de | ||
|
|
16943847fc | ||
|
|
f79b254040 | ||
|
|
e7989e41f9 | ||
|
|
a4d421d398 | ||
|
|
b46b9ea386 |
7
.dockerignore
Normal file
7
.dockerignore
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.git
|
||||||
|
db
|
||||||
|
appdata
|
||||||
|
audio
|
||||||
|
video
|
||||||
|
subscriptions
|
||||||
|
users
|
||||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -25,6 +25,7 @@
|
|||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
|
/.angular/cache
|
||||||
/.sass-cache
|
/.sass-cache
|
||||||
/connect.lock
|
/connect.lock
|
||||||
/coverage
|
/coverage
|
||||||
@@ -67,3 +68,11 @@ backend/users/*
|
|||||||
backend/appdata/cookies.txt
|
backend/appdata/cookies.txt
|
||||||
backend/public
|
backend/public
|
||||||
src/assets/i18n/*.json
|
src/assets/i18n/*.json
|
||||||
|
|
||||||
|
# User Files
|
||||||
|
db/
|
||||||
|
appdata/
|
||||||
|
audio/
|
||||||
|
video/
|
||||||
|
subscriptions/
|
||||||
|
users/
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
FROM alpine:latest AS ffmpeg
|
||||||
|
|
||||||
|
COPY docker-build.sh .
|
||||||
|
RUN sh ./docker-build.sh
|
||||||
|
|
||||||
FROM alpine:latest as frontend
|
FROM alpine:latest as frontend
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
@@ -26,7 +31,6 @@ ENV NO_UPDATE_NOTIFIER=true
|
|||||||
RUN addgroup -S $USER -g $GID && adduser -D -S $USER -G $USER -u $UID
|
RUN addgroup -S $USER -g $GID && adduser -D -S $USER -G $USER -u $UID
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
ffmpeg \
|
|
||||||
npm \
|
npm \
|
||||||
python2 \
|
python2 \
|
||||||
python3 \
|
python3 \
|
||||||
@@ -35,6 +39,8 @@ RUN apk add --no-cache \
|
|||||||
atomicparsley
|
atomicparsley
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
COPY --from=ffmpeg /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg
|
||||||
|
COPY --from=ffmpeg /usr/local/bin/ffprobe /usr/local/bin/ffprobe
|
||||||
COPY --chown=$UID:$GID [ "backend/package.json", "backend/package-lock.json", "/app/" ]
|
COPY --chown=$UID:$GID [ "backend/package.json", "backend/package-lock.json", "/app/" ]
|
||||||
ENV PM2_HOME=/app/pm2
|
ENV PM2_HOME=/app/pm2
|
||||||
RUN npm install pm2 -g
|
RUN npm install pm2 -g
|
||||||
|
|||||||
@@ -482,6 +482,26 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
security:
|
security:
|
||||||
- Auth query parameter: []
|
- Auth query parameter: []
|
||||||
|
/api/deleteAllFiles:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- files
|
||||||
|
summary: Delete all downloaded files
|
||||||
|
operationId: post-api-deleteAllFiles
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/DeleteMp3Mp4Request'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/DeleteAllFilesResponse'
|
||||||
|
security:
|
||||||
|
- Auth query parameter: []
|
||||||
/api/downloadArchive:
|
/api/downloadArchive:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@@ -1765,6 +1785,15 @@ components:
|
|||||||
type: boolean
|
type: boolean
|
||||||
error:
|
error:
|
||||||
type: string
|
type: string
|
||||||
|
DeleteAllFilesResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
file_count:
|
||||||
|
type: number
|
||||||
|
description: Number of files found matching search parameters
|
||||||
|
delete_count:
|
||||||
|
type: number
|
||||||
|
description: Number of files removed
|
||||||
DeleteSubscriptionFileRequest:
|
DeleteSubscriptionFileRequest:
|
||||||
required:
|
required:
|
||||||
- file
|
- file
|
||||||
|
|||||||
36
angular.json
36
angular.json
@@ -17,7 +17,6 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
"options": {
|
"options": {
|
||||||
"aot": true,
|
|
||||||
"outputPath": "backend/public",
|
"outputPath": "backend/public",
|
||||||
"index": "src/index.html",
|
"index": "src/index.html",
|
||||||
"main": "src/main.ts",
|
"main": "src/main.ts",
|
||||||
@@ -33,7 +32,17 @@
|
|||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": [],
|
||||||
|
"vendorChunk": true,
|
||||||
|
"extractLicenses": false,
|
||||||
|
"buildOptimizer": false,
|
||||||
|
"sourceMap": true,
|
||||||
|
"optimization": false,
|
||||||
|
"namedChunks": true,
|
||||||
|
"allowedCommonJsDependencies": [
|
||||||
|
"rxjs",
|
||||||
|
"crypto-js"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
@@ -46,7 +55,6 @@
|
|||||||
"optimization": true,
|
"optimization": true,
|
||||||
"outputHashing": "all",
|
"outputHashing": "all",
|
||||||
"namedChunks": false,
|
"namedChunks": false,
|
||||||
"aot": true,
|
|
||||||
"extractLicenses": true,
|
"extractLicenses": true,
|
||||||
"vendorChunk": false,
|
"vendorChunk": false,
|
||||||
"buildOptimizer": true,
|
"buildOptimizer": true,
|
||||||
@@ -60,7 +68,8 @@
|
|||||||
"es": {
|
"es": {
|
||||||
"localize": ["es"]
|
"localize": ["es"]
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"defaultConfiguration": ""
|
||||||
},
|
},
|
||||||
"serve": {
|
"serve": {
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
@@ -152,16 +161,6 @@
|
|||||||
"src/backend"
|
"src/backend"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": [
|
|
||||||
"src/tsconfig.app.json",
|
|
||||||
"src/tsconfig.spec.json"
|
|
||||||
],
|
|
||||||
"exclude": []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -176,15 +175,6 @@
|
|||||||
"protractorConfig": "./protractor.conf.js",
|
"protractorConfig": "./protractor.conf.js",
|
||||||
"devServerTarget": "youtube-dl-material:serve"
|
"devServerTarget": "youtube-dl-material:serve"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": [
|
|
||||||
"e2e/tsconfig.e2e.json"
|
|
||||||
],
|
|
||||||
"exclude": []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1434,6 +1434,46 @@ app.post('/api/deleteFile', optionalJwt, async (req, res) => {
|
|||||||
res.send(wasDeleted);
|
res.send(wasDeleted);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.post('/api/deleteAllFiles', optionalJwt, async (req, res) => {
|
||||||
|
const blacklistMode = false;
|
||||||
|
const uuid = req.isAuthenticated() ? req.user.uid : null;
|
||||||
|
|
||||||
|
let files = null;
|
||||||
|
let text_search = req.body.text_search;
|
||||||
|
let file_type_filter = req.body.file_type_filter;
|
||||||
|
|
||||||
|
const filter_obj = {user_uid: uuid};
|
||||||
|
const regex = true;
|
||||||
|
if (text_search) {
|
||||||
|
if (regex) {
|
||||||
|
filter_obj['title'] = {$regex: `.*${text_search}.*`, $options: 'i'};
|
||||||
|
} else {
|
||||||
|
filter_obj['$text'] = { $search: utils.createEdgeNGrams(text_search) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_type_filter === 'audio_only') filter_obj['isAudio'] = true;
|
||||||
|
else if (file_type_filter === 'video_only') filter_obj['isAudio'] = false;
|
||||||
|
|
||||||
|
files = await db_api.getRecords('files', filter_obj);
|
||||||
|
|
||||||
|
let file_count = await db_api.getRecords('files', filter_obj, true);
|
||||||
|
let delete_count = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
let wasDeleted = false;
|
||||||
|
wasDeleted = await db_api.deleteFile(files[i].uid, uuid, blacklistMode);
|
||||||
|
if (wasDeleted) {
|
||||||
|
delete_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({
|
||||||
|
file_count: file_count,
|
||||||
|
delete_count: delete_count
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
app.post('/api/downloadFileFromServer', optionalJwt, async (req, res) => {
|
app.post('/api/downloadFileFromServer', optionalJwt, async (req, res) => {
|
||||||
let uid = req.body.uid;
|
let uid = req.body.uid;
|
||||||
let uuid = req.body.uuid;
|
let uuid = req.body.uuid;
|
||||||
@@ -1456,18 +1496,14 @@ app.post('/api/downloadFileFromServer', optionalJwt, async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generate zip
|
// generate zip
|
||||||
file_path_to_download = await utils.createContainerZipFile(playlist, playlist_files_to_download);
|
file_path_to_download = await utils.createContainerZipFile(playlist['name'], playlist_files_to_download);
|
||||||
} else if (sub_id && !uid) {
|
} else if (sub_id && !uid) {
|
||||||
zip_file_generated = true;
|
zip_file_generated = true;
|
||||||
const sub_files_to_download = [];
|
const sub = await db_api.getRecord('subscriptions', {id: sub_id});
|
||||||
const sub = subscriptions_api.getSubscription(sub_id, uuid);
|
const sub_files_to_download = await db_api.getRecords('files', {sub_id: sub_id});
|
||||||
for (let i = 0; i < sub['videos'].length; i++) {
|
|
||||||
const sub_file = sub['videos'][i];
|
|
||||||
sub_files_to_download.push(sub_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate zip
|
// generate zip
|
||||||
file_path_to_download = await utils.createContainerZipFile(sub, sub_files_to_download);
|
file_path_to_download = await utils.createContainerZipFile(sub['name'], sub_files_to_download);
|
||||||
} else {
|
} else {
|
||||||
const file_obj = await db_api.getVideo(uid, uuid, sub_id)
|
const file_obj = await db_api.getVideo(uid, uuid, sub_id)
|
||||||
file_path_to_download = file_obj.path;
|
file_path_to_download = file_obj.path;
|
||||||
|
|||||||
946
backend/package-lock.json
generated
946
backend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -30,15 +30,14 @@
|
|||||||
},
|
},
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"archiver": "^3.1.1",
|
"archiver": "^5.3.1",
|
||||||
"async": "^3.1.0",
|
"async": "^3.2.3",
|
||||||
"async-mutex": "^0.3.1",
|
"async-mutex": "^0.3.1",
|
||||||
"axios": "^0.21.2",
|
"axios": "^0.21.2",
|
||||||
"bcryptjs": "^2.4.0",
|
"bcryptjs": "^2.4.0",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"config": "^3.2.3",
|
"config": "^3.2.3",
|
||||||
"exe": "^1.0.2",
|
"express": "^4.17.3",
|
||||||
"express": "^4.17.1",
|
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
"fs-extra": "^9.0.0",
|
"fs-extra": "^9.0.0",
|
||||||
"glob": "^7.1.6",
|
"glob": "^7.1.6",
|
||||||
@@ -46,7 +45,7 @@
|
|||||||
"lowdb": "^1.0.0",
|
"lowdb": "^1.0.0",
|
||||||
"md5": "^2.2.1",
|
"md5": "^2.2.1",
|
||||||
"merge-files": "^0.1.2",
|
"merge-files": "^0.1.2",
|
||||||
"mocha": "^8.4.0",
|
"mocha": "^9.2.2",
|
||||||
"moment": "^2.29.2",
|
"moment": "^2.29.2",
|
||||||
"mongodb": "^3.6.9",
|
"mongodb": "^3.6.9",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
@@ -54,10 +53,10 @@
|
|||||||
"node-id3": "^0.1.14",
|
"node-id3": "^0.1.14",
|
||||||
"node-schedule": "^2.1.0",
|
"node-schedule": "^2.1.0",
|
||||||
"nodemon": "^2.0.7",
|
"nodemon": "^2.0.7",
|
||||||
"passport": "^0.4.1",
|
"passport": "^0.5.2",
|
||||||
"passport-http": "^0.3.0",
|
"passport-http": "^0.3.0",
|
||||||
"passport-jwt": "^4.0.0",
|
"passport-jwt": "^4.0.0",
|
||||||
"passport-ldapauth": "^2.1.4",
|
"passport-ldapauth": "^3.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
"progress": "^2.0.3",
|
"progress": "^2.0.3",
|
||||||
"ps-node": "^0.1.6",
|
"ps-node": "^0.1.6",
|
||||||
@@ -66,7 +65,7 @@
|
|||||||
"shortid": "^2.2.15",
|
"shortid": "^2.2.15",
|
||||||
"unzipper": "^0.10.10",
|
"unzipper": "^0.10.10",
|
||||||
"uuidv4": "^6.0.6",
|
"uuidv4": "^6.0.6",
|
||||||
"winston": "^3.3.3",
|
"winston": "^3.7.2",
|
||||||
"xmlbuilder2": "^3.0.2",
|
"xmlbuilder2": "^3.0.2",
|
||||||
"youtube-dl": "^3.0.2"
|
"youtube-dl": "^3.0.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,13 +58,13 @@ async function getDownloadedFilesByType(basePath, type, full_metadata = false) {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createContainerZipFile(container_obj, container_file_objs) {
|
async function createContainerZipFile(file_name, container_file_objs) {
|
||||||
const container_files_to_download = [];
|
const container_files_to_download = [];
|
||||||
for (let i = 0; i < container_file_objs.length; i++) {
|
for (let i = 0; i < container_file_objs.length; i++) {
|
||||||
const container_file_obj = container_file_objs[i];
|
const container_file_obj = container_file_objs[i];
|
||||||
container_files_to_download.push(container_file_obj.path);
|
container_files_to_download.push(container_file_obj.path);
|
||||||
}
|
}
|
||||||
return await createZipFile(path.join('appdata', container_obj.name + '.zip'), container_files_to_download);
|
return await createZipFile(path.join('appdata', file_name + '.zip'), container_files_to_download);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createZipFile(zip_file_path, file_paths) {
|
async function createZipFile(zip_file_path, file_paths) {
|
||||||
|
|||||||
31
docker-build.sh
Normal file
31
docker-build.sh
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# THANK YOU TALULAH (https://github.com/nottalulah) for your help in figuring this out
|
||||||
|
# and also optimizing some code with this commit.
|
||||||
|
# xoxo :D
|
||||||
|
|
||||||
|
set -xeuo pipefail
|
||||||
|
|
||||||
|
case $(uname -m) in
|
||||||
|
x86_64)
|
||||||
|
ARCH=amd64;;
|
||||||
|
aarch64)
|
||||||
|
ARCH=arm64;;
|
||||||
|
armhf)
|
||||||
|
ARCH=armhf;;
|
||||||
|
armv7)
|
||||||
|
ARCH=armel;;
|
||||||
|
armv7l)
|
||||||
|
ARCH=armel;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported architecture: $(uname -m)"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "Architecture: $ARCH"
|
||||||
|
wget "https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-${ARCH}-static.tar.xz" -O ffmpeg.txz
|
||||||
|
mkdir /tmp/ffmpeg
|
||||||
|
tar xf ffmpeg.txz -C /tmp/ffmpeg
|
||||||
|
cp /tmp/ffmpeg/*/ffmpeg /usr/local/bin/ffmpeg
|
||||||
|
cp /tmp/ffmpeg/*/ffprobe /usr/local/bin/ffprobe
|
||||||
|
rm -rf /tmp/ffmpeg ffmpeg.txz
|
||||||
@@ -7,6 +7,8 @@ services:
|
|||||||
ytdl_use_local_db: 'false'
|
ytdl_use_local_db: 'false'
|
||||||
write_ytdl_config: 'true'
|
write_ytdl_config: 'true'
|
||||||
restart: always
|
restart: always
|
||||||
|
depends_on:
|
||||||
|
- ytdl-mongo-db
|
||||||
volumes:
|
volumes:
|
||||||
- ./appdata:/app/appdata
|
- ./appdata:/app/appdata
|
||||||
- ./audio:/app/audio
|
- ./audio:/app/audio
|
||||||
@@ -23,5 +25,6 @@ services:
|
|||||||
logging:
|
logging:
|
||||||
driver: "none"
|
driver: "none"
|
||||||
container_name: mongo-db
|
container_name: mongo-db
|
||||||
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- ./db/:/data/db
|
- ./db/:/data/db
|
||||||
11851
package-lock.json
generated
11851
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
50
package.json
50
package.json
@@ -5,7 +5,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"build": "ng build --prod",
|
"build": "ng build --configuration production",
|
||||||
"prebuild": "node src/postbuild.mjs",
|
"prebuild": "node src/postbuild.mjs",
|
||||||
"heroku-postbuild": "npm install --prefix backend",
|
"heroku-postbuild": "npm install --prefix backend",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
@@ -20,44 +20,44 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/core": "^11.0.4",
|
"@angular-devkit/core": "^13.3.3",
|
||||||
"@angular/animations": "^11.0.4",
|
"@angular/animations": "^13.3.4",
|
||||||
"@angular/cdk": "^11.0.2",
|
"@angular/cdk": "^13.3.4",
|
||||||
"@angular/common": "^11.0.4",
|
"@angular/common": "^13.3.4",
|
||||||
"@angular/compiler": "^11.0.4",
|
"@angular/compiler": "^13.3.4",
|
||||||
"@angular/core": "^11.0.4",
|
"@angular/core": "^13.3.4",
|
||||||
"@angular/forms": "^11.0.4",
|
"@angular/forms": "^13.3.4",
|
||||||
"@angular/localize": "^11.0.4",
|
"@angular/localize": "^13.3.4",
|
||||||
"@angular/material": "^11.0.2",
|
"@angular/material": "^13.3.4",
|
||||||
"@angular/platform-browser": "^11.0.4",
|
"@angular/platform-browser": "^13.3.4",
|
||||||
"@angular/platform-browser-dynamic": "^11.0.4",
|
"@angular/platform-browser-dynamic": "^13.3.4",
|
||||||
"@angular/router": "^11.0.4",
|
"@angular/router": "^13.3.4",
|
||||||
|
"@fontsource/material-icons": "^4.5.4",
|
||||||
"@ngneat/content-loader": "^5.0.0",
|
"@ngneat/content-loader": "^5.0.0",
|
||||||
"@videogular/ngx-videogular": "^2.1.0",
|
"@videogular/ngx-videogular": "^5.0.1",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"filesize": "^6.1.0",
|
"filesize": "^6.1.0",
|
||||||
"fingerprintjs2": "^2.1.0",
|
"fingerprintjs2": "^2.1.0",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"material-icons": "^0.5.4",
|
"material-icons": "^1.10.8",
|
||||||
"nan": "^2.14.1",
|
"nan": "^2.14.1",
|
||||||
"ng-lazyload-image": "^7.0.1",
|
"ng-lazyload-image": "^7.0.1",
|
||||||
"ngx-avatar": "^4.0.0",
|
"ngx-avatars": "^1.3.1",
|
||||||
"ngx-file-drop": "^9.0.1",
|
"ngx-file-drop": "^13.0.0",
|
||||||
"rxjs": "^6.6.3",
|
"rxjs": "^6.6.3",
|
||||||
"rxjs-compat": "^6.0.0-rc.0",
|
"rxjs-compat": "^6.0.0-rc.0",
|
||||||
"tslib": "^2.0.0",
|
"tslib": "^2.0.0",
|
||||||
"typescript": "~4.0.5",
|
"typescript": "~4.6.3",
|
||||||
"web-animations-js": "^2.3.2",
|
|
||||||
"xliff-to-json": "^1.0.4",
|
"xliff-to-json": "^1.0.4",
|
||||||
"zone.js": "~0.10.2"
|
"zone.js": "~0.11.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^0.1100.4",
|
"@angular-devkit/build-angular": "^13.3.3",
|
||||||
"@angular/cli": "^11.0.4",
|
"@angular/cli": "^13.3.3",
|
||||||
"@angular/compiler-cli": "^11.0.4",
|
"@angular/compiler-cli": "^13.3.4",
|
||||||
"@angular/language-service": "^11.0.4",
|
"@angular/language-service": "^13.3.4",
|
||||||
"@types/core-js": "^2.5.2",
|
"@types/core-js": "^2.5.2",
|
||||||
"@types/file-saver": "^2.0.1",
|
"@types/file-saver": "^2.0.1",
|
||||||
"@types/jasmine": "~3.6.0",
|
"@types/jasmine": "~3.6.0",
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||||
"karma-jasmine": "~4.0.0",
|
"karma-jasmine": "~4.0.0",
|
||||||
"karma-jasmine-html-reporter": "^1.5.0",
|
"karma-jasmine-html-reporter": "^1.5.0",
|
||||||
"openapi-typescript-codegen": "^0.4.11",
|
"openapi-typescript-codegen": "^0.21.0",
|
||||||
"protractor": "~7.0.0",
|
"protractor": "~7.0.0",
|
||||||
"ts-node": "~3.0.4",
|
"ts-node": "~3.0.4",
|
||||||
"tslint": "~6.1.0"
|
"tslint": "~6.1.0"
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Coolors Exported Palette - coolors.co/e8aeb7-b8e1ff-a9fff7-94fbab-82aba1 */
|
/* Coolors Exported Palette - coolors.co/e8aeb7-b8e1ff-a9fff7-94fbab-82aba1 */
|
||||||
|
|
||||||
/* HSL */
|
/* HSL */
|
||||||
$color1: hsla(351%, 56%, 80%, 1);
|
$color1: hsla(351, 56%, 80%, 1);
|
||||||
$softblue: hsla(205%, 100%, 86%, 1);
|
$softblue: hsla(205, 100%, 86%, 1);
|
||||||
$color3: hsla(174%, 100%, 83%, 1);
|
$color3: hsla(174, 100%, 83%, 1);
|
||||||
$color4: hsla(133%, 93%, 78%, 1);
|
$color4: hsla(133, 93%, 78%, 1);
|
||||||
$color5: hsla(165%, 20%, 59%, 1);
|
$color5: hsla(165, 20%, 59%, 1);
|
||||||
|
|
||||||
/* RGB */
|
/* RGB */
|
||||||
$color1: rgba(232, 174, 183, 1);
|
$color1: rgba(232, 174, 183, 1);
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ import { VgBufferingModule } from '@videogular/ngx-videogular/buffering';
|
|||||||
import { VgOverlayPlayModule } from '@videogular/ngx-videogular/overlay-play';
|
import { VgOverlayPlayModule } from '@videogular/ngx-videogular/overlay-play';
|
||||||
import { VgCoreModule } from '@videogular/ngx-videogular/core';
|
import { VgCoreModule } from '@videogular/ngx-videogular/core';
|
||||||
import { InputDialogComponent } from './input-dialog/input-dialog.component';
|
import { InputDialogComponent } from './input-dialog/input-dialog.component';
|
||||||
import { LazyLoadImageModule, IsVisibleProps } from 'ng-lazyload-image';
|
|
||||||
import { audioFilesMouseHovering, videoFilesMouseHovering, audioFilesOpened, videoFilesOpened } from './main/main.component';
|
|
||||||
import { CreatePlaylistComponent } from './create-playlist/create-playlist.component';
|
import { CreatePlaylistComponent } from './create-playlist/create-playlist.component';
|
||||||
import { SubscriptionsComponent } from './subscriptions/subscriptions.component';
|
import { SubscriptionsComponent } from './subscriptions/subscriptions.component';
|
||||||
import { SubscribeDialogComponent } from './dialogs/subscribe-dialog/subscribe-dialog.component';
|
import { SubscribeDialogComponent } from './dialogs/subscribe-dialog/subscribe-dialog.component';
|
||||||
@@ -56,7 +54,7 @@ import { SubscriptionInfoDialogComponent } from './dialogs/subscription-info-dia
|
|||||||
import { SettingsComponent } from './settings/settings.component';
|
import { SettingsComponent } from './settings/settings.component';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { NgxFileDropModule } from 'ngx-file-drop';
|
import { NgxFileDropModule } from 'ngx-file-drop';
|
||||||
import { AvatarModule } from 'ngx-avatar';
|
import { AvatarModule } from 'ngx-avatars';
|
||||||
import { ContentLoaderModule } from '@ngneat/content-loader';
|
import { ContentLoaderModule } from '@ngneat/content-loader';
|
||||||
|
|
||||||
import es from '@angular/common/locales/es';
|
import es from '@angular/common/locales/es';
|
||||||
@@ -94,122 +92,110 @@ import { RestoreDbDialogComponent } from './dialogs/restore-db-dialog/restore-db
|
|||||||
|
|
||||||
registerLocaleData(es, 'es');
|
registerLocaleData(es, 'es');
|
||||||
|
|
||||||
export function isVisible({ event, element, scrollContainer, offset }: IsVisibleProps<any>) {
|
|
||||||
return (element.id === 'video' ? videoFilesMouseHovering || videoFilesOpened : audioFilesMouseHovering || audioFilesOpened);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
MainComponent,
|
MainComponent,
|
||||||
PlayerComponent,
|
PlayerComponent,
|
||||||
InputDialogComponent,
|
InputDialogComponent,
|
||||||
CreatePlaylistComponent,
|
CreatePlaylistComponent,
|
||||||
SubscriptionsComponent,
|
SubscriptionsComponent,
|
||||||
SubscribeDialogComponent,
|
SubscribeDialogComponent,
|
||||||
SubscriptionComponent,
|
SubscriptionComponent,
|
||||||
SubscriptionFileCardComponent,
|
SubscriptionFileCardComponent,
|
||||||
SubscriptionInfoDialogComponent,
|
SubscriptionInfoDialogComponent,
|
||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
AboutDialogComponent,
|
AboutDialogComponent,
|
||||||
VideoInfoDialogComponent,
|
VideoInfoDialogComponent,
|
||||||
ArgModifierDialogComponent,
|
ArgModifierDialogComponent,
|
||||||
HighlightPipe,
|
HighlightPipe,
|
||||||
LinkifyPipe,
|
LinkifyPipe,
|
||||||
UpdaterComponent,
|
UpdaterComponent,
|
||||||
UpdateProgressDialogComponent,
|
UpdateProgressDialogComponent,
|
||||||
ShareMediaDialogComponent,
|
ShareMediaDialogComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
DownloadsComponent,
|
DownloadsComponent,
|
||||||
UserProfileDialogComponent,
|
UserProfileDialogComponent,
|
||||||
SetDefaultAdminDialogComponent,
|
SetDefaultAdminDialogComponent,
|
||||||
ModifyUsersComponent,
|
ModifyUsersComponent,
|
||||||
AddUserDialogComponent,
|
AddUserDialogComponent,
|
||||||
ManageUserComponent,
|
ManageUserComponent,
|
||||||
ManageRoleComponent,
|
ManageRoleComponent,
|
||||||
CookiesUploaderDialogComponent,
|
CookiesUploaderDialogComponent,
|
||||||
LogsViewerComponent,
|
LogsViewerComponent,
|
||||||
ModifyPlaylistComponent,
|
ModifyPlaylistComponent,
|
||||||
ConfirmDialogComponent,
|
ConfirmDialogComponent,
|
||||||
UnifiedFileCardComponent,
|
UnifiedFileCardComponent,
|
||||||
RecentVideosComponent,
|
RecentVideosComponent,
|
||||||
EditSubscriptionDialogComponent,
|
EditSubscriptionDialogComponent,
|
||||||
CustomPlaylistsComponent,
|
CustomPlaylistsComponent,
|
||||||
EditCategoryDialogComponent,
|
EditCategoryDialogComponent,
|
||||||
TwitchChatComponent,
|
TwitchChatComponent,
|
||||||
SeeMoreComponent,
|
SeeMoreComponent,
|
||||||
ConcurrentStreamComponent,
|
ConcurrentStreamComponent,
|
||||||
SkipAdButtonComponent,
|
SkipAdButtonComponent,
|
||||||
TasksComponent,
|
TasksComponent,
|
||||||
UpdateTaskScheduleDialogComponent,
|
UpdateTaskScheduleDialogComponent,
|
||||||
RestoreDbDialogComponent
|
RestoreDbDialogComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
MatNativeDateModule,
|
MatNativeDateModule,
|
||||||
MatRadioModule,
|
MatRadioModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
MatToolbarModule,
|
MatToolbarModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MatSidenavModule,
|
MatSidenavModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatListModule,
|
MatListModule,
|
||||||
MatGridListModule,
|
MatGridListModule,
|
||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
MatButtonToggleModule,
|
MatButtonToggleModule,
|
||||||
MatRippleModule,
|
MatRippleModule,
|
||||||
MatMenuModule,
|
MatMenuModule,
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
MatTabsModule,
|
MatTabsModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatDatepickerModule,
|
MatDatepickerModule,
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
ClipboardModule,
|
ClipboardModule,
|
||||||
TextFieldModule,
|
TextFieldModule,
|
||||||
NgxFileDropModule,
|
NgxFileDropModule,
|
||||||
AvatarModule,
|
AvatarModule,
|
||||||
ContentLoaderModule,
|
ContentLoaderModule,
|
||||||
VgCoreModule,
|
VgCoreModule,
|
||||||
VgControlsModule,
|
VgControlsModule,
|
||||||
VgOverlayPlayModule,
|
VgOverlayPlayModule,
|
||||||
VgBufferingModule,
|
VgBufferingModule,
|
||||||
LazyLoadImageModule.forRoot({ isVisible }),
|
RouterModule,
|
||||||
RouterModule,
|
AppRoutingModule,
|
||||||
AppRoutingModule,
|
],
|
||||||
],
|
providers: [
|
||||||
entryComponents: [
|
PostsService,
|
||||||
InputDialogComponent,
|
{ provide: HTTP_INTERCEPTORS, useClass: H401Interceptor, multi: true }
|
||||||
CreatePlaylistComponent,
|
],
|
||||||
SubscribeDialogComponent,
|
exports: [
|
||||||
SubscriptionInfoDialogComponent,
|
HighlightPipe,
|
||||||
SettingsComponent
|
LinkifyPipe
|
||||||
],
|
],
|
||||||
providers: [
|
bootstrap: [AppComponent]
|
||||||
PostsService,
|
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: H401Interceptor, multi: true }
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
HighlightPipe,
|
|
||||||
LinkifyPipe
|
|
||||||
],
|
|
||||||
bootstrap: [AppComponent]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<span class="text" [ngStyle]="{'-webkit-line-clamp': !see_more_active ? line_limit : null}" [innerHTML]="text | linkify"></span>
|
<span class="text" [ngStyle]="{'-webkit-line-clamp': !see_more_active ? line_limit : null}" [innerHTML]="text | linkify"></span>
|
||||||
<span>
|
<span>
|
||||||
<a [routerLink]="" (click)="toggleSeeMore()">
|
<a [routerLink]="[]" (click)="toggleSeeMore()">
|
||||||
<ng-container *ngIf="!see_more_active" i18n="See more">
|
<ng-container *ngIf="!see_more_active" i18n="See more">
|
||||||
See more.
|
See more.
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export class SkipAdButtonComponent implements OnInit {
|
|||||||
|
|
||||||
getVideoIDHashFromURL(video_id) {
|
getVideoIDHashFromURL(video_id) {
|
||||||
if (!video_id) return null;
|
if (!video_id) return null;
|
||||||
return CryptoJS.SHA256(video_id).toString(CryptoJS.enc.Hex);;
|
return CryptoJS.SHA256(video_id).toString(CryptoJS.enc.Hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoIDFromURL(url) {
|
getVideoIDFromURL(url) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {Injectable, isDevMode, Inject} from '@angular/core';
|
import {Injectable, isDevMode, Inject} from '@angular/core';
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||||
import 'rxjs/add/operator/map';
|
import 'rxjs/add/operator/map';
|
||||||
import 'rxjs/add/operator/map';
|
|
||||||
import 'rxjs/add/operator/catch';
|
import 'rxjs/add/operator/catch';
|
||||||
import 'rxjs/add/observable/throw';
|
import 'rxjs/add/observable/throw';
|
||||||
import { THEMES_CONFIG } from '../themes';
|
import { THEMES_CONFIG } from '../themes';
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ export class SubscriptionComponent implements OnInit, OnDestroy {
|
|||||||
constructor(private postsService: PostsService, private route: ActivatedRoute, private router: Router, private dialog: MatDialog) { }
|
constructor(private postsService: PostsService, private route: ActivatedRoute, private router: Router, private dialog: MatDialog) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.route.snapshot.paramMap.get('id')) {
|
this.route.params.subscribe(params => {
|
||||||
this.id = this.route.snapshot.paramMap.get('id');
|
this.id = params['id'];
|
||||||
|
|
||||||
this.postsService.service_initialized.subscribe(init => {
|
this.postsService.service_initialized.subscribe(init => {
|
||||||
if (init) {
|
if (init) {
|
||||||
@@ -59,7 +59,7 @@ export class SubscriptionComponent implements OnInit, OnDestroy {
|
|||||||
this.sub_interval = setInterval(() => this.getSubscription(true), 1000);
|
this.sub_interval = setInterval(() => this.getSubscription(true), 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
// set filter property to cached
|
// set filter property to cached
|
||||||
const cached_filter_property = localStorage.getItem('filter_property');
|
const cached_filter_property = localStorage.getItem('filter_property');
|
||||||
|
|||||||
@@ -20,44 +20,14 @@ import '@angular/localize/init';
|
|||||||
|
|
||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
* BROWSER POLYFILLS
|
* BROWSER POLYFILLS
|
||||||
*/
|
*/ // Run `npm install --save web-animations-js`.
|
||||||
|
|
||||||
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
|
|
||||||
// import 'core-js/es6/symbol';
|
|
||||||
// import 'core-js/es6/object';
|
|
||||||
// import 'core-js/es6/function';
|
|
||||||
// import 'core-js/es6/parse-int';
|
|
||||||
// import 'core-js/es6/parse-float';
|
|
||||||
// import 'core-js/es6/number';
|
|
||||||
// import 'core-js/es6/math';
|
|
||||||
// import 'core-js/es6/string';
|
|
||||||
// import 'core-js/es6/date';
|
|
||||||
// import 'core-js/es6/array';
|
|
||||||
// import 'core-js/es6/regexp';
|
|
||||||
// import 'core-js/es6/map';
|
|
||||||
// import 'core-js/es6/weak-map';
|
|
||||||
// import 'core-js/es6/set';
|
|
||||||
|
|
||||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
|
||||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
|
||||||
|
|
||||||
/** IE10 and IE11 requires the following to support `@angular/animation`. */
|
|
||||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
|
||||||
|
|
||||||
|
|
||||||
/** Evergreen browsers require these. **/
|
|
||||||
// import 'core-js/es6/reflect';
|
|
||||||
|
|
||||||
|
|
||||||
/** ALL Firefox browsers require the following to support `@angular/animation`. **/
|
|
||||||
import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
* Zone JS is required by Angular itself.
|
* Zone JS is required by Angular itself.
|
||||||
*/
|
*/
|
||||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
import 'zone.js'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ __karma__.loaded = function () {};
|
|||||||
// First, initialize the Angular testing environment.
|
// First, initialize the Angular testing environment.
|
||||||
getTestBed().initTestEnvironment(
|
getTestBed().initTestEnvironment(
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
platformBrowserDynamicTesting()
|
platformBrowserDynamicTesting(), {
|
||||||
|
teardown: { destroyAfterEach: false }
|
||||||
|
}
|
||||||
);
|
);
|
||||||
// Then we find all the tests.
|
// Then we find all the tests.
|
||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
|
|||||||
Reference in New Issue
Block a user