Compare commits

...

23 Commits

Author SHA1 Message Date
Tzahi12345
5ce2e2a35d Updated name of arm64 TwitchDownloaderCLI asset 2023-05-04 22:19:00 -04:00
Tzahi12345
90d9ac025a Added missing config item from default.json 2023-05-03 16:38:48 -04:00
Tzahi12345
07903131f9 GetTwitchDownloader.py now supports LinuxArm-x64 (not implemeted yet), waiting for this: https://github.com/lay295/TwitchDownloader/pull/703 2023-05-03 14:20:54 -04:00
Tzahi12345
ec3bb3e738 Updated dockerfile to move TwitchDownloaderCLI to /usr/local/bin
Fixed issue that prevented TwitchDownloader from working in windows
2023-05-03 14:04:09 -04:00
Tzahi12345
18fcf4eb61 Added missing copy in dockerfile 2023-05-03 02:01:28 -04:00
Tzahi12345
19f35d6af4 Updated content-loader and ngx-file-drop to improve build times 2023-05-03 01:33:51 -04:00
Tzahi12345
3a918b7059 Updated github actions dependencies (2) 2023-05-03 01:08:52 -04:00
Tzahi12345
7e7da6c0bc Updated github actions dependencies 2023-05-03 01:07:14 -04:00
Tzahi12345
f9f7204deb Updated several dependencies 2023-05-03 01:03:49 -04:00
Tzahi12345
8827d9f3de Added some pruning to shrink docker image size 2023-05-02 23:13:47 -04:00
Tzahi12345
42bc255d6c Removed fingerprintjs2 and sessionID param 2023-05-02 23:04:41 -04:00
Tzahi12345
2df3b9cbfd Removed electron (for now) 2023-05-02 23:02:33 -04:00
Tzahi12345
b859d08d86 Added raspberry pi specific documentation to docker-compose 2023-05-02 22:51:52 -04:00
Tzahi12345
e7325b2dc2 Merge pull request #887 from Tzahi12345/gh-actions-fix
GH actions fix
2023-05-02 19:19:06 -04:00
Tzahi12345
21463762ce Removed rimraf install from package.json 2023-05-02 19:10:40 -04:00
Tzahi12345
b06f6a81bb Force rmraf install 2023-05-01 22:34:25 -04:00
Tzahi12345
82c8146032 Updated nodejs version for backend 2023-05-01 19:56:37 -04:00
Tzahi12345
6f13eab550 Force rimraf to use locally installed version https://stackoverflow.com/questions/49092120/sh-1-rimraf-not-found-whenever-i-run-npm-run-build-within-vagrant-installed-o 2023-05-01 19:52:35 -04:00
Tzahi12345
9d2d70b194 Upgraded node version to v16 2023-05-01 19:43:04 -04:00
Tzahi12345
4e04ceae16 Fixed function call in db.js 2023-05-01 19:31:54 -04:00
Tzahi12345
5eec5ac082 Merge pull request #885 from Tzahi12345/slack-notifications
Added support for slack notifications
2023-05-01 17:21:00 -04:00
Tzahi12345
5253ce8793 Merge pull request #886 from Tzahi12345/archive-improvements
Archive improvements
2023-05-01 17:20:50 -04:00
Tzahi12345
9a08fc6140 Added support for slack notifications 2023-04-29 15:46:58 -04:00
23 changed files with 326 additions and 783 deletions

View File

@@ -15,9 +15,9 @@ jobs:
- name: checkout code
uses: actions/checkout@v2
- name: setup node
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: '14'
node-version: '16'
cache: 'npm'
- name: install dependencies
run: |
@@ -33,7 +33,7 @@ jobs:
run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
- name: create-json
id: create-json
uses: jsdaniell/create-json@1.1.2
uses: jsdaniell/create-json@v1.2.2
with:
name: "version.json"
json: '{"type": "autobuild", "tag": "N/A", "commit": "${{ steps.vars.outputs.sha_short }}", "date": "${{ steps.date.outputs.date }}"}'
@@ -55,7 +55,7 @@ jobs:
Copy-Item -Path ./backend/*.js -Destination ./build/youtubedl-material
Copy-Item -Path ./backend/*.json -Destination ./build/youtubedl-material
- name: upload build artifact
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v3
with:
name: youtubedl-material
path: build

View File

@@ -18,7 +18,7 @@ jobs:
run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
- name: create-json
id: create-json
uses: jsdaniell/create-json@1.1.2
uses: jsdaniell/create-json@v1.2.2
with:
name: "version.json"
json: '{"type": "docker", "tag": "nightly", "commit": "${{ steps.vars.outputs.sha_short }}", "date": "${{ steps.date.outputs.date }}"}'

View File

@@ -27,7 +27,7 @@ jobs:
- name: create-json
id: create-json
uses: jsdaniell/create-json@1.1.2
uses: jsdaniell/create-json@v1.2.2
with:
name: "version.json"
json: '{"type": "docker", "tag": "latest", "commit": "${{ steps.vars.outputs.sha_short }}", "date": "${{ steps.date.outputs.date }}"}'
@@ -60,10 +60,10 @@ jobs:
uses: docker/setup-qemu-action@v1
- name: setup multi-arch docker build
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View File

@@ -34,7 +34,7 @@ jobs:
- name: create-json
id: create-json
uses: jsdaniell/create-json@1.1.2
uses: jsdaniell/create-json@v1.2.2
with:
name: "version.json"
json: '{"type": "docker", "tag": "${{secrets.DOCKERHUB_MASTER_TAG}}", "commit": "${{ steps.vars.outputs.sha_short }}", "date": "${{ steps.date.outputs.date }}"}'
@@ -44,7 +44,7 @@ jobs:
uses: docker/setup-qemu-action@v1
- name: setup multi-arch docker build
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Generate Docker image metadata
id: docker-meta
@@ -63,7 +63,7 @@ jobs:
type=sha,prefix=sha-,format=short
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View File

@@ -37,6 +37,8 @@ COPY [ "src/", "/build/src/" ]
RUN npm install && \
npm run build && \
ls -al /build/backend/public
RUN npm uninstall -g @angular/cli
RUN rm -rf node_modules
# Install backend deps
@@ -71,6 +73,7 @@ COPY --chown=$UID:$GID --from=ffmpeg [ "/usr/local/bin/ffmpeg", "/usr/local/bin/
COPY --chown=$UID:$GID --from=ffmpeg [ "/usr/local/bin/ffprobe", "/usr/local/bin/ffprobe" ]
COPY --chown=$UID:$GID --from=backend ["/app/","/app/"]
COPY --chown=$UID:$GID --from=frontend [ "/build/backend/public/", "/app/public/" ]
COPY --chown=$UID:$GID --from=python ["/app/TwitchDownloaderCLI","/usr/local/bin/TwitchDownloaderCLI"]
RUN chown $UID:$GID .
RUN chmod +x /app/fix-scripts/*.sh
# Add some persistence data

View File

@@ -28,13 +28,29 @@ Dark mode:
NOTE: If you would like to use Docker, you can skip down to the [Docker](#Docker) section for a setup guide.
Debian/Ubuntu:
Required dependencies:
* Node.js 16
* Python
Optional dependencies:
* AtomicParsley (for embedding thumbnails, package name `atomicparsley`)
* [tcd](https://github.com/PetterKraabol/Twitch-Chat-Downloader) (for downloading Twitch VOD chats)
<details>
<summary>Debian/Ubuntu</summary>
```bash
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install nodejs youtube-dl ffmpeg unzip python npm
```
CentOS 7:
</details>
<details>
<summary>CentOS 7</summary>
```bash
sudo yum install epel-release
@@ -42,13 +58,11 @@ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfu
sudo yum install centos-release-scl-rh
sudo yum install rh-nodejs12
scl enable rh-nodejs12 bash
curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -
sudo yum install nodejs youtube-dl ffmpeg ffmpeg-devel
```
Optional dependencies:
* AtomicParsley (for embedding thumbnails, package name `atomicparsley`)
* [tcd](https://github.com/PetterKraabol/Twitch-Chat-Downloader) (for downloading Twitch VOD chats)
</details>
### Installing

View File

@@ -2,7 +2,6 @@ const { uuid } = require('uuidv4');
const fs = require('fs-extra');
const { promisify } = require('util');
const auth_api = require('./authentication/auth');
const winston = require('winston');
const path = require('path');
const compression = require('compression');
const multer = require('multer');
@@ -19,6 +18,7 @@ const CONSTS = require('./consts')
const read_last_lines = require('read-last-lines');
const ps = require('ps-node');
const Feed = require('feed').Feed;
const session = require('express-session');
// needed if bin/details somehow gets deleted
if (!fs.existsSync(CONSTS.DETAILS_BIN_PATH)) fs.writeJSONSync(CONSTS.DETAILS_BIN_PATH, {"version":"2000.06.06","path":"node_modules\\youtube-dl\\bin\\youtube-dl.exe","exec":"youtube-dl.exe","downloader":"youtube-dl"})
@@ -163,6 +163,7 @@ app.use(bodyParser.json());
// use passport
app.use(auth_api.passport.initialize());
app.use(session({ secret: uuid(), resave: true, saveUninitialized: true }))
app.use(auth_api.passport.session());
// actual functions

View File

@@ -50,7 +50,8 @@
"telegram_bot_token": "",
"telegram_chat_id": "",
"webhook_URL": "",
"discord_webhook_URL": ""
"discord_webhook_URL": "",
"slack_webhook_URL": ""
},
"Themes": {
"default_theme": "default",

View File

@@ -220,7 +220,8 @@ const DEFAULT_CONFIG = {
"telegram_bot_token": "",
"telegram_chat_id": "",
"webhook_URL": "",
"discord_webhook_URL": ""
"discord_webhook_URL": "",
"slack_webhook_URL": "",
},
"Themes": {
"default_theme": "default",

View File

@@ -162,6 +162,10 @@ exports.CONFIG_ITEMS = {
'key': 'ytdl_discord_webhook_url',
'path': 'YoutubeDLMaterial.API.discord_webhook_URL'
},
'ytdl_slack_webhook_url': {
'key': 'ytdl_slack_webhook_url',
'path': 'YoutubeDLMaterial.API.slack_webhook_URL'
},
// Themes

View File

@@ -169,7 +169,7 @@ exports._connectToDB = async (custom_connection_string = null) => {
exports.setVideoProperty = async (file_uid, assignment_obj) => {
// TODO: check if video exists, throw error if not
await db_api.updateRecord('files', {uid: file_uid}, assignment_obj);
await exports.updateRecord('files', {uid: file_uid}, assignment_obj);
}
exports.getFileDirectoriesAndDBs = async () => {

View File

@@ -64,6 +64,9 @@ exports.sendNotification = async (notification) => {
if (config_api.getConfigItem('ytdl_discord_webhook_url')) {
sendDiscordNotification(data);
}
if (config_api.getConfigItem('ytdl_slack_webhook_url')) {
sendSlackNotification(data);
}
await db_api.insertRecordIntoTable('notifications', notification);
return notification;
@@ -174,6 +177,65 @@ async function sendDiscordNotification({body, title, type, url, thumbnail}) {
return result;
}
function sendSlackNotification({body, title, type, url, thumbnail}) {
const slack_webhook_url = config_api.getConfigItem('ytdl_slack_webhook_url');
logger.verbose(`Sending slack notification to ${slack_webhook_url}`);
const data = {
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: `*${title}*`
}
},
{
type: "section",
text: {
type: "plain_text",
text: body
}
}
]
}
// add thumbnail if exists
if (thumbnail) {
data['blocks'].push({
type: "image",
image_url: thumbnail,
alt_text: "notification_thumbnail"
});
}
data['blocks'].push(
{
type: "section",
text: {
type: "mrkdwn",
text: `<${url}|${url}>`
}
},
{
type: "context",
elements: [
{
type: "mrkdwn",
text: `*ID:* ${type}`
}
]
}
);
fetch(slack_webhook_url, {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data),
});
}
function sendGenericNotification(data) {
const webhook_url = config_api.getConfigItem('ytdl_webhook_url');
logger.verbose(`Sending generic notification to ${webhook_url}`);

View File

@@ -2036,26 +2036,20 @@
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"lodash": "^4.17.21",
"ms": "^2.1.1",
"semver": "^5.6.0"
"semver": "^7.3.8"
},
"dependencies": {
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
}
}
},
@@ -2200,41 +2194,11 @@
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
"integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lodash.union": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
@@ -2633,11 +2597,21 @@
}
},
"node-id3": {
"version": "0.1.16",
"resolved": "https://registry.npmjs.org/node-id3/-/node-id3-0.1.16.tgz",
"integrity": "sha512-neWBJZxwrWnnebqy0b6gOGpnOPu1l1ASlusVCJUlrgr55ksftcz3lPbP/h4KaFXN+WQX7hh+kmNwkj5DMAa7KA==",
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/node-id3/-/node-id3-0.2.6.tgz",
"integrity": "sha512-w8GuKXLlPpDjTxLowCt/uYMhRQzED3cg2GdSG1i6RSGKeDzPvxlXeLQuQInKljahPZ0aDnmyX7FX8BbJOM7REg==",
"requires": {
"iconv-lite": "^0.4.15"
"iconv-lite": "0.6.2"
},
"dependencies": {
"iconv-lite": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
}
}
}
},
"node-schedule": {
@@ -2862,12 +2836,13 @@
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"passport": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
"integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz",
"integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==",
"requires": {
"passport-strategy": "1.x.x",
"pause": "0.0.1"
"pause": "0.0.1",
"utils-merge": "^1.0.1"
}
},
"passport-http": {
@@ -3288,9 +3263,12 @@
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"send": {
"version": "0.18.0",

View File

@@ -17,6 +17,10 @@
"bugs": {
"url": ""
},
"engines": {
"node": "^16",
"npm": "6.14.4"
},
"homepage": "",
"dependencies": {
"@discordjs/builders": "^1.6.1",
@@ -34,7 +38,7 @@
"fluent-ffmpeg": "^2.1.2",
"fs-extra": "^9.0.0",
"gotify": "^1.1.0",
"jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^9.0.0",
"lodash": "^4.17.21",
"lowdb": "^1.0.0",
"md5": "^2.2.1",
@@ -43,10 +47,10 @@
"mongodb": "^3.6.9",
"multer": "1.4.5-lts.1",
"node-fetch": "^2.6.7",
"node-id3": "^0.1.14",
"node-id3": "^0.2.6",
"node-schedule": "^2.1.0",
"node-telegram-bot-api": "^0.61.0",
"passport": "^0.4.1",
"passport": "^0.6.0",
"passport-http": "^0.3.0",
"passport-jwt": "^4.0.1",
"passport-ldapauth": "^3.0.1",

View File

@@ -25,7 +25,7 @@ async function getCommentsForVOD(vodId) {
return null;
}
const result = await exec(`TwitchDownloaderCLI chatdownload -u ${vodId} -o appdata/${vodId}.json`, {stdio:[0,1,2]});
const result = await exec(`${cliPath} chatdownload -u ${vodId} -o appdata/${vodId}.json`, {stdio:[0,1,2]});
if (result['stderr']) {
logger.error(`Failed to download twitch comments for ${vodId}`);

View File

@@ -18,6 +18,7 @@ services:
- "8998:17442"
image: tzahi12345/youtubedl-material:latest
ytdl-mongo-db:
# If you are using a Raspberry Pi, use mongo:4.4.18
image: mongo:4
logging:
driver: "none"

View File

@@ -3,13 +3,26 @@ import requests
import shutil
import os
import re
import sys
from collections import OrderedDict
from github import Github
machine = platform.machine()
def isARM():
return True if machine.startswith('arm') else False
# https://stackoverflow.com/questions/45125516/possible-values-for-uname-m
MACHINES_TO_ZIP = OrderedDict([
("x86_64", "Linux-x64"),
("aarch64", "LinuxArm64"),
("armv8", "LinuxArm64"),
("arm", "LinuxArm"),
("AMD64", "Windows-x64")
])
def getZipName():
for possibleMachine, possibleZipName in MACHINES_TO_ZIP.items():
if possibleMachine in machine:
return possibleZipName
def getLatestFileInRepo(repo, search_string):
# Create an unauthenticated instance of the Github object
@@ -46,8 +59,11 @@ def getLatestFileInRepo(repo, search_string):
print(f'No release found with {search_string}')
def getLatestCLIRelease():
isArm = isARM()
searchString = r'.*CLI.*' + "LinuxArm.zip" if isArm else "Linux-x64.zip"
zipName = getZipName()
if not zipName:
print(f"GetTwitchDownloader.py could not get valid path for '{machine}'. Exiting...")
sys.exit(1)
searchString = r'.*CLI.*' + zipName
getLatestFileInRepo("lay295/TwitchDownloader", searchString)
getLatestCLIRelease()

821
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -34,18 +34,17 @@
"@angular/platform-browser-dynamic": "^15.0.1",
"@angular/router": "^15.0.1",
"@fontsource/material-icons": "^4.5.4",
"@ngneat/content-loader": "^5.0.0",
"@ngneat/content-loader": "^7.0.0",
"@videogular/ngx-videogular": "^6.0.0",
"core-js": "^2.4.1",
"crypto-js": "^4.1.1",
"file-saver": "^2.0.2",
"filesize": "^10.0.7",
"fingerprintjs2": "^2.1.0",
"fs-extra": "^10.0.0",
"material-icons": "^1.10.8",
"nan": "^2.14.1",
"ngx-avatars": "^1.4.1",
"ngx-file-drop": "^13.0.0",
"ngx-file-drop": "^15.0.0",
"rxjs": "^6.6.3",
"rxjs-compat": "^6.6.7",
"tslib": "^2.0.0",
@@ -66,7 +65,6 @@
"@typescript-eslint/parser": "^4.29.0",
"ajv": "^7.2.4",
"codelyzer": "^6.0.0",
"electron": "^19.1.9",
"eslint": "^7.32.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",

View File

@@ -88,7 +88,7 @@
<ng-container *ngIf="!normal_files_received && loading_files && loading_files.length > 0">
<mat-selection-list *ngIf="!normal_files_received">
<mat-list-option *ngFor="let file of paged_data">
<content-loader class="list-ghosts" [primaryColor]="postsService.theme.ghost_primary" [secondaryColor]="postsService.theme.ghost_secondary" [width]="250" [height]="8"><svg:rect x="0" y="0" rx="3" ry="3" width="250" height="8" /></content-loader>
<content-loader class="list-ghosts" [backgroundColor]="postsService.theme.ghost_primary" [foregroundColor]="postsService.theme.ghost_secondary" viewBox="0 0 250 8"><svg:rect x="0" y="0" rx="3" ry="3" width="250" height="8" /></content-loader>
</mat-list-option>
</mat-selection-list>
</ng-container>

View File

@@ -5,7 +5,7 @@
<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 [backgroundColor]="theme.ghost_primary" [foregroundColor]="theme.ghost_secondary" viewBox="0 0 250 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 -->
<div style="visibility: hidden; position: fixed"
[style.left]="contextMenuPosition.x"
@@ -63,11 +63,11 @@
</div>
<div *ngIf="loading" class="img-div">
<content-loader [primaryColor]="theme.ghost_primary" [secondaryColor]="theme.ghost_secondary" [width]="100" [height]="55"><svg:rect x="0" y="0" rx="0" ry="0" width="100" height="55" /></content-loader>
<content-loader [backgroundColor]="theme.ghost_primary" [foregroundColor]="theme.ghost_secondary" viewBox="0 0 100 55"><svg:rect x="0" y="0" rx="0" ry="0" width="100" height="55" /></content-loader>
</div>
<span *ngIf="!loading" [ngClass]="{'max-two-lines': card_size !== 'small', 'max-one-line': card_size === 'small' }">{{card_size === 'large' && file_obj.uploader ? file_obj.uploader + ' - ' : ''}}<strong>{{!is_playlist ? file_obj.title : file_obj.name}}</strong></span>
<span *ngIf="loading" class="title-loading"><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></span>
<span *ngIf="loading" class="title-loading"><content-loader [backgroundColor]="theme.ghost_primary" [foregroundColor]="theme.ghost_secondary" viewBox="0 0 250 30"><svg:rect x="0" y="0" rx="3" ry="3" width="250" height="30" /></content-loader></span>
</div>
</mat-card>
</div>

View File

@@ -8,7 +8,6 @@ import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { DOCUMENT } from '@angular/common';
import { BehaviorSubject, Observable } from 'rxjs';
import { MatSnackBar } from '@angular/material/snack-bar';
import * as Fingerprint2 from 'fingerprintjs2';
import {
ChangeRolePermissionsRequest,
ChangeUserPermissionsRequest,
@@ -131,7 +130,6 @@ export class PostsService implements CanActivate {
// auth
auth_token = '4241b401-7236-493e-92b5-b72696b9d853';
session_id = null;
httpOptions: {
params: HttpParams
};
@@ -187,12 +185,6 @@ export class PostsService implements CanActivate {
})
};
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);
});
const redirect_not_required = window.location.href.includes('/player') || window.location.href.includes('/login');
// get config
@@ -796,7 +788,7 @@ export class PostsService implements CanActivate {
resetHttpParams() {
// resets http params
this.http_params = `apiKey=${this.auth_token}&sessionID=${this.session_id}`
this.http_params = `apiKey=${this.auth_token}`
this.httpOptions = {
params: new HttpParams({

View File

@@ -387,9 +387,16 @@
</div>
<div class="col-12 mb-2 mt-3">
<mat-form-field class="text-field" color="accent">
<mat-label i18n="Discord webhook URL">Discord Webhook URL</mat-label>
<mat-label i18n="Discord Webhook URL">Discord Webhook URL</mat-label>
<input placeholder="https://discord.com/api/webhooks/<webhook_id>/<webhook_token>" [(ngModel)]="new_config['API']['discord_webhook_URL']" matInput>
<mat-hint><a target="_blank" href="https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks"><ng-container i18n="Gotify API setting hint">See docs here.</ng-container></a></mat-hint>
<mat-hint><a target="_blank" href="https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks"><ng-container i18n="Discord API setting hint">See docs here.</ng-container></a></mat-hint>
</mat-form-field>
</div>
<div class="col-12 mb-2 mt-3">
<mat-form-field class="text-field" color="accent">
<mat-label i18n="Slack Webhook URL">Slack Webhook URL</mat-label>
<input placeholder="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX" [(ngModel)]="new_config['API']['slack_webhook_URL']" matInput>
<mat-hint><a target="_blank" href="https://api.slack.com/messaging/webhooks"><ng-container i18n="Slack API setting hint">See docs here.</ng-container></a></mat-hint>
</mat-form-field>
</div>
<div class="col-12 mt-3">