Implemented GUI for syng #2
3 changed files with 41 additions and 37 deletions
|
@ -36,6 +36,7 @@ import logging
|
||||||
import secrets
|
import secrets
|
||||||
import string
|
import string
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import signal
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from dataclasses import field
|
from dataclasses import field
|
||||||
|
@ -374,6 +375,10 @@ async def handle_request_config(data: dict[str, Any]) -> None:
|
||||||
await sio.emit("config", {"source": data["source"], "config": config})
|
await sio.emit("config", {"source": data["source"], "config": config})
|
||||||
|
|
||||||
|
|
||||||
|
def terminate(*args):
|
||||||
|
print("OOPS")
|
||||||
|
|
||||||
|
|
||||||
async def start_client(config: dict[str, Any]) -> None:
|
async def start_client(config: dict[str, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
Initialize the client and connect to the server.
|
Initialize the client and connect to the server.
|
||||||
|
@ -382,11 +387,12 @@ async def start_client(config: dict[str, Any]) -> None:
|
||||||
:type config: dict[str, Any]
|
:type config: dict[str, Any]
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
sources.update(configure_sources(config["sources"]))
|
sources.update(configure_sources(config["sources"]))
|
||||||
|
|
||||||
if "config" in config:
|
if "config" in config:
|
||||||
last_song = (
|
last_song = (
|
||||||
datetime.datetime.fromisoformat(config["config"]["last_song"])
|
datetime.datetime.fromisoformat(config["config"]["last_song"]).timestamp()
|
||||||
if "last_song" in config["config"] and config["config"]["last_song"]
|
if "last_song" in config["config"] and config["config"]["last_song"]
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
@ -403,21 +409,9 @@ async def start_client(config: dict[str, Any]) -> None:
|
||||||
|
|
||||||
await sio.connect(state.config["server"])
|
await sio.connect(state.config["server"])
|
||||||
await sio.wait()
|
await sio.wait()
|
||||||
|
print("exit")
|
||||||
|
|
||||||
|
|
||||||
async def aiomain() -> None:
|
|
||||||
"""
|
|
||||||
Async main function.
|
|
||||||
|
|
||||||
Parses the arguments, reads a config file and sets default values. Then
|
|
||||||
connects to a specified server.
|
|
||||||
|
|
||||||
If no secret is given, a random secret will be generated and presented to
|
|
||||||
the user.
|
|
||||||
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def create_async_and_start_client(config):
|
def create_async_and_start_client(config):
|
||||||
asyncio.run(start_client(config))
|
asyncio.run(start_client(config))
|
||||||
|
|
||||||
|
|
38
syng/gui.py
38
syng/gui.py
|
@ -21,6 +21,7 @@ from .client import create_async_and_start_client, default_config, start_client
|
||||||
from .sources import available_sources
|
from .sources import available_sources
|
||||||
from .server import main as server_main
|
from .server import main as server_main
|
||||||
|
|
||||||
|
|
||||||
class DateAndTimePickerWindow(customtkinter.CTkToplevel):
|
class DateAndTimePickerWindow(customtkinter.CTkToplevel):
|
||||||
def __init__(self, parent, input_field):
|
def __init__(self, parent, input_field):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
@ -32,8 +33,10 @@ class DateAndTimePickerWindow(customtkinter.CTkToplevel):
|
||||||
# self.timepicker.addAll(constants.HOURS24)
|
# self.timepicker.addAll(constants.HOURS24)
|
||||||
self.timepicker.pack(expand=True, fill="both")
|
self.timepicker.pack(expand=True, fill="both")
|
||||||
|
|
||||||
button = customtkinter.CTkButton(self, text="Ok", command=partial(self.insert, input_field))
|
button = customtkinter.CTkButton(
|
||||||
button.pack(expand=True, fill='x')
|
self, text="Ok", command=partial(self.insert, input_field)
|
||||||
|
)
|
||||||
|
button.pack(expand=True, fill="x")
|
||||||
|
|
||||||
def insert(self, input_field: customtkinter.CTkTextbox):
|
def insert(self, input_field: customtkinter.CTkTextbox):
|
||||||
input_field.delete("0.0", "end")
|
input_field.delete("0.0", "end")
|
||||||
|
@ -51,9 +54,6 @@ class DateAndTimePickerWindow(customtkinter.CTkToplevel):
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class OptionFrame(customtkinter.CTkScrollableFrame):
|
class OptionFrame(customtkinter.CTkScrollableFrame):
|
||||||
def add_option_label(self, text):
|
def add_option_label(self, text):
|
||||||
customtkinter.CTkLabel(self, text=text, justify="left").grid(
|
customtkinter.CTkLabel(self, text=text, justify="left").grid(
|
||||||
|
@ -143,12 +143,16 @@ class OptionFrame(customtkinter.CTkScrollableFrame):
|
||||||
self.number_of_options += 1
|
self.number_of_options += 1
|
||||||
|
|
||||||
def open_date_and_time_picker(self, name, input_field):
|
def open_date_and_time_picker(self, name, input_field):
|
||||||
if name not in self.date_and_time_pickers or not self.date_and_time_pickers[name].winfo_exists():
|
if (
|
||||||
self.date_and_time_pickers[name] = DateAndTimePickerWindow(self, input_field)
|
name not in self.date_and_time_pickers
|
||||||
|
or not self.date_and_time_pickers[name].winfo_exists()
|
||||||
|
):
|
||||||
|
self.date_and_time_pickers[name] = DateAndTimePickerWindow(
|
||||||
|
self, input_field
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.date_and_time_pickers[name].focus()
|
self.date_and_time_pickers[name].focus()
|
||||||
|
|
||||||
|
|
||||||
def add_date_time_option(self, name, description, value):
|
def add_date_time_option(self, name, description, value):
|
||||||
self.add_option_label(description)
|
self.add_option_label(description)
|
||||||
self.date_time_options[name] = None
|
self.date_time_options[name] = None
|
||||||
|
@ -279,7 +283,7 @@ class SyngGui(customtkinter.CTk):
|
||||||
self.protocol("WM_DELETE_WINDOW", self.on_close)
|
self.protocol("WM_DELETE_WINDOW", self.on_close)
|
||||||
|
|
||||||
rel_path = os.path.dirname(__file__)
|
rel_path = os.path.dirname(__file__)
|
||||||
img = PIL.ImageTk.PhotoImage(file=os.path.join(rel_path,"static/syng.png"))
|
img = PIL.ImageTk.PhotoImage(file=os.path.join(rel_path, "static/syng.png"))
|
||||||
self.wm_iconbitmap()
|
self.wm_iconbitmap()
|
||||||
self.iconphoto(False, img)
|
self.iconphoto(False, img)
|
||||||
|
|
||||||
|
@ -313,17 +317,16 @@ class SyngGui(customtkinter.CTk):
|
||||||
)
|
)
|
||||||
loadbutton.pack(side="left")
|
loadbutton.pack(side="left")
|
||||||
|
|
||||||
startbutton = customtkinter.CTkButton(
|
self.startbutton = customtkinter.CTkButton(
|
||||||
fileframe, text="Start", command=self.start_client
|
fileframe, text="Start", command=self.start_client
|
||||||
)
|
)
|
||||||
startbutton.pack(side="right")
|
self.startbutton.pack(side="right")
|
||||||
|
|
||||||
startserverbutton = customtkinter.CTkButton(
|
startserverbutton = customtkinter.CTkButton(
|
||||||
fileframe, text="Start Server", command=self.start_server
|
fileframe, text="Start Server", command=self.start_server
|
||||||
)
|
)
|
||||||
startserverbutton.pack(side="right")
|
startserverbutton.pack(side="right")
|
||||||
|
|
||||||
|
|
||||||
open_web_button = customtkinter.CTkButton(
|
open_web_button = customtkinter.CTkButton(
|
||||||
fileframe, text="Open Web", command=self.open_web
|
fileframe, text="Open Web", command=self.open_web
|
||||||
)
|
)
|
||||||
|
@ -365,6 +368,7 @@ class SyngGui(customtkinter.CTk):
|
||||||
self.updateQr()
|
self.updateQr()
|
||||||
|
|
||||||
def start_client(self):
|
def start_client(self):
|
||||||
|
if self.client is None:
|
||||||
sources = {}
|
sources = {}
|
||||||
for source, tab in self.tabs.items():
|
for source, tab in self.tabs.items():
|
||||||
sources[source] = tab.get_config()
|
sources[source] = tab.get_config()
|
||||||
|
@ -373,14 +377,20 @@ class SyngGui(customtkinter.CTk):
|
||||||
|
|
||||||
config = {"sources": sources, "config": general_config}
|
config = {"sources": sources, "config": general_config}
|
||||||
# print(config)
|
# print(config)
|
||||||
self.client = multiprocessing.Process(target=create_async_and_start_client, args=(config,))
|
self.client = multiprocessing.Process(
|
||||||
|
target=create_async_and_start_client, args=(config,)
|
||||||
|
)
|
||||||
self.client.start()
|
self.client.start()
|
||||||
|
self.startbutton.configure(text="Stop")
|
||||||
|
else:
|
||||||
|
self.client.terminate()
|
||||||
|
self.client = None
|
||||||
|
self.startbutton.configure(text="Start")
|
||||||
|
|
||||||
def start_server(self):
|
def start_server(self):
|
||||||
self.server = multiprocessing.Process(target=server_main)
|
self.server = multiprocessing.Process(target=server_main)
|
||||||
self.server.start()
|
self.server.start()
|
||||||
|
|
||||||
|
|
||||||
def open_web(self):
|
def open_web(self):
|
||||||
config = self.general_config.get_config()
|
config = self.general_config.get_config()
|
||||||
server = config["server"]
|
server = config["server"]
|
||||||
|
|
|
@ -26,6 +26,6 @@ def configure_sources(configs: dict[str, Any]) -> dict[str, Source]:
|
||||||
configured_sources = {}
|
configured_sources = {}
|
||||||
for source, config in configs.items():
|
for source, config in configs.items():
|
||||||
if source in available_sources:
|
if source in available_sources:
|
||||||
if config["enabled"]:
|
if "enabled" in config and config["enabled"]:
|
||||||
configured_sources[source] = available_sources[source](config)
|
configured_sources[source] = available_sources[source](config)
|
||||||
return configured_sources
|
return configured_sources
|
||||||
|
|
Loading…
Add table
Reference in a new issue