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