Compare commits

...

25 Commits

Author SHA1 Message Date
88ee2e4083 Update docker-compose.yaml 2023-05-17 07:46:35 +02:00
76f96060e5 MAJ dossier docker 2023-05-14 08:30:26 +02:00
54a7b8c293 Modification dossier docker 2023-05-13 23:41:28 +02:00
1c47cf5f94 Diverses corrections sur app.py et ajout de la possibilité de télécharger des pistes en plus des albums et des playlists.
Modification du fichier index.html afin d'accepter les liens avec "track"
2023-05-13 23:29:32 +02:00
433e219e62 Modifications 2023-01-22 14:11:31 +01:00
fab1815e7f Ajout dans le code de la création du dossier downloads si ce dernier n'existe pas 2023-01-07 17:17:46 +01:00
cfd041495c Nettoyage du code 2023-01-07 17:13:33 +01:00
1d1e3d4b3d Création dossier downloads et ajout dans gitignore le fait de ne pas sauvegarder ce qu'il y a dans ce dossier 2023-01-07 15:40:25 +01:00
570e36abcd Modifications 2023-01-05 19:05:25 +01:00
Guillaume
33ae0da421
Update style.css 2023-01-04 16:32:42 +01:00
Guillaume
503f2a3d84
Update index.html
Ajout de la ligne permettant la configuration smartphone
2023-01-04 16:29:59 +01:00
Guillaume
d434c632af
Update style.css
Update pour smartphone
2023-01-04 16:28:35 +01:00
Guillaume
c836080a73
Update style.css
Ajout CSS pour encadré procédure
2023-01-04 15:18:11 +01:00
Guillaume
eab6776eac
Update index.html
Ajout de la procédure pour télécharger de la musique.
2023-01-04 15:15:42 +01:00
637d4e585c Plusieurs modifications au niveau des pages et du bouton pour raffraichir 2023-01-03 23:33:04 +01:00
Guillaume
c9cdacd349
Modification bouton reset/refresh 2023-01-03 16:55:58 +01:00
Guillaume
6fb0ab945e
Create erreur.html 2023-01-03 16:54:11 +01:00
3186fce279 Création dossier docker pour build avec Dockerfile, requirements et dossier src 2023-01-03 07:45:30 +01:00
9c4a98bb60 Refonte complète 2023-01-02 22:14:21 +01:00
a8f96501c2 Modification complète du CSS en cours 2023-01-01 21:30:14 +01:00
121da9eefd Nombreuses modifications au niveau du CSS ainsi que sur app.py côté chemins 2022-12-31 20:12:05 +01:00
d2397191a0 Modifications 2022-12-31 11:33:44 +01:00
23d5d0d20d Nombreuses modifications mineures 2022-12-31 11:29:59 +01:00
b764f652c0 Ajout d'une procédure pour télécharger un album ou une playlist, modification des champs url, ajout de la suppression du contenu du dossier downloads en début de script 2022-12-30 00:13:58 +01:00
b0225778a1 Compression des fichiers téléchargés dans downloads et possibilité de les télécharger 2022-12-29 12:59:28 +01:00
29 changed files with 1072 additions and 172 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Ignorer ce qu'il y a dans downloads
downloads/*

3
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

28
Docker/Dockerfile Normal file
View File

@ -0,0 +1,28 @@
FROM alpine:latest
# set the working directory in the container
WORKDIR /app
# copy the dependencies file to the working directory
COPY requirements.txt .
# Update packages
RUN apk update
# Install python3 et pip
RUN apk add python3 py3-pip
# install dependencies
RUN pip install -r requirements.txt
# install ffmpeg for SpotDL
RUN spotdl --download-ffmpeg
# install zip
RUN apk update && apk add zip
# copy the content of the local src directory to the working directory
COPY src/ .
# command to run on container start
CMD [ "python", "./app.py" ]

2
Docker/requirements.txt Normal file
View File

@ -0,0 +1,2 @@
flask
spotdl

9
Docker/spotdlweb.yaml Normal file
View File

@ -0,0 +1,9 @@
version: '3.3'
services:
spotdl_web:
image: 'spotdl_web:latest'
container_name: spotdl_web
hostname: spotdl_web
ports:
- '100:3000'
restart: unless-stopped

68
Docker/src/.old/app.py Normal file
View File

@ -0,0 +1,68 @@
from flask import Flask, request, redirect, url_for, send_file, render_template, send_from_directory
from subprocess import run
from datetime import datetime
import os
import logging
app = Flask(__name__)
def process_file(urls):
download_param_album = '{artist}/{album}/{artist} - {title}'
download_param_playlist = '{playlist}/{artists}/{album} - {title} {artist}'
os.chdir('downloads')
os.system(f'rm -rf *')
#run(['rm', '-rf', '*']) ne fonctionne pas ... ??
for url in urls:
if url:
if "album" in url:
run(['python3', '-m', 'spotdl', url, '--output', download_param_album])
elif "playlist" in url:
run(['python3', '-m', 'spotdl', url, '--output', download_param_playlist])
#os.system(f'zip -r musics.zip ./downloads')
run(['zip', '-r', 'musics.zip', '.'])
os.chdir('../../')
@app.route('/', methods=['GET', 'POST'])
def upload_form():
return render_template('index.html')
#Fonctionne
# @app.route('/download/<filename>')
# def download_file(filename):
# PATH='file.txt'
# return send_file(PATH, as_attachment=True)
@app.route('/download', methods=['POST'])
def download_file():
# votre code de téléchargement ici
# now = datetime.now()
# date_time = now.strftime("%Y-%m-%d %H-%M-%S")
# with open(f"file.txt", "w") as file:
# file.write(date_time)
if request.method == 'POST':
url1 = request.form['url1']
url2 = request.form['url2']
url3 = request.form['url3']
url4 = request.form['url4']
url5 = request.form['url5']
# Vérifier si au moins un champ est vide
if not url1 and not url2 and not url3 and not url4 and not url5:
return render_template('erreur.html')
urls = [url1, url2, url3, url4, url5]
process_file(urls)
PATH = "downloads/musics.zip"
return send_file(PATH, as_attachment=True)
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'), 404
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=3000)

View File

@ -0,0 +1,193 @@
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background-color: #131313;
color: #ffffff;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
box-sizing: border-box;
}
.bordered {
border: 1px solid rgb(24,216,96);
border-radius: 5px;
padding: 20px;
margin-bottom: 20px;
}
li {
font-weight: bold;
}
a {
text-decoration-color: rgb(24,216,96);
color: rgb(24,216,96);
}
.form-group {
display: flex;
flex-direction: column;
margin-bottom: 20px;
}
.form-group label {
font-weight: bold;
margin-bottom: 5px;
}
.form-control {
background-color: #232323;
border: none;
border-radius: 5px;
padding: 10px;
color: #ffffff;
}
/* .form-control:focus {
outline: none;
box-shadow: 0 0 0 2px rgb(24,216,96);
} */
.form-control:valid:not(:placeholder-shown) {
outline: none;
border: 2px solid rgb(24,216,96);
}
.form-control:invalid {
outline: none;
border: 2px solid red;
}
.btn {
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn2 {
margin-top: 10px;
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn:hover {
background-color: rgb(24,216,96);
color: whitesmoke
}
h1 {
color: rgb(24,216,96);
}
@media (max-width: 600px) {
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background-color: #131313;
color: #ffffff;
}
.container {
max-width: 100%;
margin: 0;
padding: 10px;
box-sizing: border-box;
}
.bordered {
border: 1px solid rgb(24,216,96);
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
}
li {
font-weight: bold;
}
a {
text-decoration-color: rgb(24,216,96);
color: rgb(24,216,96);
}
.form-group {
display: flex;
flex-direction: column;
margin-bottom: 10px;
}
.form-group label {
font-weight: bold;
margin-bottom: 5px;
}
.form-control {
background-color: #232323;
border: none;
border-radius: 5px;
padding: 10px;
color: #ffffff;
}
/* .form-control:focus {
outline: none;
box-shadow: 0 0 0 2px rgb(24,216,96);
} */
.form-control:valid:not(:placeholder-shown) {
outline: none;
border: 2px solid rgb(24,216,96);
}
.form-control:invalid {
outline: none;
border: 2px solid red;
}
.btn {
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn2 {
margin-top: 10px;
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn:hover {
background-color: rgb(24,216,96);
color: whitesmoke
}
h1 {
color: rgb(24,216,96);
}
}

View File

@ -0,0 +1,15 @@
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/css/style.css", filename= 'style.css'>
<title>SpotDL Web</title>
</head>
<body>
<div class="container">
<h1>Error 404</h1>
<h2>Il semble que vous soyez perdu. Revenez à la page d'accueil</h2>
<button class="btn" onclick="window.location.href = '/';">Accueil</button>
</div>
</body>

View File

@ -0,0 +1,18 @@
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/css/style.css", filename= 'style.css'>
<title>SpotDL Web</title>
</head>
<body>
<div class="container">
<h1 class="title"> SpotDL Web </h1>
<h2> Veuillez entrer au moins une URL ! </h2>
<button class="btn" onclick="window.location.href = '/';">Accueil</button>
{% if message %}
<p>{{ message }}</p>
{% endif %}
</div>
</body>

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/css/style.css", filename= 'style.css'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SpotDL Web</title>
</head>
<body>
<div class="container">
<h1 class="title">SpotDL Web</h1>
<div class="bordered">
<p>
<h3>Procédure</h3>
<ul>
<li>Se rendre sur Spotify en cliquant <a rel="stylesheet" href="https://open.spotify.com/" target="_blank">ici</a></li>
<li>Chercher un Album ou une Playlist</li>
<li>Sur Ordinateur : A droite du coeur, cliquez sur ... puis Partager et Copier le lien vers (Album ou Playlist)</li>
<li>Sur Smartphone : Cliquez sur le logo de partage puis Copier le lien</li>
</ul>
</p>
</div>
<form action="/download" method="POST">
<div class="form-group">
<input type="text" class="form-control" name="url1" id="url1" pattern="^https://open\.spotify\.com/(?:album|playlist)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url2" id="url2" pattern="^https://open\.spotify\.com/(?:album|playlist)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url3" id="url3" pattern="^https://open\.spotify\.com/(?:album|playlist)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url4" id="url4" pattern="^https://open\.spotify\.com/(?:album|playlist)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url5" id="url5" pattern="^https://open\.spotify\.com/(?:album|playlist)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<button type="submit" class="btn" id="download-button" onclick="startDownload()">Télécharger</button>
<button type="reset" class="btn" id="refresh-button" onclick="refreshPage()">Rafraîchir</button>
</form>
<!-- <button class="btn2" id="refresh-button" onclick="refreshPage()">Rafraîchir</button> -->
<!-- <button type="reset" class="btn" id="refresh-button" onclick="refreshPage()">Rafraîchir</button> -->
</div>
<script>
function startDownload() {
document.getElementById('download-button').innerHTML = 'Téléchargement en cours...';
}
function refreshPage() {
window.location.reload();
}
</script>
</body>
</html

61
Docker/src/app.py Normal file
View File

@ -0,0 +1,61 @@
from flask import Flask, request, send_file, render_template
from subprocess import run
import os
import secrets
app = Flask(__name__)
app.secret_key = secrets.token_hex(16)
@app.route('/', methods=['GET', 'POST'])
def download_file():
session_id = secrets.token_hex(16)
download_param_album = '{artist}/{album}/{artist} - {title}'
download_param_playlist = '{playlist}/{artists}/{album} - {title} {artist}'
download_param_track = '{artist}/{album}/{artist} - {title}'
if request.method == 'POST':
url1 = request.form['url1']
url2 = request.form['url2']
url3 = request.form['url3']
url4 = request.form['url4']
url5 = request.form['url5']
# Vérifier si au moins un champ est vide
if not url1 and not url2 and not url3 and not url4 and not url5:
return render_template('erreur.html')
urls = [url1, url2, url3, url4, url5]
# Créer le dossier 'downloads' s'il n'existe pas
if not os.path.exists('downloads'):
os.makedirs('downloads')
os.chdir('downloads')
os.system(f'rm -rf *')
for url in urls:
if url:
if "album" in url:
run(['python3', '-m', 'spotdl', url, '--output', download_param_album])
elif "playlist" in url:
run(['python3', '-m', 'spotdl', url, '--output', download_param_playlist])
elif "track" in url:
run(['python3', '-m', 'spotdl', url, '--output', download_param_track])
run(['zip', '-r', 'musics.zip', '.'])
os.chdir('../')
path = "downloads/musics.zip"
return send_file(path, as_attachment=True)
return render_template('index.html')
@app.errorhandler(404)
def page_not_found():
return render_template('404.html'), 404
if __name__ == '__main__':
app.run(debug=True, port=3000)

View File

@ -0,0 +1,193 @@
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background-color: #131313;
color: #ffffff;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
box-sizing: border-box;
}
.bordered {
border: 1px solid rgb(24,216,96);
border-radius: 5px;
padding: 20px;
margin-bottom: 20px;
}
li {
font-weight: bold;
}
a {
text-decoration-color: rgb(24,216,96);
color: rgb(24,216,96);
}
.form-group {
display: flex;
flex-direction: column;
margin-bottom: 20px;
}
.form-group label {
font-weight: bold;
margin-bottom: 5px;
}
.form-control {
background-color: #232323;
border: none;
border-radius: 5px;
padding: 10px;
color: #ffffff;
}
/* .form-control:focus {
outline: none;
box-shadow: 0 0 0 2px rgb(24,216,96);
} */
.form-control:valid:not(:placeholder-shown) {
outline: none;
border: 2px solid rgb(24,216,96);
}
.form-control:invalid {
outline: none;
border: 2px solid red;
}
.btn {
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn2 {
margin-top: 10px;
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn:hover {
background-color: rgb(24,216,96);
color: whitesmoke
}
h1 {
color: rgb(24,216,96);
}
@media (max-width: 600px) {
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background-color: #131313;
color: #ffffff;
}
.container {
max-width: 100%;
margin: 0;
padding: 10px;
box-sizing: border-box;
}
.bordered {
border: 1px solid rgb(24,216,96);
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
}
li {
font-weight: bold;
}
a {
text-decoration-color: rgb(24,216,96);
color: rgb(24,216,96);
}
.form-group {
display: flex;
flex-direction: column;
margin-bottom: 10px;
}
.form-group label {
font-weight: bold;
margin-bottom: 5px;
}
.form-control {
background-color: #232323;
border: none;
border-radius: 5px;
padding: 10px;
color: #ffffff;
}
/* .form-control:focus {
outline: none;
box-shadow: 0 0 0 2px rgb(24,216,96);
} */
.form-control:valid:not(:placeholder-shown) {
outline: none;
border: 2px solid rgb(24,216,96);
}
.form-control:invalid {
outline: none;
border: 2px solid red;
}
.btn {
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn2 {
margin-top: 10px;
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn:hover {
background-color: rgb(24,216,96);
color: whitesmoke
}
h1 {
color: rgb(24,216,96);
}
}

View File

@ -0,0 +1,6 @@
function startDownload() {
document.getElementById('download-button').innerHTML = 'Téléchargement en cours...';
}
function refreshPage() {
window.location.reload();
}

View File

@ -0,0 +1,14 @@
{% extends 'layout.html' %}
{% block body %}
<body>
<div class="container">
<h1>Error 404</h1>
<h2>Il semble que vous soyez perdu. Revenez à la page d'accueil</h2>
<button class="btn" onclick="window.location.href = '/';">Accueil</button>
</div>
</body>
{% endblock body %}

View File

@ -0,0 +1,18 @@
{% extends 'layout.html' %}
{% block body %}
<body>
<div class="container">
<h1 class="title"> SpotDL Web </h1>
<h2> Veuillez entrer au moins une URL ! </h2>
<button class="btn" onclick="window.location.href = '/';">Accueil</button>
{% if message %}
<p>{{ message }}</p>
{% endif %}
</div>
</body>
{% endblock body %}

View File

@ -0,0 +1,39 @@
{% extends 'layout.html' %}
{% block body %}
<div class="container">
<h1 class="title">SpotDL Web</h1>
<div class="bordered">
<p>
<h3>Procédure</h3>
<ul>
<li>Se rendre sur Spotify en cliquant <a rel="stylesheet" href="https://open.spotify.com/" target="_blank">ici</a></li>
<li>Chercher un Album ou une Playlist</li>
<li>Sur Ordinateur : A droite du coeur, cliquez sur ... puis Partager et Copier le lien vers (Album ou Playlist)</li>
<li>Sur Smartphone : Cliquez sur le logo de partage puis Copier le lien</li>
</ul>
</p>
</div>
<form action="/" method="POST">
<div class="form-group">
<input type="text" class="form-control" name="url1" id="url1" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url2" id="url2" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url3" id="url3" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url4" id="url4" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url5" id="url5" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<button type="submit" class="btn" id="download-button" onclick="startDownload()">Télécharger</button>
<button type="reset" class="btn" id="refresh-button" onclick="refreshPage()">Rafraîchir</button>
</form>
</div>
{% endblock body %}

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/css/style.css", filename= 'style.css'>
<script src="/static/js/script.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SpotDL Web</title>
</head>
<body>
{% block body %}{% endblock body %}
</body>
</html>

View File

@ -0,0 +1,7 @@
{% extends 'layout.html' %}
{% block body %}
{% endblock body %}

Binary file not shown.

102
app.py
View File

@ -1,15 +1,19 @@
from flask import Flask, request, redirect, url_for, send_file, render_template
from flask import Flask, request, send_file, render_template
from subprocess import run
import os
import secrets
app = Flask(__name__)
app.secret_key = secrets.token_hex(16)
@app.route('/')
def upload_form():
return render_template('upload.html')
@app.route('/', methods=['GET', 'POST'])
def index():
message = None
def download_file():
session_id = secrets.token_hex(16)
download_param_album = '{artist}/{album}/{artist} - {title}'
download_param_playlist = '{playlist}/{artists}/{album} - {title} {artist}'
download_param_track = '{artist}/{album}/{artist} - {title}'
if request.method == 'POST':
url1 = request.form['url1']
url2 = request.form['url2']
@ -21,75 +25,37 @@ def index():
if not url1 and not url2 and not url3 and not url4 and not url5:
return render_template('erreur.html')
result = process_file(url1, url2, url3, url4, url5)
return render_template('download_complete.html')
urls = [url1, url2, url3, url4, url5]
# Créer le dossier 'downloads' s'il n'existe pas
if not os.path.exists('downloads'):
os.makedirs('downloads')
def process_file(url1, url2, url3, url4, url5):
path = os.path.expanduser('~/musics')
download_param_album = '{artist}/{album}/{artist} - {title}'
download_param_playlist = '{playlist}/{artists}/{album} - {title} {artist}'
os.chdir('downloads')
os.system(f'rm -rf *')
# Télécharger chaque URL s'il n'est pas vide
if url1:
if "album" in url1:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url1} --output "{download_param_album}"')
elif "playlist" in url1:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url1} --output "{download_param_playlist}"')
for url in urls:
if url:
if "album" in url:
run(['python3', '-m', 'spotdl', url, '--output', download_param_album])
elif "playlist" in url:
run(['python3', '-m', 'spotdl', url, '--output', download_param_playlist])
elif "track" in url:
run(['python3', '-m', 'spotdl', url, '--output', download_param_track])
run(['zip', '-r', 'musics.zip', '.'])
os.chdir('../')
if url2:
if "album" in url2:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url2} --output "{download_param_album}"')
elif "playlist" in url2:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url2} --output "{download_param_playlist}"')
path = "downloads/musics.zip"
return send_file(path, as_attachment=True)
if url3:
if "album" in url3:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url3} --output "{download_param_album}"')
elif "playlist" in url3:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url3} --output "{download_param_playlist}"')
if url4:
if "album" in url4:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url4} --output "{download_param_album}"')
elif "playlist" in url4:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url4} --output "{download_param_playlist}"')
if url5:
if "album" in url5:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url5} --output "{download_param_album}"')
elif "playlist" in url5:
os.chdir(f"{path}")
os.system(f'python3 -m spotdl {url5} --output "{download_param_playlist}"')
return render_template('index.html')
# def process_file(url):
# path = os.path.expanduser('~/musics')
# download_param_album = '{artist}/{album}/{artist} - {title}'
# download_param_playlist = '{playlist}/{artists}/{album} - {title} {artist}'
@app.errorhandler(404)
def page_not_found():
return render_template('404.html'), 404
# if "album" in url:
# #os.makedirs(f"{path}")
# os.chdir(f"{path}")
# print ("album found")
# os.system(f'python3 -m spotdl {url} --output "{download_param_album}"')
# elif "playlist" in url:
# os.chdir(f"{path}")
# print("playlist found")
# os.system(f'python3 -m spotdl {url} --output "{download_param_playlist}"')
# @app.route('/download/<path:filename>')
# def download_file(filename):
# return send_file(filename, attachment_filename=filename, as_attachment=True)
if __name__ == '__main__':
app.run(debug=True, port=3000)

View File

@ -1,40 +1,193 @@
body {
background-color: black;
}
h1 {
/* border: 2px #eee solid; */
color: rgb(24,216,96);
background-color: black;
text-align: center;
padding: 10px;
}
h2 {
text-align: center;
margin: auto;
padding: 10px;
color: white;
}
.url {
display: flex;
justify-content: center;
align-items: center;
/* min-height:100%; */
background-color: black;
color: white
}
input[type="submit"] {
display: block;
margin: auto;
}
button {
display: block;
margin: 10px auto;
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background-color: #131313;
color: #ffffff;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
box-sizing: border-box;
}
.bordered {
border: 1px solid rgb(24,216,96);
border-radius: 5px;
padding: 20px;
margin-bottom: 20px;
}
li {
font-weight: bold;
}
a {
text-decoration-color: rgb(24,216,96);
color: rgb(24,216,96);
}
.form-group {
display: flex;
flex-direction: column;
margin-bottom: 20px;
}
.form-group label {
font-weight: bold;
margin-bottom: 5px;
}
.form-control {
background-color: #232323;
border: none;
border-radius: 5px;
padding: 10px;
color: #ffffff;
}
/* .form-control:focus {
outline: none;
box-shadow: 0 0 0 2px rgb(24,216,96);
} */
.form-control:valid:not(:placeholder-shown) {
outline: none;
border: 2px solid rgb(24,216,96);
}
.form-control:invalid {
outline: none;
border: 2px solid red;
}
.btn {
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn2 {
margin-top: 10px;
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn:hover {
background-color: rgb(24,216,96);
color: whitesmoke
}
h1 {
color: rgb(24,216,96);
}
@media (max-width: 600px) {
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background-color: #131313;
color: #ffffff;
}
.container {
max-width: 100%;
margin: 0;
padding: 10px;
box-sizing: border-box;
}
.bordered {
border: 1px solid rgb(24,216,96);
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
}
li {
font-weight: bold;
}
a {
text-decoration-color: rgb(24,216,96);
color: rgb(24,216,96);
}
.form-group {
display: flex;
flex-direction: column;
margin-bottom: 10px;
}
.form-group label {
font-weight: bold;
margin-bottom: 5px;
}
.form-control {
background-color: #232323;
border: none;
border-radius: 5px;
padding: 10px;
color: #ffffff;
}
/* .form-control:focus {
outline: none;
box-shadow: 0 0 0 2px rgb(24,216,96);
} */
.form-control:valid:not(:placeholder-shown) {
outline: none;
border: 2px solid rgb(24,216,96);
}
.form-control:invalid {
outline: none;
border: 2px solid red;
}
.btn {
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn2 {
margin-top: 10px;
background-color: rgb(24,216,96);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #131313;
font-weight: bold;
cursor: pointer;
text-decoration:none
}
.btn:hover {
background-color: rgb(24,216,96);
color: whitesmoke
}
h1 {
color: rgb(24,216,96);
}
}

6
static/js/script.js Normal file
View File

@ -0,0 +1,6 @@
function startDownload() {
document.getElementById('download-button').innerHTML = 'Téléchargement en cours...';
}
function refreshPage() {
window.location.reload();
}

14
templates/404.html Normal file
View File

@ -0,0 +1,14 @@
{% extends 'layout.html' %}
{% block body %}
<body>
<div class="container">
<h1>Error 404</h1>
<h2>Il semble que vous soyez perdu. Revenez à la page d'accueil</h2>
<button class="btn" onclick="window.location.href = '/';">Accueil</button>
</div>
</body>
{% endblock body %}

View File

@ -1,10 +0,0 @@
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
<title>SpotDL Web</title>
</head>
<body>
<h1> SpotDL Web </h1>
<h2> Téléchargement Terminé </h2>
<button onclick="window.location.href = '/';">Télécharger à nouveau</button>
</body>

View File

@ -1,13 +1,18 @@
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
<title>SpotDL Web</title>
</head>
{% extends 'layout.html' %}
<h1> SpotDL Web </h1>
<h2> Veuillez entrer au moins une URL ! </h2>
<button onclick="window.location.href = '/';">Télécharger à nouveau</button>
{% block body %}
{% if message %}
<p>{{ message }}</p>
{% endif %}
<body>
<div class="container">
<h1 class="title"> SpotDL Web </h1>
<h2> Veuillez entrer au moins une URL ! </h2>
<button class="btn" onclick="window.location.href = '/';">Accueil</button>
{% if message %}
<p>{{ message }}</p>
{% endif %}
</div>
</body>
{% endblock body %}

39
templates/index.html Normal file
View File

@ -0,0 +1,39 @@
{% extends 'layout.html' %}
{% block body %}
<div class="container">
<h1 class="title">SpotDL Web</h1>
<div class="bordered">
<p>
<h3>Procédure</h3>
<ul>
<li>Se rendre sur Spotify en cliquant <a rel="stylesheet" href="https://open.spotify.com/" target="_blank">ici</a></li>
<li>Chercher un Album ou une Playlist</li>
<li>Sur Ordinateur : A droite du coeur, cliquez sur ... puis Partager et Copier le lien vers (Album ou Playlist)</li>
<li>Sur Smartphone : Cliquez sur le logo de partage puis Copier le lien</li>
</ul>
</p>
</div>
<form action="/" method="POST">
<div class="form-group">
<input type="text" class="form-control" name="url1" id="url1" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url2" id="url2" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url3" id="url3" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url4" id="url4" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<div class="form-group">
<input type="text" class="form-control" name="url5" id="url5" pattern="^https://open\.spotify\.com/(?:album|playlist|track)/[\w-]+(?:\?si=[\w-]+)?$" placeholder="Entrez l'URL d'un Album ou d'une Playlist">
</div>
<button type="submit" class="btn" id="download-button" onclick="startDownload()">Télécharger</button>
<button type="reset" class="btn" id="refresh-button" onclick="refreshPage()">Rafraîchir</button>
</form>
</div>
{% endblock body %}

16
templates/layout.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/css/style.css", filename= 'style.css'>
<script src="/static/js/script.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SpotDL Web</title>
</head>
<body>
{% block body %}{% endblock body %}
</body>
</html>

7
templates/modele.html Normal file
View File

@ -0,0 +1,7 @@
{% extends 'layout.html' %}
{% block body %}
{% endblock body %}

View File

@ -1,45 +0,0 @@
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
<title>SpotDL Web</title>
</head>
<h1>SpotDL Web</h1>
<div class="url">
<form method="POST">
<!-- <label for="url">URL:</label>
<input type="text" name="url" id="url"> -->
<div style="margin-top: 10px;">
<label for="url1">URL 1:</label>
<input type="text" name="url1" id="url1">
</div>
<div style="margin-top: 10px;">
<label for="url2">URL 2:</label>
<input type="text" name="url2" id="url2">
</div>
<div style="margin-top: 10px;">
<label for="url3">URL 3:</label>
<input type="text" name="url3" id="url3">
</div>
<div style="margin-top: 10px;">
<label for="url4">URL 4:</label>
<input type="text" name="url4" id="url4">
</div>
<div style="margin-top: 10px;">
<label for="url5">URL 5:</label>
<input type="text" name="url5" id="url5">
</div>
<div style="margin-top: 10px;">
<input type="submit" value="Téléchargement">
</div>
</form>
</div>