Skip to content

Commit aa35ff5

Browse files
committed
v2 ready
1 parent ca7a4ed commit aa35ff5

File tree

8 files changed

+376
-60
lines changed

8 files changed

+376
-60
lines changed

animation_controller.py

+33-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
1-
# animation_controller.py
2-
31
import time
42
from styling import CAT_FRAMES, THUMBS_UP
3+
import keyboard
4+
from os import environ
5+
6+
environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "1"
7+
import pygame
8+
9+
# Initialize Pygame mixer
10+
pygame.mixer.init()
511

612

713
def play_cool_cat_animation():
8-
"""Play the cool cat ASCII animation."""
9-
for _ in range(3): # Loop the animation 3 times
10-
for frame in CAT_FRAMES:
11-
print("\033c", end="") # Clear the console
12-
print(frame)
13-
time.sleep(1.4) # Wait a bit before showing the next frame
14+
# Load the background music
15+
pygame.mixer.music.load("resources/littleroottown.wav")
16+
# Play the music
17+
pygame.mixer.music.play(-1) # The -1 argument makes the music loop indefinitely
18+
19+
print("Press Enter to exit...")
20+
for frame in CAT_FRAMES:
21+
if keyboard.on_press: # Check if Enter key has been pressed
22+
break # Exit the loop if Enter is pressed
23+
print("\033c", end="") # Clear the console
24+
print(frame)
25+
print("\n\t Press Enter to exit...") # Reminder for the user
26+
time.sleep(1.4) # Wait a bit before showing the next frame
27+
28+
pygame.mixer.music.stop() # Stop the music when exiting the function
29+
print("\033c", end="") # Optionally clear the console after the animation is done
30+
31+
32+
if __name__ == "__main__":
33+
try:
34+
play_cool_cat_animation()
35+
except KeyboardInterrupt:
36+
pass # Handle the case where the script is interrupted with a keyboard interrupt
37+
finally:
38+
pygame.mixer.music.stop() # Ensure the music is stopped even if an exception occurs
1439

1540

1641
def print_thumbs_up():

console_helper.py

+266-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,269 @@
1-
def display_welcome_message():
2-
print("Welcome to the Spicetify Updater!")
3-
# Additional welcome message content
4-
# You can use styling from styling.py here
1+
from datetime import datetime
2+
from sys import platform
3+
import os
4+
import traceback
5+
from styling import BANNER
56

67

7-
def request_user_action():
8-
action = input("Update complete. Press any key to exit or 'a' for animations: ")
9-
if action.lower() == "a":
10-
from animation_controller import start_ascii_animation
11-
12-
start_ascii_animation()
8+
def clear_screen():
9+
"""Clears the console screen based on the OS."""
10+
if platform == "win32":
11+
os.system("cls")
1312
else:
14-
print("Exiting...")
13+
os.system("clear")
14+
15+
16+
def print_banner():
17+
"""Prints the banner that says BARANDEV for the application."""
18+
print(BANNER)
19+
20+
21+
class Menu_generator:
22+
def __init__(
23+
self,
24+
app_name="Default app name",
25+
app_ver="1.0",
26+
side_title="Default side title",
27+
side_bar=True,
28+
side_spacing=15,
29+
separator=True,
30+
enumeration=True,
31+
decoration=True,
32+
choice_msg="Choice",
33+
):
34+
self.app_name = app_name
35+
self.app_ver = app_ver
36+
self.side_bar = side_bar
37+
self.side_title = side_title
38+
self.side_spacing = side_spacing
39+
self.separator = separator
40+
self.enumeration = enumeration
41+
self.decoration = decoration
42+
self.choice_msg = choice_msg
43+
self.clear = Menu_generator.check_os()
44+
45+
@staticmethod
46+
def check_os():
47+
if platform == "linux" or platform == "darwin":
48+
return "clear"
49+
elif platform == "win32":
50+
return "cls"
51+
52+
def logger(func):
53+
def wrapper(self, *args, **kwargs):
54+
try:
55+
return func(self, *args, **kwargs)
56+
except Exception:
57+
TIME = datetime.now().strftime("%H:%M:%S")
58+
TRACEBACK = traceback.format_exc()
59+
with open("crash_log.txt", "a") as f:
60+
f.write(f"{TIME} -- {TRACEBACK}\n")
61+
input(TRACEBACK)
62+
63+
return wrapper
64+
65+
def format_entries(self, main, side=None):
66+
# THIS METHOD HAS TO BE CALLED BEFORE SPLITTING SIDE
67+
# INTO MULTIPLE LISTS!!!
68+
if self.enumeration:
69+
for index, entry in enumerate(main, 1):
70+
main[index - 1] = f"{index}. {entry}"
71+
72+
if self.decoration:
73+
for index, entry in enumerate(main):
74+
main[index] = f"|{entry}"
75+
try:
76+
for index, entry in enumerate(side):
77+
side[index] = f"|{entry}"
78+
except TypeError:
79+
pass
80+
81+
if side:
82+
return main, side
83+
84+
return main
85+
86+
"""
87+
THIS METHOD IS HANDLED BY main_menu AND sub_menu
88+
IT CHECKS IF DATA FOLLOWS GUIDELINES IN
89+
main_menu METHOD
90+
"""
91+
92+
def validate_data(self, dct):
93+
if dct:
94+
for k, v in dct.items():
95+
if not isinstance(v, list):
96+
raise Exception(f"Value from key {k} is not a list!")
97+
else:
98+
raise Exception("You didn't pass anything to the function!")
99+
100+
@logger
101+
def main_menu(self, **kwargs) -> int:
102+
"""
103+
ARGUMENTS NEED TO BE PASSED IN A DICTIONARY
104+
KEYWORDED AND WITH UNPACK OPERATOR
105+
EX. **{"main": ["item1", "item2"]}
106+
EACH VALUE FROM KWARGS KEY VALUE PAIRS
107+
HAS TO BE A LIST OR A TUPLE IN ORDER
108+
TO GENERATE IT TO THE SCREEN
109+
"""
110+
os.system(self.clear)
111+
print_banner()
112+
self.validate_data(kwargs)
113+
114+
main = kwargs.get("main")
115+
main_len = len(main)
116+
side = kwargs.get("side")
117+
side_len = len(side) if side else 0
118+
119+
self.SPACE = 45
120+
# PREVENTS MENU OPTIONS FROM TOUCHING SIDE MENU
121+
# THESE NUMBERS ARE PICKED FOR BEST LOOK
122+
for entry in main:
123+
if len(entry) >= 25:
124+
self.SPACE = len(entry) + 25
125+
126+
if self.side_bar:
127+
main, side = self.format_entries(main[:], side[:])
128+
129+
"""
130+
THE SIDE CONTENT WILL BE SLICED INTO
131+
MULTIPLE LIST BASED ON THE LENGTH OF main
132+
THIS IS DONE IN ORDER TO MAINTAIN EVENLY
133+
POSITIONED MENU AND SIDE MENU ENTRIES
134+
"""
135+
slicer = main_len
136+
sliced_side = []
137+
amount = side_len // main_len
138+
139+
"""
140+
IF DIVIDING LENGTH OF SIDE CONTENT BY
141+
LENGTH OF MAIN CONTENT GIVES US ANYTHING OTHER
142+
THAN 0 THEN THAT MEANS SIDE LIST HAS TO BE SLICED
143+
"""
144+
# if amount != 0:
145+
current_point = 0
146+
for _ in range(amount):
147+
sliced = side[current_point : (main_len + current_point)]
148+
sliced_side.append(sliced)
149+
current_point += main_len
150+
151+
# GET THE UNEVEN REMAINDER FROM side
152+
for li in sliced_side:
153+
for i in li:
154+
side.remove(i)
155+
if side:
156+
sliced_side.append([i for i in side])
157+
# COMMENTED IF ENDS HERE
158+
159+
print(f"{self.app_name} {self.app_ver}")
160+
161+
# MENU GENERATION WITH SIDEBAR
162+
if self.side_bar:
163+
# self.SPACE WAS HERE
164+
print(f"{self.side_title:>{self.SPACE}}")
165+
166+
for index, entry in enumerate(main, 1):
167+
sd = []
168+
for i in range(len(sliced_side)):
169+
try:
170+
sd.append(sliced_side[i][index - 1])
171+
except IndexError:
172+
i += 1
173+
pass
174+
175+
side_str = str()
176+
for string in sd:
177+
side_str += f"{string:<{self.side_spacing}}"
178+
print(f"{entry:<{self.SPACE-18}}{side_str}")
179+
180+
else:
181+
print(f"{self.app_name} {self.app_ver}\n")
182+
main = self.format_entries(main[:])
183+
for entry in main:
184+
print(entry)
185+
186+
"""
187+
THIS PRINTS THE EXIT SEPARATOR
188+
THE NUMBER 18 IN THIS IS
189+
PICKED BASED ON THE BEST LOOK
190+
"""
191+
if self.separator:
192+
x = str()
193+
print(f"{x:-<{self.SPACE - 18}}")
194+
else:
195+
print("")
196+
197+
print(f"{main_len + 1}. Exit")
198+
choice = input(f"\n{self.choice_msg}: ")
199+
print(choice)
200+
return choice
201+
202+
@logger
203+
def sub_menu(self, **kwargs) -> int:
204+
os.system(self.clear)
205+
self.validate_data(kwargs)
206+
207+
title = kwargs.get("title")
208+
main = kwargs.get("main")
209+
210+
main = self.format_entries(main[:])
211+
print(f"{title[0]}\n")
212+
for entry in main:
213+
print(entry)
214+
215+
choice = input(f"\n{self.choice_msg}: ")
216+
print(choice)
217+
return choice
218+
219+
220+
def display_menu(options):
221+
menu = Menu_generator(
222+
app_name="Spicetify Updater",
223+
app_ver="v2.0",
224+
side_title="",
225+
side_bar=True,
226+
side_spacing=15,
227+
separator=True,
228+
enumeration=True,
229+
decoration=True,
230+
choice_msg="Welcome to the Spicetify Updater! Please choose an option",
231+
)
232+
choice = menu.main_menu(
233+
main=options,
234+
side=["Author: BaranDev"],
235+
)
236+
return choice
237+
238+
239+
# EXAMPLE USAGE
240+
"""
241+
if __name__ == "__main__":
242+
menu = Menu_generator(
243+
app_name="Spicetify Updater",
244+
app_ver="v2.0",
245+
side_title="Options",
246+
side_bar=True,
247+
side_spacing=15,
248+
separator=True,
249+
enumeration=True,
250+
decoration=True,
251+
choice_msg="Welcome to the Spicetify Updater! Please choose an option",
252+
)
253+
while True:
254+
choice = menu.main_menu(
255+
main=["Update Spicetify", "Check for Updates"],
256+
side=["Author: BaranDev"],
257+
)
258+
if choice == "1":
259+
print("Updating Spicetify...")
260+
# Add code to update Spicetify here
261+
elif choice == "2":
262+
print("Checking for updates...")
263+
# Add code to check for updates here
264+
elif choice == "3":
265+
break
266+
else:
267+
print("Invalid choice. Please try again.")
268+
input("Press Enter to continue...")
269+
"""

crash_log.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
21:58:14 -- Traceback (most recent call last):
2+
File "c:\Users\PC\Desktop\vsc git clones\spicetify-updater\console_helper.py", line 41, in wrapper
3+
return func(self, *args, **kwargs)
4+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
File "c:\Users\PC\Desktop\vsc git clones\spicetify-updater\console_helper.py", line 162, in main_menu
6+
side_str += f"{string:<{self.side_spacing}}"
7+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8+
ValueError: Sign not allowed in string format specifier
9+

0 commit comments

Comments
 (0)