Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb866f32be | ||
| 1577eced3f | |||
|
|
b097755664 | ||
|
|
473d2943a5 | ||
|
|
01bb24eb3a | ||
|
|
6d0ca200e9 | ||
|
|
4feda2d8de | ||
|
|
408ebf185b | ||
|
|
3c79b3c9ed | ||
|
|
a78e200ea1 | ||
|
|
5b126f3a5e | ||
|
|
1165049b18 | ||
|
|
48a357c039 | ||
|
|
c6f237d1ba |
325
README.md
325
README.md
@@ -1,39 +1,298 @@
|
|||||||
# 🎵 Deezer Downloader for Nextcloud WebDav
|
# 🎵 Deezer Downloader for Nextcloud
|
||||||
|
|
||||||
## 🧩 Description
|
## 🧩 Description
|
||||||
|
|
||||||
Ce projet a pour objectif d’évoluer en une **application Nextcloud**.
|
Ce projet a pour objectif d’évoluer vers une **application Nextcloud native**.
|
||||||
Pour l’instant, il s’agit d’une **application externe utilasant WEBDAV **.
|
Pour le moment, il s’agit d’une **application externe** avec dossier partagé et commande SSH pour interagir avec Nextcloud.
|
||||||
|
|
||||||
Le projet est basé sur le dépôt GitHub de [deezer-downloader](https://github.com/kmille/deezer-downloader).
|
Le projet est basé sur le dépôt GitHub original : [kmille/deezer-downloader](https://github.com/kmille/deezer-downloader).
|
||||||
Un grand merci aux auteurs pour leur excellent travail !
|
👉 Un grand merci à ses auteurs pour leur excellent travail !
|
||||||
|
|
||||||
## ❓ Pourquoi
|
---
|
||||||
|
|
||||||
Je souhaitais intégrer à **Nextcloud** un **raccourci** permettant aux utilisateurs de **télécharger leur musique, playlists, albums**, etc., directement depuis **Nextcloud**.
|
## ❓ Objectif
|
||||||
Les téléchargement sont directement accessible des **Fichiers** de Nextcloud. Vous pouvez aussi choisir un répertoire situé dans le dossier de syncronisation de l'application interne **Musique** pour profiter directement du téléchargement sur une appli de streaming style subsonic...
|
|
||||||
|
L’idée est d’intégrer à **Nextcloud** un **raccourci** permettant aux utilisateurs de **télécharger leurs musiques, albums et playlists** directement depuis leur espace Nextcloud.
|
||||||
|
Les téléchargements sont accessibles depuis la section **Fichiers**.
|
||||||
|
Il est également possible de choisir un répertoire dans le dossier de synchronisation de l’application interne **Musique**, afin d’écouter les morceaux depuis une appli compatible **Subsonic** ou équivalent.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🔧 Modifications apportées par rapport au dépôt original
|
## 🔧 Modifications apportées par rapport au dépôt original
|
||||||
|
|
||||||
* 🔐 Utilisation du **JWT de Nextcloud** pour obtenir les informations d’identification de l’utilisateur connecté.
|
- 🔐 Utilisation du **JWT Nextcloud** pour récupérer les informations de l’utilisateur connecté.
|
||||||
* 📂 Téléchargement des fichiers dans le **dossier personnel** de l’utilisateur connecté, dans un répertoire créé à la racine : `DeezerDl`.
|
- 📂 Téléchargement dans le **dossier personnel** de l’utilisateur : `Music/DeezerDl`.
|
||||||
* 🍪 Utilisation d’un **cookie** pour sauvegarder le répertoire de destination choisi par l’utilisateur.
|
- 🚫 Vérification de la **connexion Nextcloud** : si non connecté → retour **403 Forbidden**.
|
||||||
* 🚫 Vérification de la **connexion à Nextcloud** : si non connecté → retour **403 Forbidden**.
|
|
||||||
|
|
||||||
## Dev sous windows (vsCode):
|
---
|
||||||
|
|
||||||
|
# 🧱 Installation sur Nextcloud (Debian 12)
|
||||||
|
|
||||||
|
## ⚙️ 1. Préparer le conteneur DeezerDownloader
|
||||||
|
|
||||||
|
### 🔄 Mise à jour
|
||||||
|
```bash
|
||||||
|
apt update && apt upgrade -y
|
||||||
|
````
|
||||||
|
|
||||||
|
### 📁 Monter le dossier Nextcloud
|
||||||
|
|
||||||
|
Créer un point de montage vers le répertoire de données Nextcloud :
|
||||||
|
|
||||||
Pour que powershell accepte d'exécuter des scripts:
|
|
||||||
```
|
```
|
||||||
|
mp0: /Data/NAS/nextcloud/data_directory/data/,mp=/nextcloud_user_data
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 👤 2. Créer l’utilisateur `www-data`
|
||||||
|
|
||||||
|
### Vérifier s’il existe déjà
|
||||||
|
|
||||||
|
```bash
|
||||||
|
id www-data
|
||||||
|
```
|
||||||
|
|
||||||
|
S’il n’existe pas :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
groupadd www-data
|
||||||
|
useradd -r -s /usr/sbin/nologin -g www-data www-data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Synchroniser l’UID et le GID avec ceux du conteneur Nextcloud
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls -ln /nextcloud_user_data/
|
||||||
|
# Exemple de sortie :
|
||||||
|
# drwxr-xr-x 5 100033 100033 5 Oct 19 14:57 Parent
|
||||||
|
```
|
||||||
|
|
||||||
|
Ici, l’UID et le GID sont `100033` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
usermod -u 100033 www-data
|
||||||
|
groupmod -g 100033 www-data
|
||||||
|
```
|
||||||
|
|
||||||
|
Vérifier :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
id www-data
|
||||||
|
# uid=100033(www-data) gid=100033(www-data) groups=100033(www-data)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐍 3. Installer Python et créer le venv
|
||||||
|
|
||||||
|
Installer Python et ses dépendances :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install -y python3 python3-venv python3-pip sudo ffmpeg
|
||||||
|
```
|
||||||
|
|
||||||
|
Créer le venv :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /var/www/venv
|
||||||
|
chown www-data:www-data /var/www/venv
|
||||||
|
chmod 750 /var/www/venv
|
||||||
|
sudo -u www-data python3 -m venv /var/www/venv
|
||||||
|
```
|
||||||
|
|
||||||
|
Vérifier le fonctionnement :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u www-data bash
|
||||||
|
source /var/www/venv/bin/activate
|
||||||
|
python --version
|
||||||
|
pip --version
|
||||||
|
deactivate
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 4. Installer DeezerDownloader
|
||||||
|
|
||||||
|
### Cloner le dépôt
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /var/www/app
|
||||||
|
sudo chown www-data:www-data /var/www/app
|
||||||
|
apt install -y git
|
||||||
|
sudo -u www-data git clone https://git.bonisco.fr/Grizouille/Deezer-Downloader-Nextcloud.git /var/www/app
|
||||||
|
```
|
||||||
|
|
||||||
|
### Installer les dépendances
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u www-data /var/www/venv/bin/pip install /var/www/app
|
||||||
|
sudo -u www-data /var/www/venv/bin/pip install yt-dlp paramiko PyJWT
|
||||||
|
```
|
||||||
|
|
||||||
|
### Générer et modifier le fichier de configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u www-data bash
|
||||||
|
source /var/www/venv/bin/activate
|
||||||
|
deezer-downloader --show-config-template > /var/www/app/config.ini
|
||||||
|
deactivate
|
||||||
|
```
|
||||||
|
|
||||||
|
📝 Ensuite, édite `/var/www/app/config.ini` (les explications sont dans le fichier).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ 5. Créer un service systemd
|
||||||
|
|
||||||
|
Créer le fichier `/etc/systemd/system/deezer_downloader.service` :
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Deezer Downloader Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=www-data
|
||||||
|
Group=www-data
|
||||||
|
WorkingDirectory=/var/www/app
|
||||||
|
ExecStart=/var/www/venv/bin/deezer-downloader --config /var/www/app/config.ini
|
||||||
|
Restart=on-failure
|
||||||
|
Environment="PATH=/var/www/venv/bin:/usr/bin"
|
||||||
|
Environment=PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 6. Configurer les permissions Nextcloud
|
||||||
|
|
||||||
|
Dans le conteneur Nextcloud :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adduser nextclouddeezer
|
||||||
|
apt install sudo
|
||||||
|
nano /etc/sudoers
|
||||||
|
```
|
||||||
|
|
||||||
|
Ajouter à la fin du fichier :
|
||||||
|
|
||||||
|
```
|
||||||
|
nextclouddeezer ALL=(www-data) NOPASSWD: /usr/bin/php
|
||||||
|
```
|
||||||
|
|
||||||
|
Cela permet à l’utilisateur `nextclouddeezer` d’exécuter des commandes PHP sous `www-data`.
|
||||||
|
|
||||||
|
➡️ Ensuite, dans le `config.ini` du conteneur DeezerDownloader, renseigne le mot de passe de cet utilisateur.
|
||||||
|
|
||||||
|
Pour avoir la clé public pour décrypter le JWT tapé la ligne suivante sur le container nextcloud et ajouter le au fichier de config.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo -u www-data php occ config:app:get external jwt_token_pubkey_es256
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ 7. Activer et démarrer le service
|
||||||
|
|
||||||
|
🔁 Recharge systemd, active le service au démarrage et lance-le immédiatement :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable deezer_downloader.service
|
||||||
|
sudo systemctl start deezer_downloader.service
|
||||||
|
```
|
||||||
|
|
||||||
|
📋 Pour vérifier les logs en direct :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u deezer_downloader.service -f
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 8. Intégrer Deezer Downloader dans l’interface Nextcloud
|
||||||
|
|
||||||
|
1. Ouvre **Paramètres d’administration** → **Sites externes** dans Nextcloud.
|
||||||
|
2. Clique sur ➕ **Ajouter un nouveau site**.
|
||||||
|
3. Renseigne l’URL suivante :
|
||||||
|
|
||||||
|
```
|
||||||
|
https://votre.url.fr/deezer/?jwt={jwt}
|
||||||
|
```
|
||||||
|
|
||||||
|
(Remplace `votre.url.fr` par ton domaine ou IP publique.)
|
||||||
|
4. (Optionnel) Ajoute une **icône personnalisée** pour le menu :
|
||||||
|
🖼️ L’image se trouve ici → `doc/deezerDownloader.png`
|
||||||
|
|
||||||
|
💡 Une fois ajouté, le lien apparaîtra directement dans la barre latérale de Nextcloud pour tous les utilisateurs autorisés.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧠 9. Bonus : configuration du reverse proxy Nginx
|
||||||
|
|
||||||
|
💡 Pour éviter de gérer un énième nom de domaine **et** contourner les problèmes de **CORS**, j’ai simplement ajouté un bloc de configuration dans **le reverse proxy Nginx** qui gère déjà les certificats SSL de **Nextcloud**.
|
||||||
|
|
||||||
|
Voici le **bloc ajouté** à la configuration Nginx de Nextcloud :
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
location /deezer/ {
|
||||||
|
set_real_ip_from 192.168.10.8/24;
|
||||||
|
real_ip_header proxy_protocol;
|
||||||
|
proxy_pass http://192.168.10.12:5000/;
|
||||||
|
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
proxy_set_header X-Forwarded-Server $host;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
🔀 **Explication rapide :**
|
||||||
|
|
||||||
|
* `location /deezer/` → redirige toutes les requêtes Nextcloud vers ton conteneur **DeezerDownloader**.
|
||||||
|
* `proxy_pass http://192.168.10.12:5000/` → correspond à l’adresse interne de ton service Python.
|
||||||
|
* Les directives `proxy_set_header` assurent la transmission correcte des en-têtes HTTP et des IP réelles.
|
||||||
|
|
||||||
|
✅ Résultat : tu peux accéder à **DeezerDownloader** directement depuis ton domaine Nextcloud, par exemple :
|
||||||
|
|
||||||
|
```
|
||||||
|
https://cloud.mondomaine.fr/deezer/
|
||||||
|
```
|
||||||
|
|
||||||
|
…sans erreur CORS, ni besoin d’un certificat supplémentaire.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 💻 Développement sous Windows (VS Code)
|
||||||
|
|
||||||
|
Autoriser l’exécution de scripts PowerShell :
|
||||||
|
|
||||||
|
```powershell
|
||||||
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
|
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
|
||||||
```
|
```
|
||||||
|
|
||||||
venv activer avec:
|
Activer le venv :
|
||||||
```
|
|
||||||
|
```powershell
|
||||||
.\.venv\Scripts\Activate.ps1
|
.\.venv\Scripts\Activate.ps1
|
||||||
```
|
```
|
||||||
|
|
||||||
Install:
|
Installer et exécuter le projet :
|
||||||
```
|
|
||||||
|
```powershell
|
||||||
pip install poetry
|
pip install poetry
|
||||||
git clone https://github.com/kmille/deezer-downloader.git
|
git clone https://github.com/kmille/deezer-downloader.git
|
||||||
cd deezer-downloader
|
cd deezer-downloader
|
||||||
@@ -41,32 +300,14 @@ poetry install
|
|||||||
poetry run deezer-downloader --show-config-template > settings.ini
|
poetry run deezer-downloader --show-config-template > settings.ini
|
||||||
```
|
```
|
||||||
|
|
||||||
run du srv en ligne de cmd:
|
Lancer le serveur :
|
||||||
```
|
|
||||||
|
```powershell
|
||||||
poetry run deezer-downloader --config .\deezer_downloader\settings.ini
|
poetry run deezer-downloader --config .\deezer_downloader\settings.ini
|
||||||
```
|
```
|
||||||
|
|
||||||
# Installation sur NextCloud (Debian 12)
|
---
|
||||||
|
|
||||||
Dans le container nextcloud:
|
✍️ **Auteur** : [Grizouille](https://git.bonisco.fr/Grizouille)
|
||||||
```
|
💡 Basé sur le travail de [kmille/deezer-downloader](https://github.com/kmille/deezer-downloader)
|
||||||
adduser nextclouddeezer
|
|
||||||
```
|
|
||||||
|
|
||||||
installer `sudo`, puis taper `visudo`,
|
|
||||||
ajouter en fin de fichier la ligne:
|
|
||||||
```
|
|
||||||
nextclouddeezer ALL=(www-data) NOPASSWD: /usr/bin/php
|
|
||||||
```
|
|
||||||
cela permet d'executer des command php avec l'utilisateur `nextclouddeezer`
|
|
||||||
|
|
||||||
Dans le container DeezerDownloader
|
|
||||||
|
|
||||||
* Créer le point de montage où son stoké les données Nextcloud.
|
|
||||||
* Créer un utilisateur `www-data` pour faire tourner le service.
|
|
||||||
* Donner à l'utilisateur `www-data` le meme `uid` user et group que celui de `www-data` du contenair Nextcloud.
|
|
||||||
* `ls -ln /nextcloud_user_data/`
|
|
||||||
* Installer `python` et le `venv`
|
|
||||||
* Installer le site DeezerDownloader
|
|
||||||
* Créer le service pour qu'il soit autonome
|
|
||||||
* Configurer les settings
|
|
||||||
@@ -10,13 +10,13 @@ port = 6600
|
|||||||
music_dir_root = /tmp/deezer-downloader
|
music_dir_root = /tmp/deezer-downloader
|
||||||
|
|
||||||
[download_dirs]
|
[download_dirs]
|
||||||
base = /tmp/deezer-downloader
|
base = /nextcloud_user_data
|
||||||
|
|
||||||
songs = %(base)s/songs
|
songs = %(base)s/{uid}/files/Music/DeezerDl/songs
|
||||||
albums = %(base)s/albums
|
albums = %(base)s/{uid}/files/Music/DeezerDl/albums
|
||||||
zips = %(base)s/zips
|
zips = %(base)s/{uid}/files/Music/DeezerDl/zips
|
||||||
playlists = %(base)s/playlists
|
playlists = %(base)s/{uid}/files/Music/DeezerDl/playlists
|
||||||
youtubedl = %(base)s/youtube-dl
|
youtubedl = %(base)s/{uid}/files/Music/DeezerDl/youtube-dl
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
; debug output used for /debug
|
; debug output used for /debug
|
||||||
@@ -29,7 +29,7 @@ port = 5000
|
|||||||
|
|
||||||
; if used behind a proxy, specify base url prefix
|
; if used behind a proxy, specify base url prefix
|
||||||
; url_prefix = /deezer
|
; url_prefix = /deezer
|
||||||
url_prefix =
|
url_prefix = /deezer
|
||||||
api_root = %(url_prefix)s
|
api_root = %(url_prefix)s
|
||||||
static_root = %(url_prefix)s/static
|
static_root = %(url_prefix)s/static
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ quality = mp3
|
|||||||
[youtubedl]
|
[youtubedl]
|
||||||
; you are responsible for keeping yt-dlp up-to-date (https://github.com/yt-dlp/yt-dlp)
|
; you are responsible for keeping yt-dlp up-to-date (https://github.com/yt-dlp/yt-dlp)
|
||||||
; command = /home/kmille/projects/deezer-downloader/app/venv/bin/yt-dlp
|
; command = /home/kmille/projects/deezer-downloader/app/venv/bin/yt-dlp
|
||||||
command = /usr/bin/yt-dlp
|
command = /var/www/venv/bin/yt-dlp
|
||||||
|
|
||||||
|
|
||||||
[nextcloud]
|
[nextcloud]
|
||||||
@@ -67,13 +67,13 @@ jwt_name_parameter = jwt
|
|||||||
|
|
||||||
[nextcloud_ssh_scan_files]
|
[nextcloud_ssh_scan_files]
|
||||||
; ip from nextcloud server
|
; ip from nextcloud server
|
||||||
host = 192.168.10.9
|
host = 192.168.1..
|
||||||
; port ssh from nextcloud server
|
; port ssh from nextcloud server
|
||||||
port = 22
|
port = 22
|
||||||
; username ssh nextcloud server
|
; username ssh nextcloud server
|
||||||
username = nextclouddeezer
|
username = nextclouddeezer
|
||||||
; password ssh nextcloud server
|
; password ssh nextcloud server
|
||||||
password = Q8QbqQru3hRc16vK
|
password = dqflfgkfgmvgv615vs
|
||||||
; occ path nextcloud server
|
; occ path nextcloud server
|
||||||
occ_path = /var/www/nextcloud/occ
|
occ_path = /var/www/nextcloud/occ
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -86,14 +86,6 @@ def index():
|
|||||||
static_root=config["http"]["static_root"],
|
static_root=config["http"]["static_root"],
|
||||||
use_mpd=str(config['mpd'].getboolean('use_mpd')).lower())
|
use_mpd=str(config['mpd'].getboolean('use_mpd')).lower())
|
||||||
|
|
||||||
@app.route("/save_config", methods=['POST'])
|
|
||||||
@validate_schema("login", "password", "dirPath")
|
|
||||||
def parameters():
|
|
||||||
user_input = request.get_json(force=True)
|
|
||||||
dir = user_input['dirPath']
|
|
||||||
|
|
||||||
#return jsonify({'error': 'Champs requis manquants'}), 400
|
|
||||||
return jsonify()
|
|
||||||
|
|
||||||
@app.route("/debug")
|
@app.route("/debug")
|
||||||
def show_debug():
|
def show_debug():
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
border: 1px solid #ced4da;
|
border: 1px solid #ced4da;
|
||||||
|
background-color: white;
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
}
|
}
|
||||||
@@ -13,12 +14,12 @@ input.search {
|
|||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: white !important;
|
color: black !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.search {
|
button.search {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
color: white;
|
color: #6c757d;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|||||||
@@ -306,25 +306,6 @@ $(document).ready(function() {
|
|||||||
});
|
});
|
||||||
// END DEEZER FAVORITE SONGS
|
// END DEEZER FAVORITE SONGS
|
||||||
|
|
||||||
$('#paramters').on('submit', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
$.ajax({
|
|
||||||
url: deezer_downloader_api_root + '/save_config',
|
|
||||||
type: 'POST',
|
|
||||||
contentType: 'application/json', // essentiel pour Flask.get_json()
|
|
||||||
data: JSON.stringify({ dirPath: $('#param-directry-path').val(),
|
|
||||||
login: $('#param-login').val(),
|
|
||||||
password: $('#param-password').val()}),
|
|
||||||
success: function(response) {
|
|
||||||
$.jGrowl("Sauvegarder avec succès", { life: 4000 });
|
|
||||||
},
|
|
||||||
error: function(xhr) {
|
|
||||||
const err = xhr.responseJSON?.error || 'Erreur inconnue';
|
|
||||||
$('#result').css('color', 'red').text(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function show_tab(id_nav, id_content) {
|
function show_tab(id_nav, id_content) {
|
||||||
// nav
|
// nav
|
||||||
@@ -338,6 +319,14 @@ $(document).ready(function() {
|
|||||||
$("#" + id_content).addClass("active show")
|
$("#" + id_content).addClass("active show")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('#youtubedl-query-video').on('keypress', function(e) {
|
||||||
|
if (e.which === 13) {
|
||||||
|
e.preventDefault();
|
||||||
|
$('#yt_download_video').click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var bbody = document.getElementById('body');
|
var bbody = document.getElementById('body');
|
||||||
bbody.onkeydown = function (event) {
|
bbody.onkeydown = function (event) {
|
||||||
|
|||||||
@@ -57,9 +57,6 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" id="nav-task-queue" data-toggle="tab" href="#queue">Queue (5)</a>
|
<a class="nav-link" id="nav-task-queue" data-toggle="tab" href="#queue">Queue (5)</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="nav-task-param" data-toggle="tab" href="#param">Parameter (6)</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div> <!-- end row -->
|
</div> <!-- end row -->
|
||||||
|
|
||||||
@@ -108,28 +105,38 @@
|
|||||||
<br>
|
<br>
|
||||||
<h3>Download audio files via youtube-dl</h3>
|
<h3>Download audio files via youtube-dl</h3>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" id="youtubedl-query" placeholder="Download audio from YouTube, Invidious, Vimeo, Soundcloud, ... " />
|
<input type="text" class="form-control" id="youtubedl-query" placeholder="Download audio from YouTube, Invidious, Vimeo, Soundcloud, ... " />
|
||||||
|
</div>
|
||||||
</div>
|
|
||||||
<br>
|
<br>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" class="btn btn-info" id="yt_download_play">Download & Play</button>
|
<button type="button" class="btn btn-info" id="yt_download_play" title="Download & Play Audio">
|
||||||
<button type="button" class="btn btn-info" id="yt_download">Download</button>
|
<i class="fa fa-play"></i> Download & Play
|
||||||
<button type="button" class="btn btn-info" onclick="$('#youtubedl-query').val('')" >Clear</button>
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" id="yt_download" title="Download Audio">
|
||||||
|
<i class="fa fa-download"></i> Download Audio
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" onclick="$('#youtubedl-query').val('')" title="Clear">
|
||||||
|
<i class="fa fa-times"></i> Clear
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
<h3>Download video files via youtube-dl</h3>
|
<h3>Download video files via youtube-dl</h3>
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" class="form-control" id="youtubedl-query-video" placeholder="Download video from YouTube, Invidious, Vimeo, Soundcloud, ... " />
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control" id="youtubedl-query-video" placeholder="Download video from YouTube, Invidious, Vimeo, Soundcloud, ... " />
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" class="btn btn-info" id="yt_download_video">Download</button>
|
<button type="button" class="btn btn-info" id="yt_download_video" title="Download Video">
|
||||||
<button type="button" class="btn btn-info" onclick="$('#youtubedl-query-video').val('')" >Clear</button>
|
<i class="fa fa-download"></i> Download Video
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" onclick="$('#youtubedl-query-video').val('')" title="Clear">
|
||||||
|
<i class="fa fa-times"></i> Clear
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div> <!-- end div tab youtube-dl -->
|
</div>
|
||||||
|
<!-- end div tab youtube-dl -->
|
||||||
|
|
||||||
<div id="spotify-playlists" class="container tab-pane fade">
|
<div id="spotify-playlists" class="container tab-pane fade">
|
||||||
<br>
|
<br>
|
||||||
@@ -143,10 +150,18 @@
|
|||||||
<br>
|
<br>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" class="btn btn-info" id="spotify_download_play">Download & Play</button>
|
<button type="button" class="btn btn-info" id="spotify_download_play" title="Download & Play">
|
||||||
<button type="button" class="btn btn-info" id="spotify_download">Download</button>
|
<i class="fa fa-play"></i> Download & Play
|
||||||
<button type="button" class="btn btn-info" id="spotify_zip">Give me a zip</button>
|
</button>
|
||||||
<button type="button" class="btn btn-info" onclick="$('input[id^=\'spotify\']').val('')" >Clear</button>
|
<button type="button" class="btn btn-info" id="spotify_download" title="Download">
|
||||||
|
<i class="fa fa-download"></i> Download
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" id="spotify_zip" title="Give me a zip">
|
||||||
|
<i class="fa fa-file-archive-o"></i> Give me a zip
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" onclick="$('input[id^=\'spotify\']').val('')" title="Clear">
|
||||||
|
<i class="fa fa-times"></i> Clear
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div> <!-- end div tab spotify playlists -->
|
</div> <!-- end div tab spotify playlists -->
|
||||||
@@ -161,10 +176,18 @@
|
|||||||
<br>
|
<br>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" class="btn btn-info" id="deezer_playlist_download_play">Download & Play</button>
|
<button type="button" class="btn btn-info" id="deezer_playlist_download_play" title="Download & Play">
|
||||||
<button type="button" class="btn btn-info" id="deezer_playlist_download">Download</button>
|
<i class="fa fa-play"></i> Download & Play
|
||||||
<button type="button" class="btn btn-info" id="deezer_playlist_zip">Give me a zip</button>
|
</button>
|
||||||
<button type="button" class="btn btn-info" onclick="$('#deezer-playlist-url').val('')" >Clear</button>
|
<button type="button" class="btn btn-info" id="deezer_playlist_download" title="Download">
|
||||||
|
<i class="fa fa-download"></i> Download
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" id="deezer_playlist_zip" title="Give me a zip">
|
||||||
|
<i class="fa fa-file-archive-o"></i> Give me a zip
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" onclick="$('#deezer-playlist-url').val('')" title="Clear">
|
||||||
|
<i class="fa fa-times"></i> Clear
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -177,10 +200,18 @@
|
|||||||
<br>
|
<br>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" class="btn btn-info" id="deezer_favorites_download_play">Download & Play</button>
|
<button type="button" class="btn btn-info" id="deezer_favorites_download_play" title="Download & Play">
|
||||||
<button type="button" class="btn btn-info" id="deezer_favorites_download">Download</button>
|
<i class="fa fa-play"></i> Download & Play
|
||||||
<button type="button" class="btn btn-info" id="deezer_favorites_zip">Give me a zip</button>
|
</button>
|
||||||
<button type="button" class="btn btn-info" onclick="$('#deezer-favorites-userid').val('')" >Clear</button>
|
<button type="button" class="btn btn-info" id="deezer_favorites_download" title="Download">
|
||||||
|
<i class="fa fa-download"></i> Download
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" id="deezer_favorites_zip" title="Give me a zip">
|
||||||
|
<i class="fa fa-file-archive-o"></i> Give me a zip
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info" onclick="$('#deezer-favorites-userid').val('')" title="Clear">
|
||||||
|
<i class="fa fa-times"></i> Clear
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -203,30 +234,6 @@
|
|||||||
</table>
|
</table>
|
||||||
</div> <!-- end div tab queue -->
|
</div> <!-- end div tab queue -->
|
||||||
|
|
||||||
<div id="param" class="container tab-pane fade">
|
|
||||||
<br>
|
|
||||||
<h3 class="mb-4 text-center">Configuration</h3>
|
|
||||||
|
|
||||||
<form class="p-4 rounded" id="paramters" >
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="directory-path">Directory Path</label>
|
|
||||||
<input type="text" class="form-control" id="param-directry-path" name="directory_path" placeholder="/path/to/folder" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="login">Login</label>
|
|
||||||
<input type="text" class="form-control" id="param-login" name="login" placeholder="Username" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password">Password</label>
|
|
||||||
<input type="password" class="form-control" id="param-password" name="password" placeholder="••••••" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-info btn-block font-weight-bold">Save</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- end div tab parameters -->
|
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|||||||
@@ -13,20 +13,22 @@ class DownloadedFileNotFoundException(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def execute(cmd):
|
def execute(cmd, isVideo):
|
||||||
print('Executing "{}"'.format(cmd))
|
print('Executing "{}"'.format(cmd))
|
||||||
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
|
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
|
||||||
p.wait()
|
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
print(stdout.decode())
|
print(stdout.decode())
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
print(stderr.decode())
|
print(stderr.decode())
|
||||||
raise YoutubeDLFailedException("ERROR: youtube-dl exited with non-zero: \n{}\nYou may have to update it!".format(stderr.decode()))
|
raise YoutubeDLFailedException("ERROR: youtube-dl exited with non-zero: \n{}\nYou may have to update it!".format(stderr.decode()))
|
||||||
return get_absolute_filename(stdout.decode(), stderr.decode())
|
return get_absolute_filename(stdout.decode(), stderr.decode(), isVideo)
|
||||||
|
|
||||||
|
|
||||||
def get_absolute_filename(stdout, stderr):
|
def get_absolute_filename(stdout, stderr, isVideo):
|
||||||
regex_foo = re.search(r'Destination:\s(.*mp3)', stdout)
|
if isVideo:
|
||||||
|
regex_foo = re.search(r'Destination:\s(.*mp4)', stdout)
|
||||||
|
else:
|
||||||
|
regex_foo = re.search(r'Destination:\s(.*mp3)', stdout)
|
||||||
if not regex_foo:
|
if not regex_foo:
|
||||||
raise DownloadedFileNotFoundException("ERROR: Can not extract output file via regex. \nstderr: {}\nstdout: {}".format(stderr, stdout))
|
raise DownloadedFileNotFoundException("ERROR: Can not extract output file via regex. \nstderr: {}\nstdout: {}".format(stderr, stdout))
|
||||||
return regex_foo.group(1)
|
return regex_foo.group(1)
|
||||||
@@ -45,21 +47,23 @@ def youtubedl_download(url, destination_dir, proxy=None, video=False):
|
|||||||
if video:
|
if video:
|
||||||
youtube_dl_cmd = config["youtubedl"]["command"] + \
|
youtube_dl_cmd = config["youtubedl"]["command"] + \
|
||||||
proxy_command + \
|
proxy_command + \
|
||||||
" -f \"best\" " + \
|
" -f b " + \
|
||||||
|
"--no-cache-dir " + \
|
||||||
"--merge-output-format mp4 " + \
|
"--merge-output-format mp4 " + \
|
||||||
f"-o \"{destination_dir}/%(title)s.%(ext)s\" " + \
|
f"-o \"{destination_dir}/%(title)s [video].%(ext)s\" " + \
|
||||||
quote(url)
|
quote(url)
|
||||||
else:
|
else:
|
||||||
youtube_dl_cmd = config["youtubedl"]["command"] + \
|
youtube_dl_cmd = config["youtubedl"]["command"] + \
|
||||||
proxy_command + \
|
proxy_command + \
|
||||||
" -x --audio-format mp3 " + \
|
" -x --audio-format mp3 " + \
|
||||||
"--audio-quality 0 " + \
|
"--audio-quality 0 " + \
|
||||||
f"-o \"{destination_dir}/%(title)s.%(ext)s\" " + \
|
f"-o \"{destination_dir}/%(title)s [audio].%(ext)s\" " + \
|
||||||
"--embed-metadata " + \
|
"--embed-metadata " + \
|
||||||
"--no-embed-chapters " + \
|
"--no-embed-chapters " + \
|
||||||
|
"--no-cache-dir " + \
|
||||||
quote(url)
|
quote(url)
|
||||||
|
|
||||||
filename_absolute = execute(youtube_dl_cmd)
|
filename_absolute = execute(youtube_dl_cmd, video)
|
||||||
return filename_absolute
|
return filename_absolute
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
docs/deezerDownloader.png
Normal file
BIN
docs/deezerDownloader.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Reference in New Issue
Block a user