Skip to content
This repository was archived by the owner on Aug 8, 2025. It is now read-only.

Commit aa2d5c0

Browse files
committed
Own api ,cleanup and other improvements
1 parent e1e8ae8 commit aa2d5c0

File tree

7 files changed

+72
-52
lines changed

7 files changed

+72
-52
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ Clicking on the update button will check for version numbers first before initia
7777

7878
2. Auto apply spicetify after updates (or block them completely)
7979

80+
## Manager API
81+
82+
Due to rate limiting I decided to create my own relay for the official Github api.
83+
It just returns the latest release tag from the spicetify-cli repo.
84+
You can monitor the status here: [![Netlify Status](https://api.netlify.com/api/v1/badges/a32b6502-e8ec-45a7-b3e3-4af087f5d38e/deploy-status)](https://app.netlify.com/sites/spicetifymanagerapi/deploys)
85+
There might be more efficient ways to do this so feel free to suggest any improvements as an issue!
86+
8087

8188
## Acknowledgements
8289
- [Spicetify](https://spicetify.app/)

components/popups.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ def infoDialog(title, text):
1414
info_dialog.setText(text)
1515
info_dialog.exec()
1616

17+
def confirmDialog(title, text):
18+
confirm_dialog = QMessageBox()
19+
confirm_dialog.setWindowTitle(title)
20+
confirm_dialog.setText(text)
21+
confirm_dialog.setStandardButtons(QMessageBox.StandardButton.Ok)
22+
confirm_dialog.exec()
23+
24+
1725
def windowsNotification(title, message):
1826
notification.notify(
1927
title=title,

components/shellbridge.py

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import sys
32
import os
43
import subprocess
@@ -16,24 +15,24 @@ def run(self):
1615
if sys.platform == 'win32':
1716
self.progress_signal.emit("Downloading Spicetify...")
1817
subprocess.run('powershell.exe -Command "iwr -useb https://raw.githubusercontent.com/spicetify/spicetify-cli/master/install.ps1 | iex"',check=True)
19-
self.progress_signal.emit("Creating backup...")
18+
self.progress_signal.emit("Cleaning up...")
2019
subprocess.run('spicetify clear -n -q',check=True)
21-
subprocess.run('spicetify backup apply -n -q enable-devtools -n -q',check=True)
22-
self.progress_signal.emit("Installing Marketplace...")
23-
subprocess.run('powershell.exe -Command "iwr -useb https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/install.ps1 | iex"',check=True)
24-
else:
25-
self.progress_signal.emit("Downloading Spicetify...")
26-
subprocess.run('curl -fsSL https://raw.githubusercontent.com/spicetify/spicetify-cli/master/install.sh | sh',check=True)
2720
self.progress_signal.emit("Creating backup...")
28-
subprocess.run('spicetify clear',check=True)
29-
subprocess.run('spicetify backup apply enable-devtools',check=True)
21+
subprocess.run('spicetify backup -n -q',check=True)
22+
self.progress_signal.emit("Enabling devtools...")
23+
subprocess.run('spicetify enable-devtools -n -q',check=True)
24+
self.progress_signal.emit("Applying modification...")
25+
subprocess.run('spicetify apply -n -q',check=True)
3026
self.progress_signal.emit("Installing Marketplace...")
31-
subprocess.run('curl -fsSL https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/install.sh | sh',check=True)
27+
subprocess.run('powershell.exe -Command "iwr -useb https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/install.ps1 | iex"',check=True)
3228
except Exception as e:
3329
print("Error detected!")
3430
print(e)
3531
self.progress_signal.emit("fail")
32+
finally:
33+
self.progress_signal.emit("done")
3634
self.finished_signal.emit()
35+
3736
# Update spicetify task
3837
class UpdateSpicetify(QThread):
3938
finished_signal = pyqtSignal()
@@ -49,6 +48,7 @@ def run(self):
4948
print("Apply started")
5049
subprocess.check_output('spicetify apply -n -q')
5150
self.finished_signal.emit()
51+
5252
# Unisnatll spicetify task
5353
class UninstallSpicetify(QThread):
5454
finished_signal = pyqtSignal()
@@ -85,18 +85,6 @@ def run(self):
8585
except:
8686
print("Error while running custom command!")
8787

88-
89-
#Checks github for latest spicetify version
90-
def getLatestRelease():
91-
url = f"https://api.github.com/repos/spicetify/spicetify-cli/releases/latest"
92-
response = requests.get(url)
93-
94-
if response.status_code == 200:
95-
latest_release = response.json()
96-
tag_name = latest_release["tag_name"]
97-
return tag_name
98-
else:
99-
return None
10088

10189
#Checks if spicetify is installed by checking appdata folder
10290
def checkInstalled():
@@ -119,8 +107,8 @@ def checkSpotifyRunning():
119107
if 'Spotify.exe' in process.info['name']:
120108
return True
121109
return False
110+
122111
#Try blocking spotify updates by changing permissions (Windows only)
123-
#Warning this function is unstable!
124112
def blockSpotifyUpdate(active):
125113
if active:
126114
try:
@@ -145,7 +133,7 @@ def blockSpotifyUpdate(active):
145133
print(f'Error: {e.returncode}. patcher failed.')
146134
return e.returncode
147135

148-
# Checks if spotify updates are blocked (unfinished)
136+
# Checks if spotify updates are blocked !WIP!
149137
def checkSpotifyBlockedUpdate():
150138

151139
directory_path = r'C:\path\to\directory'

components/tools.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
import configparser
2+
import requests
23

4+
#Reads config files
35
def readConfig(file_path,section,key):
46
config = configparser.ConfigParser()
57
config.read(file_path)
6-
return config[section][key]
8+
return config[section][key]
9+
10+
#Checks for the latest spicetify version
11+
def getLatestRelease():
12+
try:
13+
url = f"https://spicetifymanagerapi.netlify.app/.netlify/functions/api/latest/spicetifycli"
14+
response = requests.get(url)
15+
16+
if response.status_code == 200:
17+
latest_release = response.json()
18+
tag_name = latest_release["tag_name"]
19+
return tag_name
20+
else:
21+
return '0.0.0'
22+
except:
23+
return '0.0.0'

manager_window.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
import sys
66
import subprocess
77
from PyQt6.QtWidgets import QMainWindow
8-
from PyQt6.QtCore import Qt
8+
from PyQt6.QtCore import Qt, QUrl
99
from PyQt6.uic import loadUi
1010
from PyQt6.QtGui import QDesktopServices
1111
from components.popups import errorDialog, infoDialog, windowsNotification
12-
from components.shellbridge import InstallSpicetify, UpdateSpicetify, ApplySpicetify, UninstallSpicetify, CustomCommand, getLatestRelease,checkApplied,blockSpotifyUpdate
13-
12+
from components.shellbridge import InstallSpicetify, UpdateSpicetify, ApplySpicetify, UninstallSpicetify, CustomCommand,checkApplied,blockSpotifyUpdate
13+
from components.tools import getLatestRelease
1414
from components.afterinstall_popup import Popup
1515

1616

@@ -39,38 +39,28 @@ def __init__(self):
3939

4040
self.bt_master.clicked.connect(self.masterButton)
4141
self.bt_uninstall.clicked.connect(self.startRemoval)
42+
self.bt_refresh.clicked.connect(self.SystemSoftStatusCheck)
4243
self.bt_cmd.clicked.connect(self.Custom)
4344
self.check_noupdate.stateChanged.connect(self.DisableUpdate)
4445

4546

4647
# Execute once window is loaded before listeners are enabled
4748
def InitWindow(self):
4849
self.SystemSoftStatusCheck()
50+
print('Made by Protonos')
4951

50-
#Update user about progress while installing spicetify
51-
def progressmaster(self, action):
52-
if (action == "fail"):
53-
self.l_status.setStyleSheet("color: red")
54-
self.l_status.setText("Installation has failed")
55-
errorDialog("The installation of Spicetify has failed due to an unrecoverable error! Check logs or ask for help.")
56-
else:
57-
self.l_status.setStyleSheet("color: Orange")
58-
self.l_status.setText(action)
59-
self.l_versioninfo.setText("This process may take a few minutes!")
60-
61-
62-
# Launch installer task !WIP
52+
# Master trigger for all requests
6353
def masterButton(self):
6454
if self.managermode == 0:
6555
os.startfile(os.path.join( os.path.expanduser('~'), 'AppData','Roaming/Spotify/Spotify.exe'))
6656
self.SystemSoftStatusCheck()
6757
if self.managermode == 1:
68-
QDesktopServices.openUrl('https://download.scdn.co/SpotifySetup.exe')
58+
QDesktopServices.openUrl(QUrl('https://download.scdn.co/SpotifySetup.exe'))
6959
self.SystemSoftStatusCheck()
7060
elif self.managermode == 2:
7161
self.setCursor(Qt.CursorShape.WaitCursor)
7262
self.bt_master.setEnabled(False)
73-
self.bt_update.setEnabled(False)
63+
self.bt_refresh.setEnabled(False)
7464
self.bt_uninstall.setEnabled(False)
7565
self.l_status.setText("Installling Spicetify...")
7666
self.l_versioninfo.setText('⏳Please wait⏳')
@@ -81,7 +71,7 @@ def masterButton(self):
8171
elif self.managermode == 3:
8272
self.setCursor(Qt.CursorShape.WaitCursor)
8373
self.bt_master.setEnabled(False)
84-
self.bt_update.setEnabled(False)
74+
self.bt_refresh.setEnabled(False)
8575
self.bt_uninstall.setEnabled(False)
8676
self.l_status.setText("Running apply")
8777
self.l_versioninfo.setText('⏳Please wait⏳')
@@ -97,22 +87,32 @@ def masterButton(self):
9787
elif self.managermode == 5:
9888
self.setCursor(Qt.CursorShape.WaitCursor)
9989
self.bt_master.setEnabled(False)
100-
self.bt_update.setEnabled(False)
90+
self.bt_refresh.setEnabled(False)
10191
self.bt_uninstall.setEnabled(False)
10292
self.l_status.setText("Updating patcher")
10393
self.l_versioninfo.setText('⏳Please wait⏳')
10494
self.iprocess = UpdateSpicetify()
10595
self.iprocess.finished_signal.connect(self.update_finished)
10696
self.iprocess.start()
97+
98+
#Update user about progress while installing spicetify
99+
def progressmaster(self, action):
100+
if (action == "fail"):
101+
self.l_status.setStyleSheet("color: red")
102+
self.l_status.setText("⚠️ Installer has crashed ⚠️")
103+
errorDialog("The installation of Spicetify has failed due to an unrecoverable error! Check logs or ask for help.")
107104
else:
108-
print("Error selection overshoot!")
105+
self.l_status.setStyleSheet("color: Orange")
106+
self.l_status.setText(action)
107+
self.l_versioninfo.setText("This process may take a few minutes!")
108+
109109

110110

111111
# Launch uninstaller task
112112
def startRemoval(self):
113113
self.setCursor(Qt.CursorShape.WaitCursor)
114114
self.bt_uninstall.setEnabled(False)
115-
self.bt_update.setEnabled(False)
115+
self.bt_refresh.setEnabled(False)
116116
self.bt_master.setEnabled(False)
117117
self.l_status.setStyleSheet("color: Orange")
118118
self.l_status.setText("Uninstalling Spicetify...")
@@ -192,11 +192,11 @@ def SystemSoftStatusCheck(self):
192192

193193
def installerUiUpdate(self):
194194
self.setCursor(Qt.CursorShape.ArrowCursor)
195-
self.bt_update.setEnabled(True)
195+
self.bt_refresh.setEnabled(True)
196196
self.bt_uninstall.setEnabled(True)
197197
self.bt_master.setEnabled(True)
198198

199-
if(self.isSpotifyInstalled):
199+
if (self.isSpotifyInstalled):
200200

201201
if(self.isSpicetifyInstalled):
202202

requirements.txt

1.41 KB
Binary file not shown.

res/manager.ui

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ QPushButton{
335335
</property>
336336
<layout class="QHBoxLayout" name="advanced">
337337
<item>
338-
<widget class="QPushButton" name="bt_update">
338+
<widget class="QPushButton" name="bt_refresh">
339339
<property name="font">
340340
<font>
341341
<pointsize>-1</pointsize>
@@ -350,7 +350,7 @@ QPushButton{
350350
}</string>
351351
</property>
352352
<property name="text">
353-
<string>Update</string>
353+
<string>Refresh</string>
354354
</property>
355355
<property name="icon">
356356
<iconset>

0 commit comments

Comments
 (0)