diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
new file mode 100644
index 0000000..2ec345c
--- /dev/null
+++ b/.github/workflows/main.yaml
@@ -0,0 +1,26 @@
+name: "Repo publisher"
+
+on:
+ push:
+ branches:
+ - dev
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Clone Repository
+ run: git clone --recursive --branch dev https://github.com/SpotifyXP/SpotifyXP-Repository
+ - name: Run generate_repo.py script
+ working-directory: ./SpotifyXP-Repository
+ run: python3 generate_repo.py
+ - name: Make public directory
+ working-directory: ./SpotifyXP-Repository
+ run: mkdir public
+ - name: Copy files to public directory
+ working-directory: ./SpotifyXP-Repository
+ run: cp -R repo public/
+ - name: Upload to GitHub Pages
+ uses: peaceiris/actions-gh-pages@v4
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./SpotifyXP-Repository/public
\ No newline at end of file
diff --git a/.github/workflows/pullrequest.yaml b/.github/workflows/pullrequest.yaml
new file mode 100644
index 0000000..6095440
--- /dev/null
+++ b/.github/workflows/pullrequest.yaml
@@ -0,0 +1,13 @@
+name: "Pull request tester"
+
+on: pull_request
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Pull Request Branch
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.ref }}
+ - name: Run generate_repo.py script
+ run: python3 generate_repo.py
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a5942fc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+repo/
+venv/
+extensions/SpotifyXP.jar
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..b989ab9
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "extensions/MSNStatusSupport"]
+ path = extensions/MSNStatusSupport
+ url = https://github.com/SpotifyXP/MSNStatusSupport
+[submodule "extensions/SpotifyXP-Last.FM"]
+ path = extensions/SpotifyXP-Last.FM
+ url = https://github.com/SpotifyXP/SpotifyXP-Last.FM
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100755
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/SpotifyXP-Repository.iml b/.idea/SpotifyXP-Repository.iml
deleted file mode 100755
index 11e7ac6..0000000
--- a/.idea/SpotifyXP-Repository.iml
+++ /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 100755
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/misc.xml b/.idea/misc.xml
deleted file mode 100755
index 2c72cff..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 100755
index e43d923..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100755
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/REPO_FORMAT.md b/REPO_FORMAT.md
new file mode 100644
index 0000000..608f53b
--- /dev/null
+++ b/REPO_FORMAT.md
@@ -0,0 +1,17 @@
+# The format of the repository
+
+
+Repo url format: https://example.com/repo
+
+For the formats of specific files look at the schemas
+File Tree:
+
+```
+repo
+|
+|___repo.json (repo.schema.json)
+|___extension1-Werwolf2303.json (extension.schema.json)
+|___storage
+ |
+ |___extension1-Werwolf2303.jar
+```
\ No newline at end of file
diff --git a/debug.py b/debug.py
index 4c03caf..91bec02 100755
--- a/debug.py
+++ b/debug.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-
import http.server as SimpleHTTPServer
import socketserver as SocketServer
import logging
diff --git a/dependency.schema.json b/dependency.schema.json
new file mode 100644
index 0000000..3a76d60
--- /dev/null
+++ b/dependency.schema.json
@@ -0,0 +1,25 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Extension dependency descriptor",
+ "description": "This document describes a dependency of an extension",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the extension",
+ "type": "string"
+ },
+ "author": {
+ "description": "The author of the extension",
+ "type": "string"
+ },
+ "location": {
+ "description": "The location relative to the root folder where the jar file is stored",
+ "type": "string"
+ },
+ "dependencies": {
+ "description": "List of dependencies of the dependency",
+ "type": "array",
+ "$ref": "dependency.schema.json"
+ }
+ }
+}
\ No newline at end of file
diff --git a/extension.schema.json b/extension.schema.json
new file mode 100644
index 0000000..e63de9f
--- /dev/null
+++ b/extension.schema.json
@@ -0,0 +1,37 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Extension descriptor",
+ "description": "This document describes an extension",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the extension",
+ "type": "string"
+ },
+ "author": {
+ "description": "The author of the extension",
+ "type": "string"
+ },
+ "version": {
+ "description": "The version string of the extension e.g. 0.0.1",
+ "type": "string"
+ },
+ "description": {
+ "description": "The description for the extension",
+ "type": "string"
+ },
+ "location": {
+ "description": "The location relative to the root folder where the jar file is stored",
+ "type": "string"
+ },
+ "identifier": {
+ "description": "The UUID 4 of the extension",
+ "type": "string"
+ },
+ "dependencies": {
+ "description": "List of dependencies of the extension",
+ "type": "array",
+ "$ref": "dependency.schema.json"
+ }
+ }
+}
\ No newline at end of file
diff --git a/extensions/MSNStatusSupport b/extensions/MSNStatusSupport
new file mode 160000
index 0000000..8295588
--- /dev/null
+++ b/extensions/MSNStatusSupport
@@ -0,0 +1 @@
+Subproject commit 8295588a142a55a8fbb23e9ca5af71cab05a7777
diff --git a/extensions/SpotifyXP-Last.FM b/extensions/SpotifyXP-Last.FM
new file mode 160000
index 0000000..ab82af4
--- /dev/null
+++ b/extensions/SpotifyXP-Last.FM
@@ -0,0 +1 @@
+Subproject commit ab82af46359fc56f82bed9847c6002aacac72ef9
diff --git a/generate_repo.py b/generate_repo.py
new file mode 100644
index 0000000..86e4792
--- /dev/null
+++ b/generate_repo.py
@@ -0,0 +1,107 @@
+# This python script generates all the JSON files needed for the repository
+import json
+import os
+import shutil
+import subprocess
+import sys
+import urllib.request
+
+
+ROOT_LOCATION = "repo/repo.json"
+JARS_LOCATION = "repo/storage"
+EXTENSIONS_LOCATION = "extensions"
+BUILD_SCRIPT = "build.sh" # e.g. extensions/MSNStatusSupport/build.sh
+SPXP_JAR_URL = "https://github.com/SpotifyXP/SpotifyXP/releases/latest/download/SpotifyXP.jar"
+REPO_PATH = "repo"
+DEPENDENCIES = []
+
+def compile_jar(dir, PLUGIN_JSON):
+ print("Building " + dir)
+ os.chmod(os.path.join(EXTENSIONS_LOCATION + "/" + dir + "/" + BUILD_SCRIPT), 0o755)
+ proc = subprocess.call("./" + BUILD_SCRIPT, cwd=EXTENSIONS_LOCATION + "/" + dir, shell=True)
+ if proc != 0:
+ print("Failed to build " + dir)
+ return
+ if os.path.exists(EXTENSIONS_LOCATION + "/" + dir + "/build.gradle"):
+ JAR_PATH = EXTENSIONS_LOCATION + "/" + dir + "/build/libs/" + dir + ".jar"
+ if not os.path.exists(JAR_PATH):
+ print("Couldn't find jar file in '" + JAR_PATH + "'")
+ return
+ shutil.copyfile(JAR_PATH, JARS_LOCATION + "/" + dir + "-" + PLUGIN_JSON["author"] + ".jar")
+ elif os.path.exists(EXTENSIONS_LOCATION + "/" + dir + "/pom.xml"):
+ JAR_PATH = EXTENSIONS_LOCATION + "/" + dir + "/target/" + dir + ".jar"
+ if not os.path.exists(JAR_PATH):
+ print("Couldn't find jar file in '" + JAR_PATH + "'")
+ return
+ shutil.copyfile(JAR_PATH, JARS_LOCATION + "/" + dir + "-" + PLUGIN_JSON["author"] + ".jar")
+ else:
+ print("Extension named '" + dir + "' doesn't contain a recognized build system")
+
+def extract_extension_descriptor(dir):
+ PLUGIN_JSON_PATH = EXTENSIONS_LOCATION + "/" + dir + "/src/main/resources/plugin.json"
+ return json.loads(open(PLUGIN_JSON_PATH).read())
+
+def create_plugin_descriptor(PLUGIN_JSON):
+ NEW_PLUGIN_JSON = PLUGIN_JSON
+ del NEW_PLUGIN_JSON["main"]
+ NEW_PLUGIN_JSON["location"] = JARS_LOCATION + "/" + PLUGIN_JSON["name"] + "-" + PLUGIN_JSON["author"] + ".jar"
+ for dependency in NEW_PLUGIN_JSON["dependencies"]:
+ dependency["location"] = REPO_PATH + "/" + dependency["name"] + "-" + dependency["author"] + ".json"
+ DEPENDENCIES.append(dependency)
+ file = open(REPO_PATH + "/" + PLUGIN_JSON["name"] + "-" + PLUGIN_JSON["author"] + ".json", "w")
+ file.write(json.dumps(NEW_PLUGIN_JSON))
+ file.close()
+
+# 1. Make required directories
+if os.path.exists(REPO_PATH):
+ shutil.rmtree(REPO_PATH)
+ os.makedirs(REPO_PATH)
+else:
+ os.makedirs(REPO_PATH)
+
+if not os.path.exists(JARS_LOCATION):
+ os.makedirs(JARS_LOCATION)
+
+# 2. Download the newest SpotifyXP.jar
+if not os.path.exists(EXTENSIONS_LOCATION + "/SpotifyXP.jar"):
+ print("Downloading SpotifyXP")
+ urllib.request.urlretrieve(SPXP_JAR_URL, EXTENSIONS_LOCATION + "/SpotifyXP.jar")
+
+# 3. Create repo.json
+REPO_JSON = {
+ "name": "SpotifyXP-Repository",
+ "extensions": [
+ ]
+}
+
+# 4. Build every extension via the build script defined in BUILD_SCRIPT
+print("Building extensions")
+for dir in os.listdir(EXTENSIONS_LOCATION):
+ if dir.endswith(".jar"): continue
+
+ # 4.1. Extract extension descriptor "plugin.json"
+ PLUGIN_JSON = extract_extension_descriptor(dir)
+
+ # 4.2. Compile and copy extension
+ compile_jar(dir, PLUGIN_JSON)
+
+ # 4.3 Create extension descriptor for the repository e.g. Test-Werwolf2303.json
+ create_plugin_descriptor(PLUGIN_JSON)
+
+ # 4.4 Add extension to the list
+ REPO_JSON["extensions"].append({
+ "location": "/" + PLUGIN_JSON["name"] + "-" + PLUGIN_JSON["author"] + ".json",
+ })
+
+# 5. Store repo.json
+file = open(ROOT_LOCATION, "w")
+file.write(json.dumps(REPO_JSON))
+file.close()
+
+# 6. Check for non existent dependencies
+for dependency in DEPENDENCIES:
+ if not os.path.exists(dependency["location"]):
+ print("Couldn't find dependency '" + dependency["name"] + " from " + dependency["author"] + "'")
+
+
+
diff --git a/jardependency.schema.json b/jardependency.schema.json
new file mode 100644
index 0000000..8be6e20
--- /dev/null
+++ b/jardependency.schema.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Jar extension dependency descriptor",
+ "description": "This document describes a dependency of an extension packaged in a jar",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the extension",
+ "type": "string"
+ },
+ "author": {
+ "description": "The author of the extension",
+ "type": "string"
+ },
+ "dependencies": {
+ "description": "List of dependencies of the dependency",
+ "type": "array",
+ "$ref": "jardependency.schema.json"
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugin.schema.json b/plugin.schema.json
new file mode 100644
index 0000000..5454ad2
--- /dev/null
+++ b/plugin.schema.json
@@ -0,0 +1,37 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Jar extension descriptor",
+ "description": "This document describes an extension descriptor in a jar file",
+ "type": "object",
+ "properties": {
+ "main": {
+ "description": "The entry point of the extension",
+ "type": "string"
+ },
+ "name": {
+ "description": "The name of the extension",
+ "type": "string"
+ },
+ "author": {
+ "description": "The author of the extension",
+ "type": "string"
+ },
+ "version": {
+ "description": "The version string of the extension e.g. 0.0.1",
+ "type": "string"
+ },
+ "description": {
+ "description": "The description for the extension",
+ "type": "string"
+ },
+ "identifier": {
+ "description": "The UUID 4 of the extension",
+ "type": "string"
+ },
+ "dependencies": {
+ "description": "List of dependencies of the dependency",
+ "type": "array",
+ "$ref": "jardependency.schema.json"
+ }
+ }
+}
\ No newline at end of file
diff --git a/repo.schema.json b/repo.schema.json
new file mode 100644
index 0000000..0f730ed
--- /dev/null
+++ b/repo.schema.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "name": "The descriptor of a repository",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the repository",
+ "type": "string"
+ },
+ "extensions": {
+ "description": "List of extensions in a repository",
+ "type": "array",
+ "properties": {
+ "location": {
+ "description": "The location of the extension json file relative to the repo folder"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/repo/Hello-Werwolf2303.json b/repo/Hello-Werwolf2303.json
deleted file mode 100755
index 72ae705..0000000
--- a/repo/Hello-Werwolf2303.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name" : "Hello",
- "author" : "Werwolf2303",
- "version" : "1.0",
- "description" : "Test extension for testing extension functionality",
- "location" : "/storage/Hello-Werwolf2303.jar",
- "identifier" : "000001",
- "minversion" : "1.9",
- "dependencies": [
- ]
-}
diff --git a/repo/LastFM-Werwolf2303.json b/repo/LastFM-Werwolf2303.json
deleted file mode 100755
index 76ae91f..0000000
--- a/repo/LastFM-Werwolf2303.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name" : "LastFM",
- "author" : "Werwolf2303",
- "version" : "1.0",
- "description" : "Last.FM functionality",
- "location" : "/storage/LastFM-Werwolf2303.jar",
- "identifier" : "000002",
- "minversion" : "2.0.3",
- "dependencies": [
- ]
-}
diff --git a/repo/MSNStatusSupport-Werwolf2303.json b/repo/MSNStatusSupport-Werwolf2303.json
deleted file mode 100644
index 77940a4..0000000
--- a/repo/MSNStatusSupport-Werwolf2303.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name" : "MSNStatus",
- "author" : "Werwolf2303",
- "version" : "0.0.1",
- "description" : "MSNStatus support",
- "location" : "/storage/MSNStatusSupport-Werwolf2303.jar",
- "identifier" : "000003",
- "minversion" : "2.0.3",
- "dependencies": [
- ]
-}
diff --git a/repo/repo.json b/repo/repo.json
deleted file mode 100755
index f1b5c06..0000000
--- a/repo/repo.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "SpotifyXP-Repository",
- "extensions": [
- {
- "location": "/Hello-Werwolf2303.json"
- },
- {
- "location": "/LastFM-Werwolf2303.json"
- },
- {
- "location": "/MSNStatusSupport-Werwolf2303.json"
- }
- ]
-}
\ No newline at end of file
diff --git a/repo/storage/Hello-Werwolf2303.jar b/repo/storage/Hello-Werwolf2303.jar
deleted file mode 100755
index 68cb436..0000000
Binary files a/repo/storage/Hello-Werwolf2303.jar and /dev/null differ
diff --git a/repo/storage/LastFM-Werwolf2303.jar b/repo/storage/LastFM-Werwolf2303.jar
deleted file mode 100644
index 8f3caec..0000000
Binary files a/repo/storage/LastFM-Werwolf2303.jar and /dev/null differ
diff --git a/repo/storage/MSNStatusSupport-Werwolf2303.jar b/repo/storage/MSNStatusSupport-Werwolf2303.jar
deleted file mode 100644
index da4c5ba..0000000
Binary files a/repo/storage/MSNStatusSupport-Werwolf2303.jar and /dev/null differ