diff --git a/.dockerignore b/.dockerignore
index 2eea525..24800a8 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1 +1,2 @@
-.env
\ No newline at end of file
+.env
+n8n_workflow.json
\ No newline at end of file
diff --git a/.env.example b/.env.example
index ecf80a4..f4920ae 100644
--- a/.env.example
+++ b/.env.example
@@ -1,4 +1,5 @@
client_id=
client_secret=
-n8n_webhook=
-enviroment=dev
\ No newline at end of file
+n8n_webhook_add_tracks=
+n8n_webhook_create_playlist=
+environment=production
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 09b72b2..a19e5cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,8 @@
.idea/**/gradle.xml
.idea/**/libraries
+.idea/
+
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
deleted file mode 100644
index 4dd9ac1..0000000
--- a/.idea/dataSources.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
- sqlite.xerial
- true
- org.sqlite.JDBC
- jdbc:sqlite:database.db
- $ProjectFileDir$
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index dedcd2a..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 105ce2d..0000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
deleted file mode 100644
index cc4655d..0000000
--- a/.idea/jsLibraryMappings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index a0209ef..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 4e31d73..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/playlistCreator.iml b/.idea/playlistCreator.iml
deleted file mode 100644
index 7317fc5..0000000
--- a/.idea/playlistCreator.iml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
deleted file mode 100644
index 9011cb5..0000000
--- a/.idea/sqldialects.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 0f7efb4..afaf0d9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,7 @@
FROM python:3.11-alpine
-LABEL authors="louisgallet"
+LABEL authors="Louis Gallet"
+LABEL description="Make This Playlist is a web application that allows anyone to add music to a Spotify playlist without needing a Spotify account. The application is accessible at the following address: [Make This Playlist](https://makethisplaylist.louisgallet.fr)."
+
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
diff --git a/README.md b/README.md
index cd71bd8..d4abc29 100644
--- a/README.md
+++ b/README.md
@@ -7,16 +7,24 @@ Make This Playlist is a web application that allows anyone to add music to a Spo
- Search for music on Spotify
- Add music to a playlist
+## Requirements
+- n8n account or instance
+- n8n workflow (import [n8n workflow file](https://gitea.louisgallet.fr/lgallet/makethisplaylist/src/branch/main/n8n_workflow.json) into your account and set your Spotify credentials)
+- Spotify Developer Account
+
## Installation
### Docker
-You can install the application via Docker. To do this, execute the following command:
+You can install the application via Docker. To do this, execute the following command:
+For the webhook URLs, make sure to remove the parameters, as they will be added directly by the application.
```bash
docker run -d \
-p 80:3000 \
-e client_id=SPOTIFY_CLIENT_ID \
-e client_secret=SPOTIFY_CLIENT_SECRET \
- -e n8n_webhook=N8N_WEBHOOK_URL \
+ -e n8n_webhook_create_playlist=N8N_WEBHOOK_URL \
+ -e n8n_webhook_add_tracks=N8N_WEBHOOK_URL \
+ -e environment=production \
gitea.louisgallet.fr/lgallet/makethisplaylist:latest
```
@@ -26,5 +34,6 @@ To install the application manually, clone the repository and install the depend
git clone https://gitea.louisgallet.fr/lgallet/makethisplaylist.git
cd makethisplaylist
pip install -r requirements.txt
+cp .env.example .env
python main.py
```
\ No newline at end of file
diff --git a/main.py b/main.py
index 171ed5c..9cdc9ac 100644
--- a/main.py
+++ b/main.py
@@ -41,7 +41,6 @@ def create_playlist():
data = requests.get((os.getenv("n8n_webhook_create_playlist") + "/" + str(roomid) + "/" + playlistName))
playlistID = data.json()['playlistID']
spotifyURL = data.json()['spotifyURL']
- print(playlistID)
cursor.execute("INSERT INTO rooms (roomid, spotify_id, playlist_name, spotify_URL) VALUES (?, ?, ?, ?)",
(roomid, playlistID, playlistName, spotifyURL))
database.commit()
@@ -54,7 +53,7 @@ def create_playlist():
return render_template("create.html", response='Request failed', comment=e, type="error")
@app.route('/search/', methods=['GET', 'POST'])
-def main_app(roomid):
+def search(roomid):
if len(roomid) != 8 or not cursor.execute("SELECT * FROM rooms WHERE roomid = ?", (roomid,)).fetchone():
return main()
playlistName = cursor.execute("SELECT playlist_name FROM rooms WHERE roomid = ?", (roomid,)).fetchone()[0]
@@ -69,16 +68,12 @@ def main_app(roomid):
# otherwise handle the GET request
return render_template("search.html", roomid=roomid, playlistName=playlistName, spotifyURL=spotifyURL)
-@app.route('/add///', methods=['GET'])
+@app.route('/add/room//playlist//track/', methods=['GET'])
def add_to_playlist(roomid, playlistID, trackid):
- print(roomid)
- print(playlistID)
- print(trackid)
if not os.getenv("n8n_webhook_add_tracks"):
return render_template("add.html", response="No n8n webhook provided", comment="Please provide a n8n webhook in the .env file", type="error", roomid=roomid)
try:
data = requests.get(os.getenv("n8n_webhook_add_tracks") + "/" + playlistID + "/" + trackid)
- print(data.json)
if data.json()['status'] == 'success':
return render_template("add.html", response="Track added to playlist successfully", comment="Enjoy the night \U0001f57a", type="success", roomid=roomid)
diff --git a/n8n_workflow.json b/n8n_workflow.json
new file mode 100644
index 0000000..99f8cac
--- /dev/null
+++ b/n8n_workflow.json
@@ -0,0 +1,207 @@
+{
+ "name": "PlaylistCreator Workflows",
+ "nodes": [
+ {
+ "parameters": {
+ "content": "## Workflow to add track to a playlist\n\nThis webhook is called with the following parameters: `playlistid` and `trackid`, which are sent by the Flask application. This webhook will attempt to add the desired track to the playlist. We assume that the playlist exists and that the current user has the right to add a track to it. As for the `trackid`, it is guaranteed to be valid since it is retrieved from the Spotify API.",
+ "height": 212,
+ "width": 495
+ },
+ "id": "1c6779f6-ed75-457e-b19c-dd24268eb527",
+ "name": "Sticky Note",
+ "type": "n8n-nodes-base.stickyNote",
+ "typeVersion": 1,
+ "position": [
+ 460,
+ 120
+ ]
+ },
+ {
+ "parameters": {
+ "resource": "playlist",
+ "id": "={{ $json.params.playlistid }}",
+ "trackID": "={{ $('Add Track Webhook').item.json.params.trackid }}",
+ "additionalFields": {}
+ },
+ "id": "6defaf1d-1c28-46d2-b31f-55b02cd8dda3",
+ "name": "Add track to the Spotify Playlist",
+ "type": "n8n-nodes-base.spotify",
+ "typeVersion": 1,
+ "position": [
+ 680,
+ 320
+ ],
+ "alwaysOutputData": true,
+ "credentials": {
+ "spotifyOAuth2Api": {
+ "id": "ry4GegWcWUTXupsE",
+ "name": "Spotify account"
+ }
+ }
+ },
+ {
+ "parameters": {
+ "resource": "playlist",
+ "operation": "create",
+ "name": "={{ $json.params.playlistName }} - {{ $json.params.roomID }}",
+ "additionalFields": {
+ "description": "=Playlist created with Make This Playlist - https://makethisplaylist.louisgallet.fr. Add some music by entering the roomID: {{ $json.params.roomID }}",
+ "public": true
+ }
+ },
+ "id": "319efc18-903e-42d2-bb72-ce50b8bef1ee",
+ "name": "Create a Spotify playlist",
+ "type": "n8n-nodes-base.spotify",
+ "typeVersion": 1,
+ "position": [
+ 660,
+ 740
+ ],
+ "credentials": {
+ "spotifyOAuth2Api": {
+ "id": "ry4GegWcWUTXupsE",
+ "name": "Spotify account"
+ }
+ }
+ },
+ {
+ "parameters": {
+ "content": "## Workflow to create a Spotify playlist\n\nThis webhook is called with the following parameters: `roomid` and `playlistid`, which are sent by the Flask application. This webhook will attempt to create the playlist on the associated Spotify account. We assume that the playlist name will be unique, as it uses the following format: `playlist name` - `roomid`.",
+ "height": 212,
+ "width": 495
+ },
+ "id": "972e1642-69f9-4458-b252-35b8446f4a15",
+ "name": "Sticky Note1",
+ "type": "n8n-nodes-base.stickyNote",
+ "typeVersion": 1,
+ "position": [
+ 480,
+ 560
+ ]
+ },
+ {
+ "parameters": {
+ "respondWith": "json",
+ "responseBody": "={\n \"playlistID\": \"{{ $json.id }}\", \n \"spotifyURL\": \"{{ $json.external_urls.spotify }}\"\n} ",
+ "options": {}
+ },
+ "id": "4223f8bf-0c4d-4184-8a50-bb3e9f1bb1fb",
+ "name": "Respond to Webhook",
+ "type": "n8n-nodes-base.respondToWebhook",
+ "typeVersion": 1.1,
+ "position": [
+ 840,
+ 740
+ ]
+ },
+ {
+ "parameters": {
+ "respondWith": "json",
+ "responseBody": "{\n \"status\": \"success\"\n}",
+ "options": {}
+ },
+ "id": "296a009b-cfb2-4594-bedc-7362b5f0e7eb",
+ "name": "Respond to Webhook1",
+ "type": "n8n-nodes-base.respondToWebhook",
+ "typeVersion": 1.1,
+ "position": [
+ 860,
+ 320
+ ]
+ },
+ {
+ "parameters": {
+ "path": "61f08b8c-5bca-4091-a934-da66d9ae09e7/:playlistid/:trackid",
+ "responseMode": "responseNode",
+ "options": {}
+ },
+ "id": "de91df67-33f9-4a6a-aaa4-17a272d54968",
+ "name": "Add Track Webhook",
+ "type": "n8n-nodes-base.webhook",
+ "typeVersion": 2,
+ "position": [
+ 500,
+ 320
+ ],
+ "webhookId": "61f08b8c-5bca-4091-a934-da66d9ae09e7",
+ "notesInFlow": true
+ },
+ {
+ "parameters": {
+ "path": "b1447737-cf34-43d5-8d42-8fb29fbfa275/:roomID/:playlistName",
+ "responseMode": "responseNode",
+ "options": {}
+ },
+ "id": "2b8e9c76-786e-4784-aa8c-0789727b375b",
+ "name": "Create Playlist Webhook",
+ "type": "n8n-nodes-base.webhook",
+ "typeVersion": 2,
+ "position": [
+ 480,
+ 740
+ ],
+ "webhookId": "b1447737-cf34-43d5-8d42-8fb29fbfa275"
+ }
+ ],
+ "pinData": {},
+ "connections": {
+ "Create a Spotify playlist": {
+ "main": [
+ [
+ {
+ "node": "Respond to Webhook",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Add track to the Spotify Playlist": {
+ "main": [
+ [
+ {
+ "node": "Respond to Webhook1",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Add Track Webhook": {
+ "main": [
+ [
+ {
+ "node": "Add track to the Spotify Playlist",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Create Playlist Webhook": {
+ "main": [
+ [
+ {
+ "node": "Create a Spotify playlist",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ }
+ },
+ "active": true,
+ "settings": {
+ "executionOrder": "v1",
+ "timezone": "Europe/Paris",
+ "saveManualExecutions": true,
+ "callerPolicy": "workflowsFromSameOwner"
+ },
+ "versionId": "21bcacb5-a3ce-4355-ba98-bb3c865e2905",
+ "meta": {
+ "templateCredsSetupCompleted": true,
+ "instanceId": "2ebecfc6e81edd91c6988c37863cd68c7d8e130f8ce8a9ab9fe59ab24a8d3949"
+ },
+ "id": "kWG5BTxflXVL7fFm",
+ "tags": []
+}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index fbd8268..863bcef 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,64 +1,6 @@
-appnope==0.1.4
-asttokens==2.4.1
-attrs==23.2.0
-backcall==0.2.0
-beautifulsoup4==4.12.3
-bleach==6.1.0
-blinker==1.8.2
-Bootstrap-Flask==2.4.0
-certifi==2024.6.2
-charset-normalizer==3.3.2
-click==8.1.7
-decorator==5.1.1
-defusedxml==0.7.1
-docopt==0.6.2
-executing==2.0.1
-fastjsonschema==2.20.0
-Flask==3.0.3
-idna==3.7
-ipython==8.12.3
-itsdangerous==2.2.0
-jedi==0.19.1
-Jinja2==3.1.4
-jsonschema==4.22.0
-jsonschema-specifications==2023.12.1
-jupyter_client==8.6.2
-jupyter_core==5.7.2
-jupyterlab_pygments==0.3.0
-MarkupSafe==2.1.5
-matplotlib-inline==0.1.7
-mistune==3.0.2
-nbclient==0.10.0
-nbconvert==7.16.4
-nbformat==5.10.4
-packaging==24.1
-pandocfilters==1.5.1
-parso==0.8.4
-pexpect==4.9.0
-pickleshare==0.7.5
-pipreqs==0.5.0
-platformdirs==4.2.2
-prompt_toolkit==3.0.47
-ptyprocess==0.7.0
-pure-eval==0.2.2
-Pygments==2.18.0
-python-dateutil==2.9.0.post0
-python-dotenv==1.0.1
-pyzmq==26.0.3
-redis==5.0.6
-referencing==0.35.1
-requests==2.32.3
-rpds-py==0.18.1
-six==1.16.0
-soupsieve==2.5
-spotipy==2.24.0
-stack-data==0.6.3
-tinycss2==1.3.0
-tornado==6.4.1
-traitlets==5.14.3
-urllib3==2.2.2
-wcwidth==0.2.13
-webencodings==0.5.1
-Werkzeug==3.0.3
-WTForms==3.1.2
-yarg==0.1.9
+spotipy~=2.24.0
+python-dotenv~=1.0.1
+Flask~=3.0.3
+qrcode~=7.4.2
+requests~=2.32.3
+bootstrap-flask~=2.4.0
\ No newline at end of file
diff --git a/templates/add.html b/templates/add.html
index 90abaf0..d37ab62 100644
--- a/templates/add.html
+++ b/templates/add.html
@@ -2,7 +2,7 @@
- Fête de la musique
+ Make this playlist
{{ bootstrap.load_css() }}
diff --git a/templates/create.html b/templates/create.html
index ab6e6a2..40998c3 100644
--- a/templates/create.html
+++ b/templates/create.html
@@ -2,7 +2,7 @@
- Fête de la musique
+ Make this playlist
{{ bootstrap.load_css() }}
diff --git a/templates/found.html b/templates/found.html
index 5bd224f..6f54ddb 100644
--- a/templates/found.html
+++ b/templates/found.html
@@ -41,7 +41,7 @@
{{ track[0] }}
{{ track[1] }} - {{ track[2] }}
-
diff --git a/templates/index.html b/templates/index.html
index 8f5ecf6..ff284b8 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -2,7 +2,7 @@
- Fête de la musique
+ Make this playlist
{{ bootstrap.load_css() }}
@@ -30,7 +30,7 @@
This will be the playlist name
-
+
diff --git a/templates/search.html b/templates/search.html
index c9f8a33..53336f5 100644
--- a/templates/search.html
+++ b/templates/search.html
@@ -2,7 +2,7 @@
- Fête de la musique
+ Make this playlist - Search
{{ bootstrap.load_css() }}