tui: more work

This commit is contained in:
2025-09-21 00:33:35 -04:00
parent dd546dcce2
commit 2612fc984c

298
tui.py
View File

@ -8,9 +8,11 @@ import bcrypt
import secrets
import string
from sqlalchemy.engine import Row
import inflection
from core.data import Data
from core.config import CoreConfig
from core.const import AllnetCountryCode
try:
from asciimatics.widgets import Frame, Layout, Text, Button, RadioButtons, CheckBox, Divider, Label
@ -139,7 +141,7 @@ class MainView(Frame):
layout.add_widget(Button("User Management", self._user_mgmt))
layout.add_widget(Button("Card Management", self._card_mgmt))
layout.add_widget(Button("Arcade Management", self._arcade_mgmt))
layout.add_widget(Button("Machine Management", self._mech_mgmt))
layout.add_widget(Button("Machine Management", self._machine_mgmt))
layout.add_widget(Button("Quit", self._quit))
self.fix()
@ -156,9 +158,9 @@ class MainView(Frame):
self.save()
raise NextScene("Arcade Management")
def _mech_mgmt(self):
def _machine_mgmt(self):
self.save()
raise NextScene("Mech Management")
raise NextScene("Machine Management")
@staticmethod
def _quit():
@ -193,7 +195,7 @@ class ManageUserView(Frame):
usr_cards = []
if state.selected_user.id != 0:
cards = loop.run_until_complete(data.card.get_user_cards(state.selected_user.id))
for card in cards:
for card in cards or []:
usr_cards.append(card._asdict())
if len(usr_cards) > 0:
@ -693,6 +695,65 @@ class ManageArcadeView(Frame):
self.save()
raise NextScene("Main")
class CreateArcadeView(Frame):
def __init__(self, screen: Screen):
super(CreateArcadeView, self).__init__(
screen,
screen.height * 2 // 3,
screen.width * 2 // 3,
hover_focus=True,
can_scroll=False,
title="Create Arcade"
)
layout = Layout([100], fill_frame=True)
self.add_layout(layout)
layout.add_widget(Text("Name:", "name"))
layout.add_widget(Text("Nickname:", "nickname"))
layout.add_widget(Text("Timezone:", "timezone"))
layout.add_widget(Text("VPN IP:", "ip"))
layout.add_widget(CheckBox("", "Add Machine:", "is_add_machine", ))
layout.add_widget(RadioButtons([
(inflection.titleize(x.name), x.value) for x in AllnetCountryCode
], "Country:", "country"))
layout3 = Layout([100])
self.add_layout(layout3)
layout3.add_widget(Text("", f"status", readonly=True, disabled=True))
layout2 = Layout([1, 1, 1, 1])
self.add_layout(layout2)
layout2.add_widget(Button("OK", self._ok), 0)
layout2.add_widget(Button("Cancel", self._cancel), 3)
self.fix()
def _ok(self):
self.save()
state.clear_last_err()
self.find_widget('status').value = state.last_err
loop.run_until_complete(self._create_arcade_async(self.data.get("name"), self.data.get("nickname"), self.data.get("country"), self.data.get('timezone'), self.data.get('ip')))
raise NextScene("Create Machine" if self.data.get("is_add_machine") else "Arcade Management")
async def _create_arcade_async(self, name: str, nickname: Optional[str], country: str, timezone: Optional[str], ip: Optional[str]):
arcade_id = await data.arcade.create_arcade(name, nickname if nickname != "" else None, country)
if timezone:
data.arcade.set_arcade_timezone(arcade_id, timezone)
if ip:
data.arcade.set_arcade_vpn_ip(arcade_id, ip)
if arcade_id:
state.set_arcade(arcade_id, country, name)
def _cancel(self):
state.clear_last_err()
self.find_widget('status').value = state.last_err
raise NextScene("Arcade Management")
class LookupArcadeView(Frame):
def __init__(self, screen):
super(LookupArcadeView, self).__init__(
@ -800,6 +861,231 @@ class LookupArcadeView(Frame):
self.find_widget('status').value = state.last_err
raise NextScene("Arcade Management")
class ManageMachineView(Frame):
def __init__(self, screen: Screen):
super(ManageMachineView, self).__init__(
screen,
screen.height * 2 // 3,
screen.width * 2 // 3,
hover_focus=True,
can_scroll=False,
title="Machine Management",
on_load=self._redraw
)
layout = Layout([3])
self.add_layout(layout)
layout.add_widget(Button("Create Machine", self._create))
layout.add_widget(Button("Lookup Machine", self._lookup))
def _redraw(self):
self._layouts = [self._layouts[0]]
layout = Layout([3])
self.add_layout(layout)
layout.add_widget(Button("Reassign Machine", self._reassign, disabled=state.selected_machine.id == 0 or state.selected_machine.id is None))
layout.add_widget(Button("Edit Machine", self._edit, disabled=state.selected_machine.id == 0 or state.selected_machine.id is None))
layout.add_widget(Button("Delete Machine", self._del, disabled=state.selected_machine.id == 0 or state.selected_machine.id is None))
layout.add_widget((Divider()))
layout2 = Layout([1, 1, 1])
self.add_layout(layout2)
a = Text("", f"status", readonly=True, disabled=True)
a.value = f"Selected Machine: {state.selected_arcade}"
layout2.add_widget(a)
layout2.add_widget(Button("Back", self._back), 2)
self.fix()
def _create(self):
self.save()
raise NextScene("Create Machine")
def _lookup(self):
self.save()
raise NextScene("Lookup Machine")
def _reassign(self):
self.save()
raise NextScene("Reassign Machine")
def _edit(self):
self.save()
raise NextScene("Edit Machine")
def _del(self):
self.save()
raise NextScene("Delete Machine")
def _back(self):
self.save()
raise NextScene("Main")
class CreateMachineView(Frame):
def __init__(self, screen: Screen):
super(CreateMachineView, self).__init__(
screen,
screen.height - 10,
screen.width * 2 // 3,
hover_focus=True,
can_scroll=False,
title="Create Machine"
)
layout = Layout([100], fill_frame=True)
self.add_layout(layout)
layout.add_widget(Text("Arcade:", "arcade_id"))
layout.add_widget(Text("Serial:", "serial"))
layout.add_widget(Text("Game:", "game_id"))
layout.add_widget(CheckBox("", "Real Cabinet:", "is_cab", ))
layout.add_widget(RadioButtons([("Not Set", None)] + [
(inflection.titleize(x.name), x.value) for x in AllnetCountryCode
], "Country Override:", "country"))
layout3 = Layout([100])
self.add_layout(layout3)
layout3.add_widget(Text("", f"status", readonly=True, disabled=True))
layout2 = Layout([1, 1, 1, 1])
self.add_layout(layout2)
layout2.add_widget(Button("OK", self._ok), 0)
layout2.add_widget(Button("Cancel", self._cancel), 3)
self.fix()
def _redraw(self):
self.find_widget("arcade_id").value = state.selected_arcade.id
def _ok(self):
self.save()
state.clear_last_err()
self.find_widget('status').value = state.last_err
loop.run_until_complete(self._create_arcade_async(self.data.get("name"), self.data.get("nickname"), self.data.get("country"), self.data.get('timezone'), self.data.get('ip')))
raise NextScene("Arcade Management")
async def _create_arcade_async(self, arcade_id: int, serial: str, game: Optional[str], is_cab: bool, country: Optional[str]):
machine_id = await data.arcade.create_machine(arcade_id, serial, None, game, is_cab)
if country:
data.arcade.set_machine_country(machine_id, country)
if machine_id:
state.set_machine(machine_id, serial)
def _cancel(self):
state.clear_last_err()
self.find_widget('status').value = state.last_err
raise NextScene("Machine Management")
class LookupMachineView(Frame):
def __init__(self, screen):
super(LookupMachineView, self).__init__(
screen,
screen.height * 2 // 3,
screen.width * 2 // 3,
hover_focus=True,
can_scroll=False,
title="Lookup Machine"
)
layout = Layout([1, 1], fill_frame=True)
self.add_layout(layout)
layout.add_widget(RadioButtons([
("Name", "1"),
("Serial", "2"),
("Arcade ID", "3"),
("Machine ID", "4"),
], "Search By:", "search_type"))
layout.add_widget(Text("Search:", "search_str"), 1)
layout3 = Layout([100])
self.add_layout(layout3)
layout3.add_widget(Text("", f"status", readonly=True, disabled=True))
layout2 = Layout([1, 1, 1, 1])
self.add_layout(layout2)
layout2.add_widget(Button("Search", self._lookup), 0)
layout2.add_widget(Button("Cancel", self._cancel), 3)
self.fix()
def _lookup(self):
self.save()
if not self.data.get("search_str"):
state.set_last_err("Search cannot be blank")
self.find_widget('status').value = state.last_err
self.screen.reset()
return
state.clear_last_err()
self.find_widget('status').value = state.last_err
search_type = self.data.get("search_type")
if search_type == "1":
loop.run_until_complete(self._lookup_arcade_by_name(self.data.get("search_str")))
elif search_type == "2":
loop.run_until_complete(self._lookup_arcade_by_serial(self.data.get("search_str")))
elif search_type == "3":
real_id = int(self.data.get("search_str"), 16)
loop.run_until_complete(self._lookup_arcade_by_id(real_id))
elif search_type == "4":
loop.run_until_complete(self._lookup_arcade_by_id(self.data.get("search_str")))
else:
state.set_last_err("Unknown search type")
self.find_widget('status').value = state.last_err
self.screen.reset()
return
if len(state.search_results) < 1:
state.set_last_err("Search returned no results")
self.find_widget('status').value = state.last_err
self.screen.reset()
return
state.search_type = "user"
raise NextScene("Search Results")
async def _lookup_arcade_by_id(self, ac_id: str):
ac = await data.arcade.get_arcade(ac_id)
if ac is not None:
res = ac._asdict()
num_cabs = await data.arcade.get_arcade_machines(ac_id)
res['mech_ct'] = len(num_cabs) if num_cabs else 0
state.search_results = [res]
async def _lookup_arcade_by_name(self, name: str):
ac = await data.arcade.get_arcade_by_name(name)
if ac is not None:
res = []
for ac_res in ac:
t = ac_res._asdict()
num_cabs = await data.arcade.get_arcade_machines(t['id'])
t['mech_ct'] = len(num_cabs) if num_cabs else 0
res.append(t)
state.search_results = res
async def _lookup_arcade_by_serial(self, serial: str):
mech = await data.arcade.get_machine(serial)
if mech is not None:
ac = await data.arcade.get_arcade(mech['arcade'])
if ac is not None:
res = ac._asdict()
num_cabs = await data.arcade.get_arcade_machines(mech['arcade'])
res['mech_ct'] = len(num_cabs) if num_cabs else 0
state.search_results = [res]
def _cancel(self):
state.clear_last_err()
self.find_widget('status').value = state.last_err
raise NextScene("Machine Management")
def demo(screen:Screen, scene: Scene):
scenes = [
Scene([MainView(screen)], -1, name="Main"),
@ -810,7 +1096,11 @@ def demo(screen:Screen, scene: Scene):
Scene([ManageCardView(screen)], -1, name="Card Management"),
Scene([EditUserView(screen)], -1, name="Edit User"),
Scene([ManageArcadeView(screen)], -1, name="Arcade Management"),
Scene([CreateArcadeView(screen)], -1, name="Create Arcade"),
Scene([LookupArcadeView(screen)], -1, name="Lookup Arcade"),
Scene([ManageMachineView(screen)], -1, name="Machine Management"),
Scene([LookupMachineView(screen)], -1, name="Lookup Machine"),
Scene([CreateMachineView(screen)], -1, name="Create Machine"),
]
screen.play(scenes, stop_on_resize=False, start_scene=scene, allow_int=True)