spolyrics 1.2.2__tar.gz → 1.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spolyrics
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: A minimalist, borderless, zero-delay synced lyrics miniplayer for Spotify on Windows.
5
5
  Author: SpoLyrics Team
6
6
  Requires-Python: >=3.8
@@ -15,7 +15,7 @@ from assets import ICON_B64
15
15
  from tkinter import messagebox
16
16
  from winsdk.windows.media.control import GlobalSystemMediaTransportControlsSessionManager as MediaManager
17
17
 
18
- CURRENT_VERSION = "1.2.2"
18
+ CURRENT_VERSION = "1.2.4"
19
19
  CONFIG_PATH = os.path.join(os.environ.get("APPDATA", ""), "SpoLyrics", "config.json")
20
20
  APP_DIR = os.path.join(os.environ.get("APPDATA", ""), "SpoLyrics")
21
21
  os.makedirs(APP_DIR, exist_ok=True)
@@ -94,6 +94,10 @@ def get_exe_path():
94
94
  script_exe = os.path.join(sys.prefix, 'Scripts', 'spolyrics.exe')
95
95
  if os.path.exists(script_exe):
96
96
  return script_exe
97
+
98
+ pythonw = os.path.join(sys.prefix, 'pythonw.exe')
99
+ if os.path.exists(pythonw):
100
+ return (pythonw, os.path.abspath(__file__))
97
101
  return sys.executable
98
102
 
99
103
  def set_auto_start(enable, force_update=False):
@@ -104,7 +108,11 @@ def set_auto_start(enable, force_update=False):
104
108
  exe_path = get_exe_path()
105
109
  if exe_path and os.path.exists(icon_path):
106
110
  if force_update or not os.path.exists(STARTUP_SHORTCUT):
107
- ps_script = f"$s=(New-Object -COM WScript.Shell).CreateShortcut('{STARTUP_SHORTCUT}');$s.TargetPath='{exe_path}';$s.IconLocation='{icon_path}';$s.Save()"
111
+ if isinstance(exe_path, tuple):
112
+ target, args = exe_path
113
+ ps_script = f"$s=(New-Object -COM WScript.Shell).CreateShortcut('{STARTUP_SHORTCUT}');$s.TargetPath='{target}';$s.Arguments='\"{args}\"';$s.IconLocation='{icon_path}';$s.Save()"
114
+ else:
115
+ ps_script = f"$s=(New-Object -COM WScript.Shell).CreateShortcut('{STARTUP_SHORTCUT}');$s.TargetPath='{exe_path}';$s.IconLocation='{icon_path}';$s.Save()"
108
116
  subprocess.run(["powershell", "-Command", ps_script], creationflags=0x08000000)
109
117
  else:
110
118
  if os.path.exists(STARTUP_SHORTCUT):
@@ -186,6 +194,20 @@ class MiniLyrics:
186
194
  self.render_lyrics()
187
195
  threading.Thread(target=self.poll_song, daemon=True).start()
188
196
 
197
+ def get_tray_menu(self):
198
+ import pystray
199
+ items = [
200
+ pystray.MenuItem("Shortcuts & Info", self.tray_callbacks['on_info']),
201
+ pystray.MenuItem("Settings", self.tray_callbacks['on_settings']),
202
+ pystray.MenuItem("Toggle Visibility", self.tray_callbacks['on_toggle_lyrics']),
203
+ pystray.MenuItem("Quit", self.tray_callbacks['on_quit']),
204
+ pystray.MenuItem(f"v{CURRENT_VERSION}", lambda: None, enabled=False)
205
+ ]
206
+ if getattr(self, 'update_available', False):
207
+ items.insert(0, pystray.MenuItem("🔥 Update Available!", lambda: self.root.after(0, self.prompt_update)))
208
+ return pystray.Menu(*items)
209
+
210
+
189
211
  def render_lyrics(self):
190
212
  if self.synced_lyrics:
191
213
  pos = self.base_pos
@@ -769,21 +791,31 @@ class MiniLyrics:
769
791
  def show_update_prompt(self, latest):
770
792
  self.update_available = latest
771
793
  if getattr(self, 'tray_icon', None):
772
- self.tray_icon.update_menu()
794
+ self.tray_icon.menu = self.get_tray_menu()
773
795
 
774
796
  res = messagebox.askyesno("Update Available", f"A new version of SpoLyrics (v{latest}) is available!\n\nYou are currently on v{CURRENT_VERSION}.\nWould you like to update now?")
775
797
  if res:
776
798
  import tempfile
777
799
  bat_path = os.path.join(tempfile.gettempdir(), "update_spolyrics.bat")
778
800
  exe_path = get_exe_path()
801
+
802
+ # Extract arguments if get_exe_path returns pythonw.exe + main.py
803
+ exe_cmd = f'"{exe_path}"'
804
+ if isinstance(exe_path, tuple):
805
+ exe_cmd = f'"{exe_path[0]}" "{exe_path[1]}"'
806
+
779
807
  with open(bat_path, 'w') as f:
780
808
  f.write('@echo off\n')
781
809
  f.write('echo Updating SpoLyrics...\n')
782
810
  f.write('ping 127.0.0.1 -n 3 > nul\n')
783
- f.write('python -m pip install --upgrade spolyrics\n')
784
- f.write(f'start "" "{exe_path}"\n')
811
+ import sys
812
+ f.write(f'"{sys.executable}" -m pip install --upgrade --no-cache-dir spolyrics\n')
813
+ f.write(f'start "" {exe_cmd}\n')
785
814
  f.write('del "%~f0"\n')
786
- subprocess.Popen(['cmd.exe', '/c', bat_path], creationflags=16)
815
+
816
+ # Run bat silently without creating a window
817
+ import subprocess
818
+ subprocess.Popen(['cmd.exe', '/c', bat_path], creationflags=0x08000000)
787
819
  if getattr(self, 'tray_icon', None):
788
820
  self.tray_icon.stop()
789
821
  self.root.quit()
@@ -815,15 +847,19 @@ def create_shortcut():
815
847
  with open(path_file, 'r') as f:
816
848
  saved_path = f.read().strip()
817
849
 
818
- if saved_path != exe_path:
850
+ if saved_path != str(exe_path):
819
851
  needs_update = True
820
852
  path_changed = True
821
853
  with open(path_file, 'w') as f:
822
- f.write(exe_path)
854
+ f.write(str(exe_path))
823
855
 
824
856
  if needs_update:
825
857
  if exe_path:
826
- ps_script = f"$s=(New-Object -COM WScript.Shell).CreateShortcut('{shortcut_path}');$s.TargetPath='{exe_path}';$s.IconLocation='{icon_path}';$s.Save()"
858
+ if isinstance(exe_path, tuple):
859
+ target, args = exe_path
860
+ ps_script = f"$s=(New-Object -COM WScript.Shell).CreateShortcut('{shortcut_path}');$s.TargetPath='{target}';$s.Arguments='\"{args}\"';$s.IconLocation='{icon_path}';$s.Save()"
861
+ else:
862
+ ps_script = f"$s=(New-Object -COM WScript.Shell).CreateShortcut('{shortcut_path}');$s.TargetPath='{exe_path}';$s.IconLocation='{icon_path}';$s.Save()"
827
863
  subprocess.run(["powershell", "-Command", ps_script], creationflags=0x08000000)
828
864
  except Exception as e:
829
865
  logging.error("Failed to create shortcut", exc_info=e)
@@ -835,8 +871,7 @@ def setup_tray(app):
835
871
  from PIL import Image
836
872
 
837
873
  def on_quit(icon, item):
838
- icon.stop()
839
- app.root.quit()
874
+ app.root.after(0, app.root.quit)
840
875
 
841
876
  def on_settings(icon, item):
842
877
  app.root.after(0, app.open_settings)
@@ -856,19 +891,23 @@ def setup_tray(app):
856
891
  logging.error("Failed to open tray icon image, using fallback", exc_info=e)
857
892
  image = Image.new('RGB', (64, 64), color = (29, 185, 84))
858
893
 
859
- def get_menu():
860
- items = [
861
- pystray.MenuItem("Shortcuts & Info", on_info),
862
- pystray.MenuItem("Settings", on_settings),
863
- pystray.MenuItem("Toggle Visibility", on_toggle_lyrics),
864
- pystray.MenuItem("Quit", on_quit),
865
- pystray.MenuItem(f"v{CURRENT_VERSION}", lambda: None, enabled=False)
866
- ]
867
- if getattr(app, 'update_available', False):
868
- items.insert(0, pystray.MenuItem("🔥 Update Available!", lambda: app.root.after(0, app.prompt_update)))
869
- return pystray.Menu(*items)
870
-
871
- icon = pystray.Icon("SpoLyrics", image, "SpoLyrics", menu=get_menu)
894
+ app.tray_callbacks = {
895
+ 'on_quit': on_quit,
896
+ 'on_settings': on_settings,
897
+ 'on_toggle_lyrics': on_toggle_lyrics,
898
+ 'on_info': on_info
899
+ }
900
+
901
+ app_dir = os.path.join(os.environ.get("APPDATA", ""), "SpoLyrics")
902
+ icon_path = os.path.join(app_dir, 'icon.ico')
903
+
904
+ try:
905
+ image = Image.open(icon_path)
906
+ except Exception as e:
907
+ logging.error("Failed to open tray icon image, using fallback", exc_info=e)
908
+ image = Image.new('RGB', (64, 64), color = (29, 185, 84))
909
+
910
+ icon = pystray.Icon("SpoLyrics", image, "SpoLyrics", menu=app.get_tray_menu())
872
911
  app.tray_icon = icon
873
912
  threading.Thread(target=icon.run, daemon=True).start()
874
913
  except Exception as e:
@@ -2,7 +2,7 @@ from setuptools import setup
2
2
 
3
3
  setup(
4
4
  name='spolyrics',
5
- version='1.2.2',
5
+ version='1.2.4',
6
6
  description='A minimalist, borderless, zero-delay synced lyrics miniplayer for Spotify on Windows.',
7
7
  long_description=open('README.md', 'r', encoding='utf-8').read(),
8
8
  long_description_content_type='text/markdown',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spolyrics
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: A minimalist, borderless, zero-delay synced lyrics miniplayer for Spotify on Windows.
5
5
  Author: SpoLyrics Team
6
6
  Requires-Python: >=3.8
File without changes
File without changes
File without changes
File without changes