Compare commits
No commits in common. "29bc72cc439416080ba178496c6d3779ac4a4595" and "81c6d2468cc8d5ce6f4431f84fe9a15b150139e0" have entirely different histories.
29bc72cc43
...
81c6d2468c
5 changed files with 9 additions and 157 deletions
|
@ -45,7 +45,6 @@ from . import SYNG_VERSION, jsonencoder
|
||||||
from .entry import Entry
|
from .entry import Entry
|
||||||
from .sources import configure_sources, Source
|
from .sources import configure_sources, Source
|
||||||
from .log import logger
|
from .log import logger
|
||||||
from . import jsonencoder
|
|
||||||
|
|
||||||
|
|
||||||
class ConnectionState:
|
class ConnectionState:
|
||||||
|
@ -175,7 +174,7 @@ class Client:
|
||||||
self.quit_callback,
|
self.quit_callback,
|
||||||
)
|
)
|
||||||
self.connection_state.set_mpv_running()
|
self.connection_state.set_mpv_running()
|
||||||
logger.debug(f"MPV running: {self.connection_state.is_mpv_running()} ")
|
logger.info(f"MPV: {self.connection_state.is_mpv_running()} ")
|
||||||
self.register_handlers()
|
self.register_handlers()
|
||||||
self.queue_callbacks: list[Callable[[list[Entry]], None]] = []
|
self.queue_callbacks: list[Callable[[list[Entry]], None]] = []
|
||||||
|
|
||||||
|
@ -249,8 +248,8 @@ class Client:
|
||||||
terminated.
|
terminated.
|
||||||
"""
|
"""
|
||||||
logger.info("Disconnecting from server")
|
logger.info("Disconnecting from server")
|
||||||
logger.debug(f"Connection: {self.connection_state.is_connected()}")
|
logger.info(f"Connection: {self.connection_state.is_connected()}")
|
||||||
logger.debug(f"MPV running: {self.connection_state.is_mpv_running()}")
|
logger.info(f"MPV: {self.connection_state.is_mpv_running()}")
|
||||||
if self.connection_state.is_connected():
|
if self.connection_state.is_connected():
|
||||||
await self.sio.disconnect()
|
await self.sio.disconnect()
|
||||||
if self.connection_state.is_mpv_running():
|
if self.connection_state.is_mpv_running():
|
||||||
|
@ -618,43 +617,6 @@ class Client:
|
||||||
logger.info("Removing room %s from server", self.state.config["room"])
|
logger.info("Removing room %s from server", self.state.config["room"])
|
||||||
await self.sio.emit("remove-room", {"room": self.state.config["room"]})
|
await self.sio.emit("remove-room", {"room": self.state.config["room"]})
|
||||||
|
|
||||||
def export_queue(self, filename: str) -> None:
|
|
||||||
"""
|
|
||||||
Export the current queue to a file.
|
|
||||||
|
|
||||||
:param filename: The name of the file to export the queue to.
|
|
||||||
:type filename: str
|
|
||||||
:rtype: None
|
|
||||||
"""
|
|
||||||
with open(filename, "w", encoding="utf8") as file:
|
|
||||||
jsonencoder.dump(
|
|
||||||
{
|
|
||||||
"queue": self.state.queue,
|
|
||||||
"waiting_room": self.state.waiting_room,
|
|
||||||
"recent": self.state.recent,
|
|
||||||
},
|
|
||||||
file,
|
|
||||||
indent=2,
|
|
||||||
ensure_ascii=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def import_queue(self, filename: str) -> None:
|
|
||||||
"""
|
|
||||||
Import a queue from a file.
|
|
||||||
|
|
||||||
:param filename: The name of the file to import the queue from.
|
|
||||||
:type filename: str
|
|
||||||
:rtype: None
|
|
||||||
"""
|
|
||||||
with open(filename, "r", encoding="utf8") as file:
|
|
||||||
data = jsonencoder.load(file)
|
|
||||||
queue = [Entry(**entry) for entry in data["queue"]]
|
|
||||||
waiting_room = [Entry(**entry) for entry in data["waiting_room"]]
|
|
||||||
recent = [Entry(**entry) for entry in data["recent"]]
|
|
||||||
await self.sio.emit(
|
|
||||||
"import-queue", {"queue": queue, "waiting_room": waiting_room, "recent": recent}
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_room_removed(self, data: dict[str, Any]) -> None:
|
async def handle_room_removed(self, data: dict[str, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
Handle the "room-removed" message.
|
Handle the "room-removed" message.
|
||||||
|
|
69
syng/gui.py
69
syng/gui.py
|
@ -564,6 +564,9 @@ class SyngGui(QMainWindow):
|
||||||
self.buttons_layout.addItem(spacer_item)
|
self.buttons_layout.addItem(spacer_item)
|
||||||
|
|
||||||
if os.getenv("SYNG_DEBUG", "0") == "1":
|
if os.getenv("SYNG_DEBUG", "0") == "1":
|
||||||
|
self.remove_room_button = QPushButton("Remove Room")
|
||||||
|
self.remove_room_button.clicked.connect(self.remove_room)
|
||||||
|
self.buttons_layout.addWidget(self.remove_room_button)
|
||||||
self.print_background_tasks_button = QPushButton("Print Background Tasks")
|
self.print_background_tasks_button = QPushButton("Print Background Tasks")
|
||||||
self.print_background_tasks_button.clicked.connect(
|
self.print_background_tasks_button.clicked.connect(
|
||||||
lambda: print(asyncio.all_tasks(self.loop))
|
lambda: print(asyncio.all_tasks(self.loop))
|
||||||
|
@ -575,50 +578,9 @@ class SyngGui(QMainWindow):
|
||||||
self.startbutton.clicked.connect(self.start_syng_client)
|
self.startbutton.clicked.connect(self.start_syng_client)
|
||||||
self.buttons_layout.addWidget(self.startbutton)
|
self.buttons_layout.addWidget(self.startbutton)
|
||||||
|
|
||||||
def export_queue(self) -> None:
|
|
||||||
if self.client is not None:
|
|
||||||
filename = QFileDialog.getSaveFileName(self, "Export Queue", "", "JSON Files (*.json)")[
|
|
||||||
0
|
|
||||||
]
|
|
||||||
if filename:
|
|
||||||
self.client.export_queue(filename)
|
|
||||||
else:
|
|
||||||
QMessageBox.warning(
|
|
||||||
self,
|
|
||||||
"No Client Running",
|
|
||||||
"You need to start the client before you can export the queue.",
|
|
||||||
)
|
|
||||||
|
|
||||||
def import_queue(self) -> None:
|
|
||||||
if self.client is not None:
|
|
||||||
filename = QFileDialog.getOpenFileName(self, "Import Queue", "", "JSON Files (*.json)")[
|
|
||||||
0
|
|
||||||
]
|
|
||||||
if filename:
|
|
||||||
asyncio.create_task(self.client.import_queue(filename))
|
|
||||||
else:
|
|
||||||
QMessageBox.warning(
|
|
||||||
self,
|
|
||||||
"No Client Running",
|
|
||||||
"You need to start the client before you can import a queue.",
|
|
||||||
)
|
|
||||||
|
|
||||||
def remove_room(self) -> None:
|
def remove_room(self) -> None:
|
||||||
if self.client is not None:
|
if self.client is not None:
|
||||||
answer = QMessageBox.question(
|
asyncio.create_task(self.client.remove_room())
|
||||||
self,
|
|
||||||
"Remove Room",
|
|
||||||
"Are you sure you want to remove the room on the server? This will disconnect all clients and clear the queue.",
|
|
||||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
|
||||||
)
|
|
||||||
if answer == QMessageBox.StandardButton.Yes:
|
|
||||||
asyncio.create_task(self.client.remove_room())
|
|
||||||
else:
|
|
||||||
QMessageBox.warning(
|
|
||||||
self,
|
|
||||||
"No Client Running",
|
|
||||||
"You need to start the client before you can remove a room.",
|
|
||||||
)
|
|
||||||
|
|
||||||
def toggle_advanced(self, state: bool) -> None:
|
def toggle_advanced(self, state: bool) -> None:
|
||||||
self.resetbutton.setVisible(state)
|
self.resetbutton.setVisible(state)
|
||||||
|
@ -722,26 +684,6 @@ class SyngGui(QMainWindow):
|
||||||
|
|
||||||
self.tabview.addTab(self.queue_tab, "Queue")
|
self.tabview.addTab(self.queue_tab, "Queue")
|
||||||
|
|
||||||
def add_admin_tab(self) -> None:
|
|
||||||
self.admin_tab = QWidget(parent=self.central_widget)
|
|
||||||
self.admin_layout = QVBoxLayout(self.admin_tab)
|
|
||||||
self.admin_layout.setAlignment(Qt.AlignmentFlag.AlignVCenter)
|
|
||||||
self.admin_tab.setLayout(self.admin_layout)
|
|
||||||
|
|
||||||
self.remove_room_button = QPushButton("Remove Room", self.admin_tab)
|
|
||||||
self.remove_room_button.clicked.connect(self.remove_room)
|
|
||||||
self.admin_layout.addWidget(self.remove_room_button)
|
|
||||||
|
|
||||||
self.export_queue_button = QPushButton("Export Queue", self.admin_tab)
|
|
||||||
self.export_queue_button.clicked.connect(self.export_queue)
|
|
||||||
self.admin_layout.addWidget(self.export_queue_button)
|
|
||||||
|
|
||||||
self.import_queue_button = QPushButton("Import Queue", self.admin_tab)
|
|
||||||
self.import_queue_button.clicked.connect(self.import_queue)
|
|
||||||
self.admin_layout.addWidget(self.import_queue_button)
|
|
||||||
|
|
||||||
self.tabview.addTab(self.admin_tab, "Admin")
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setWindowTitle("Syng")
|
self.setWindowTitle("Syng")
|
||||||
|
@ -770,8 +712,7 @@ class SyngGui(QMainWindow):
|
||||||
for source_name in available_sources:
|
for source_name in available_sources:
|
||||||
self.add_source_config(source_name, config["sources"][source_name])
|
self.add_source_config(source_name, config["sources"][source_name])
|
||||||
|
|
||||||
# self.add_queue_tab()
|
self.add_queue_tab()
|
||||||
self.add_admin_tab()
|
|
||||||
self.add_log_tab()
|
self.add_log_tab()
|
||||||
|
|
||||||
self.update_qr()
|
self.update_qr()
|
||||||
|
|
|
@ -34,20 +34,10 @@ class SyngEncoder(json.JSONEncoder):
|
||||||
|
|
||||||
|
|
||||||
def dumps(obj: Any, **kw: Any) -> str:
|
def dumps(obj: Any, **kw: Any) -> str:
|
||||||
"""Wrap around ``json.dumps`` with the :py:class:`SyngEncoder`."""
|
"""Wrap around ``json.dump`` with the :py:class:`SyngEncoder`."""
|
||||||
return json.dumps(obj, cls=SyngEncoder, **kw)
|
return json.dumps(obj, cls=SyngEncoder, **kw)
|
||||||
|
|
||||||
|
|
||||||
def dump(obj: Any, fp: Any, **kw: Any) -> None:
|
|
||||||
"""Forward everything to ``json.dump``."""
|
|
||||||
json.dump(obj, fp, cls=SyngEncoder, **kw)
|
|
||||||
|
|
||||||
|
|
||||||
def loads(string: str, **kw: Any) -> Any:
|
def loads(string: str, **kw: Any) -> Any:
|
||||||
"""Forward everything to ``json.loads``."""
|
"""Forward everything to ``json.loads``."""
|
||||||
return json.loads(string, **kw)
|
return json.loads(string, **kw)
|
||||||
|
|
||||||
|
|
||||||
def load(fp: Any, **kw: Any) -> Any:
|
|
||||||
"""Forward everything to ``json.load``."""
|
|
||||||
return json.load(fp, **kw)
|
|
||||||
|
|
|
@ -31,17 +31,6 @@ class Queue:
|
||||||
self.num_of_entries_sem = asyncio.Semaphore(len(self._queue))
|
self.num_of_entries_sem = asyncio.Semaphore(len(self._queue))
|
||||||
self.readlock = asyncio.Lock()
|
self.readlock = asyncio.Lock()
|
||||||
|
|
||||||
def extend(self, entries: Iterable[Entry]) -> None:
|
|
||||||
"""
|
|
||||||
Extend the queue with a list of entries and increase the semaphore.
|
|
||||||
|
|
||||||
:param entries: The entries to add
|
|
||||||
:type entries: Iterable[Entry]
|
|
||||||
:rtype: None
|
|
||||||
"""
|
|
||||||
for entry in entries:
|
|
||||||
self.append(entry)
|
|
||||||
|
|
||||||
def append(self, entry: Entry) -> None:
|
def append(self, entry: Entry) -> None:
|
||||||
"""
|
"""
|
||||||
Append an entry to the queue, increase the semaphore.
|
Append an entry to the queue, increase the semaphore.
|
||||||
|
|
|
@ -230,7 +230,6 @@ class Server:
|
||||||
self.sio.on("connect", self.handle_connect)
|
self.sio.on("connect", self.handle_connect)
|
||||||
self.sio.on("search", self.handle_search)
|
self.sio.on("search", self.handle_search)
|
||||||
self.sio.on("search-results", self.handle_search_results)
|
self.sio.on("search-results", self.handle_search_results)
|
||||||
self.sio.on("import-queue", self.handle_import_queue)
|
|
||||||
|
|
||||||
async def is_admin(self, state: State, sid: str) -> bool:
|
async def is_admin(self, state: State, sid: str) -> bool:
|
||||||
"""
|
"""
|
||||||
|
@ -964,35 +963,6 @@ class Server:
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@admin
|
|
||||||
@with_state
|
|
||||||
async def handle_import_queue(self, state: State, sid: str, data: dict[str, Any]) -> None:
|
|
||||||
"""
|
|
||||||
Handle the "import-queue" message.
|
|
||||||
|
|
||||||
This will add entries to the queue and waiting room from the client.
|
|
||||||
|
|
||||||
The data dictionary should have the following keys:
|
|
||||||
- `queue`, a list of entries to import into the queue
|
|
||||||
- `waiting_room`, a list of entries to import into the waiting room
|
|
||||||
|
|
||||||
:param sid: The session id of the client sending this request
|
|
||||||
:type sid: str
|
|
||||||
:param data: A dictionary with the keys described above
|
|
||||||
:type data: dict[str, Any]
|
|
||||||
:rtype: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
queue_entries = [Entry(**entry) for entry in data.get("queue", [])]
|
|
||||||
waiting_room_entries = [Entry(**entry) for entry in data.get("waiting_room", [])]
|
|
||||||
recent_entries = [Entry(**entry) for entry in data.get("recent", [])]
|
|
||||||
|
|
||||||
state.queue.extend(queue_entries)
|
|
||||||
state.waiting_room.extend(waiting_room_entries)
|
|
||||||
state.recent.extend(recent_entries)
|
|
||||||
|
|
||||||
await self.broadcast_state(state, sid=sid)
|
|
||||||
|
|
||||||
@admin
|
@admin
|
||||||
@with_state
|
@with_state
|
||||||
async def handle_remove_room(self, state: State, sid: str, data: dict[str, Any]) -> None:
|
async def handle_remove_room(self, state: State, sid: str, data: dict[str, Any]) -> None:
|
||||||
|
|
Loading…
Add table
Reference in a new issue