feat: spawn dialog on API timeout

This commit is contained in:
aclist 2026-01-26 13:28:10 +09:00
parent d2d5fdb59f
commit 8205559f2e
6 changed files with 32 additions and 54 deletions

View File

@ -397,7 +397,11 @@ def query_api(key: str, appid: int, param: str) -> Res:
"key": key,
}
try:
res = requests.get(STEAM_SERVERS, params=payload, timeout=5)
"""
NOTE: the global default timeout is None;
using a low timeout (~5s) sometimes fails
"""
res = requests.get(STEAM_SERVERS, params=payload, timeout=REQUEST_TIMEOUT)
res.raise_for_status()
parsed = True
status = 200

View File

@ -4,7 +4,7 @@ UDP_PORT = 27016
VM_FILE = "/proc/sys/vm/max_map_count"
MIN_COUNT = 1048576
REQUEST_TIMEOUT = 5
REQUEST_TIMEOUT = 10
APPNAME_DAYZ = "DayZ"
APPNAME_DAYZ_EXP = "DayZ Experimental"

View File

@ -381,7 +381,7 @@ class Controller(GObject.GObject):
res = future.result()
if res.status != 200 or not res.parsed:
# TODO: pop warning dialog
self.push_data(None)
self.push_data(None, FilterMode.INITIAL)
return
j = res.json
serv += j["response"]["servers"]
@ -609,22 +609,22 @@ class Controller(GObject.GObject):
# TODO: may be superfluous
treeview.grab_focus()
self.destroy_on_idle()
if len(treeview.filter_man.get_model()) == 0:
# TODO: different dialogs for server tab contexts
# TODO: if history/favorites is empty, don't even trigger a call
# TODO: add proper string for this dialog
dialog = ExceptionDialog(self, "API TIMEOUT")
dialog.run()
def push_data(self, data: tuple, mode: FilterMode) -> None:
#def cleanup():
# # TODO: rename signal
# self.mediator.statusbar.emit("server_page_changed", context)
# # TODO: may be superfluous
# treeview.grab_focus()
# self.destroy_on_idle()
treeview = self.get_active_treeview()
context = self.get_active_context()
manager = treeview.get_filter_man()
if data is None:
insert = None
else:
manager = treeview.get_filter_man()
# TODO: consolidate into filter manager
if mode == FilterMode.INITIAL:
manager.set_control(data)
@ -639,32 +639,6 @@ class Controller(GObject.GObject):
def highlight_stale(self) -> None:
self.colorize_mods()
# def call_on_thread(self, func: Callable, *args) -> None:
# self.wait_dialog = WaitDialog(self, strings.dialog.fetching)
# self.wait_dialog.show_all()
# thread = threading.Thread(target=func, args=args)
# thread.start()
#def filter_cleanup(self) -> None:
# tv = self.get_active_treeview()
# m = tv.filter_man.get_model()
# # TODO: model should not be getting updated in this thread
# # delegate to self.push_data()
# # keeping in mind that server refresh button has to wipe control model
# tv.set_model(m)
#@call_on_thread
#def filter_threaded(self, mode: FilterMode, label: str) -> None:
# tv = self.get_active_treeview()
# tv.filter_man.filter(mode, label)
# self.set_callback(self.filter_cleanup)
# self.destroy_on_idle()
#def filter_model(self, mode: FilterMode, label: str) -> None:
# tv = self.get_active_treeview()
# tv.set_model(None)
# self.filter_threaded(mode, label)
def get_callback(self) -> Callable | None:
return self.callback["func"]

View File

@ -79,6 +79,7 @@ class FilterPanel(Gtk.Box):
self.filters_label = BoldLabel("Filters")
self.keyword_entry = Gtk.Entry()
# TODO :strings
self.keyword_entry.set_placeholder_text("Filter by keyword")
self.keyword_entry.connect("activate", self._on_keyword_enter)
self.keyword_entry.connect("key-press-event", self._on_keyword_keypress)

View File

@ -1,5 +1,5 @@
import textwrap
from typing import Any, Literal, Self, TYPE_CHECKING
from typing import Literal, Self, TYPE_CHECKING
from dzgui.const.constants import NO_EXPAND, NO_FILL, EXPAND, FILL
from dzgui.const.enum import Popup, ButtonType, NotebookPage
@ -7,6 +7,7 @@ from dzgui.util import strings
from dzgui.views.components.buttons import ClipboardButton
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
@ -29,12 +30,13 @@ if TYPE_CHECKING:
class GenericDialog(Gtk.MessageDialog):
def __init__(self,
def __init__(
self,
controller: "Controller",
text: str,
mtype: Gtk.MessageType,
buttons: Gtk.ButtonsType,
secondary: str
secondary: str,
) -> None:
super().__init__(
transient_for=controller.mediator.window,
@ -101,10 +103,10 @@ class WaitDialog(GenericDialog):
spinner.start()
# FIXME: center on parent window
#self.show_all()
# self.show_all()
def _on_dialog_delete(
self, response_id: Gtk.ResponseType, event: Gdk.Event
self, response_id: Gtk.ResponseType, event: Gdk.Event
) -> Literal[True]:
"""
Prevent manual dialog destruction
@ -143,6 +145,7 @@ class ExceptionDialog(GenericDialog):
dialog = ExceptionDialog(Controller, trace)
dialog.run()
"""
def __init__(self, controller: "Controller", trace: str):
super().__init__(
controller=controller,
@ -154,15 +157,11 @@ class ExceptionDialog(GenericDialog):
# NOTE: box expands to end of content area
scrollable = Gtk.ScrolledWindow(
propagate_natural_height=True,
max_content_height=500
propagate_natural_height=True, max_content_height=500
)
box = Gtk.Box(hexpand=True, vexpand=True, orientation=Gtk.Orientation.VERTICAL)
textview = Gtk.TextView(
wrap_mode=Gtk.WrapMode.WORD,
editable=False,
left_margin=10,
right_margin=10
wrap_mode=Gtk.WrapMode.WORD, editable=False, left_margin=10, right_margin=10
)
textview.set_buffer(Gtk.TextBuffer(text=trace))
box.pack_start(textview, EXPAND, FILL, 10)
@ -176,16 +175,18 @@ class ExceptionDialog(GenericDialog):
copy_button = ClipboardButton(controller, trace)
self.add_action_widget(copy_button, Gtk.ResponseType.NONE)
self.add_button("OK", Gtk.ResponseType.OK)
action_area = self.get_action_area()
self.show_all()
self.show_all()
self.action_area.get_children()[1].grab_focus()
self.connect("response", self._on_response)
def _on_response(self, dialog: Self, response: Gtk.ResponseType) -> None:
def _on_response(
self, dialog: Self, response: Gtk.ResponseType
) -> None | Literal[True]:
match response:
case Gtk.ResponseType.OK:
self.destroy()
case Gtk.ResponseType.NONE:
return True # type: ignore
return True
case Gtk.ResponseType.DELETE_EVENT:
self.destroy()

View File

@ -80,8 +80,7 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
def _on_keypress(self, treeview: Gtk.TreeView, event: Gdk.EventKey) -> None:
if is_navkey(event.keyval):
# TODO: if model is None
if len(self.get_model()) < 2:
if self.get_model() is None:
return
if self.sel_blocked is False:
self.controller.suppress_signal(
@ -108,7 +107,6 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
return
if len(self.get_model()) < 2:
return
if is_navkey(event.keyval):
if self.sel_blocked is True:
self.controller.suppress_signal(