1
0
Fork 0
mirror of https://github.com/aclist/dztui.git synced 2025-01-01 15:12:05 +01:00

feat: highlight stale mods (#162)

This commit is contained in:
aclist 2024-11-21 23:40:17 +09:00
parent e9cd457233
commit 08af994361
4 changed files with 92 additions and 14 deletions

View file

@ -1,5 +1,11 @@
# Changelog # Changelog
## [5.6.0-beta.5] 2024-11-21
### Added
- Highlight stale mods in mods list
### Fixed
- Duplicate dialog title on Steam Deck
## [5.6.0-beta.4] 2024-11-20 ## [5.6.0-beta.4] 2024-11-20
### Added ### Added
- Application header bar and controls - Application header bar and controls

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -o pipefail set -o pipefail
version=5.6.0-beta.4 version=5.6.0-beta.5
#CONSTANTS #CONSTANTS
aid=221100 aid=221100
@ -569,10 +569,10 @@ fetch_helpers_by_sum(){
[[ -f "$config_file" ]] && source "$config_file" [[ -f "$config_file" ]] && source "$config_file"
declare -A sums declare -A sums
sums=( sums=(
["ui.py"]="549b0415af9ccad6a882b640615b9a22" ["ui.py"]="15fd3fc32e96db8345c5a3ac8564ecc2"
["query_v2.py"]="55d339ba02512ac69de288eb3be41067" ["query_v2.py"]="55d339ba02512ac69de288eb3be41067"
["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397" ["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397"
["funcs"]="75afe0be7e73af2fb6a7e423b5ac9159" ["funcs"]="d1f0d32e3ad34a34d561305ffa597e79"
["lan"]="c62e84ddd1457b71a85ad21da662b9af" ["lan"]="c62e84ddd1457b71a85ad21da662b9af"
) )
local author="aclist" local author="aclist"

View file

@ -39,6 +39,7 @@ lock_file="$state_path/$prefix.lock"
cache_dir="$HOME/.cache/$app_name" cache_dir="$HOME/.cache/$app_name"
_cache_servers="$cache_dir/$prefix.servers" _cache_servers="$cache_dir/$prefix.servers"
_cache_mods_temp="$cache_dir/$prefix.mods_temp" _cache_mods_temp="$cache_dir/$prefix.mods_temp"
_cache_stale_mods_temp="$cache_dir/$prefix.stale_mods_temp"
_cache_temp="$cache_dir/$prefix.temp" _cache_temp="$cache_dir/$prefix.temp"
_cache_my_servers="$cache_dir/$prefix.my_servers" _cache_my_servers="$cache_dir/$prefix.my_servers"
_cache_history="$cache_dir/$prefix.history" _cache_history="$cache_dir/$prefix.history"
@ -95,6 +96,7 @@ else
fi fi
declare -A funcs=( declare -A funcs=(
["Highlight stale"]="find_stale_mods"
["My servers"]="dump_servers" ["My servers"]="dump_servers"
["Change player name"]="update_config_val" ["Change player name"]="update_config_val"
["Change Steam API key"]="update_config_val" ["Change Steam API key"]="update_config_val"
@ -144,6 +146,20 @@ lan_scan(){
printf "%s\n" "$res" printf "%s\n" "$res"
fi fi
} }
find_stale_mods(){
local res
local mods=()
> $_cache_stale_mods_temp
for i in "${ip_list[@]}"; do
local ip=$(<<< "$i" awk -F: '{print $1}')
local qport=$(<<< "$i" awk -F: '{print $3}')
res=$(a2s $ip $qport rules)
if [[ -n $res ]]; then
printf "%s\n" "$res" >> $_cache_stale_mods_temp
fi
done
return 99
}
get_player_count(){ get_player_count(){
shift shift
local res local res

View file

@ -34,8 +34,8 @@ checks = list()
map_store = Gtk.ListStore(str) map_store = Gtk.ListStore(str)
row_store = Gtk.ListStore(str) row_store = Gtk.ListStore(str)
modlist_store = Gtk.ListStore(str, str, str) modlist_store = Gtk.ListStore(str, str, str)
#cf. mod_cols #cf. mod_cols, last column holds hex color
mod_store = Gtk.ListStore(str, str, str, float) mod_store = Gtk.ListStore(str, str, str, float, str)
#cf. log_cols #cf. log_cols
log_store = Gtk.ListStore(str, str, str, str) log_store = Gtk.ListStore(str, str, str, str)
#cf. browser_cols #cf. browser_cols
@ -53,6 +53,7 @@ changelog_path = '%s/CHANGELOG.md' %(state_path)
geometry_path = '%s/dzg.cols.json' %(state_path) geometry_path = '%s/dzg.cols.json' %(state_path)
funcs = '%s/funcs' %(helpers_path) funcs = '%s/funcs' %(helpers_path)
mods_temp_file = '%s/dzg.mods_temp' %(cache_path) mods_temp_file = '%s/dzg.mods_temp' %(cache_path)
stale_mods_temp_file = '%s/dzg.stale_mods_temp' %(cache_path)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
log_file = '%s/DZGUI_DEBUG.log' %(log_path) log_file = '%s/DZGUI_DEBUG.log' %(log_path)
@ -77,7 +78,8 @@ mod_cols = [
"Mod", "Mod",
"Symlink", "Symlink",
"Dir", "Dir",
"Size (MiB)" "Size (MiB)",
"Color"
] ]
log_cols = [ log_cols = [
"Timestamp", "Timestamp",
@ -121,6 +123,11 @@ class RowType(EnumWithAttrs):
"label": None, "label": None,
"tooltip": None, "tooltip": None,
} }
HIGHLIGHT = {
"label": "Highlight stale",
"tooltip": None,
"wait_msg": "Looking for stale mods"
}
HANDSHAKE = { HANDSHAKE = {
"label": "Handshake", "label": "Handshake",
"tooltip": None, "tooltip": None,
@ -519,8 +526,9 @@ def parse_mod_rows(data):
lines = data.stdout.splitlines() lines = data.stdout.splitlines()
hits = len(lines) hits = len(lines)
reader = csv.reader(lines, delimiter=delimiter) reader = csv.reader(lines, delimiter=delimiter)
# Nonetype inherits default GTK color
try: try:
rows = [[row[0], row[1], row[2], locale.atof(row[3], func=float)] for row in reader if row] rows = [[row[0], row[1], row[2], locale.atof(row[3], func=float), None] for row in reader if row]
except IndexError: except IndexError:
return 1 return 1
for row in rows: for row in rows:
@ -640,6 +648,10 @@ def process_shell_return_code(transient_parent, msg, code, original_input):
# re-block this signal before redrawing table contents # re-block this signal before redrawing table contents
toggle_signal(treeview, treeview, '_on_keypress', False) toggle_signal(treeview, treeview, '_on_keypress', False)
treeview.update_quad_column(RowType.LIST_MODS) treeview.update_quad_column(RowType.LIST_MODS)
case 99:
# highlight stale mods
panel = transient_parent.grid.sel_panel
panel.colorize_cells(msg, True)
case 100: case 100:
# final handoff before launch # final handoff before launch
final_conf = spawn_dialog(transient_parent, msg, Popup.CONFIRM) final_conf = spawn_dialog(transient_parent, msg, Popup.CONFIRM)
@ -690,6 +702,10 @@ def process_tree_option(input, treeview):
process_shell_return_code(transient_parent, msg, rc, input) process_shell_return_code(transient_parent, msg, rc, input)
# help pages # help pages
if context == WindowContext.TABLE_MODS and command == RowType.HIGHLIGHT:
wait_msg = command.dict["wait_msg"]
call_on_thread(True, cmd_string, wait_msg, '')
return
if context == WindowContext.HELP: if context == WindowContext.HELP:
match command: match command:
case RowType.CHANGELOG: case RowType.CHANGELOG:
@ -1589,11 +1605,13 @@ class TreeView(Gtk.TreeView):
for i, column_title in enumerate(cols): for i, column_title in enumerate(cols):
renderer = Gtk.CellRendererText() renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i) column = Gtk.TreeViewColumn(column_title, renderer, text=i, foreground=4)
if mode == RowType.LIST_MODS: if mode == RowType.LIST_MODS:
if i == 3: if i == 3:
column.set_cell_data_func(renderer, self._format_float, func_data=None) column.set_cell_data_func(renderer, self._format_float, func_data=None)
column.set_sort_column_id(i) column.set_sort_column_id(i)
# hidden color property column
if i != 4:
self.append_column(column) self.append_column(column)
widgets = relative_widget(self) widgets = relative_widget(self)
@ -1848,7 +1866,7 @@ class GenericDialog(Gtk.MessageDialog):
text=header_text, text=header_text,
secondary_text=textwrap.fill(text, 50), secondary_text=textwrap.fill(text, 50),
buttons=button_type, buttons=button_type,
title=app_name, title="DZGUI - Dialog",
modal=True, modal=True,
) )
@ -1939,7 +1957,7 @@ class LanDialog(Gtk.MessageDialog):
buttons=Gtk.ButtonsType.OK_CANCEL, buttons=Gtk.ButtonsType.OK_CANCEL,
text=text, text=text,
secondary_text="Select the query port", secondary_text="Select the query port",
title=app_name, title="DZGUI - Dialog",
modal=True, modal=True,
) )
@ -2328,9 +2346,12 @@ class ModSelectionPanel(Gtk.Box):
labels = [ labels = [
"Select all", "Select all",
"Unselect all", "Unselect all",
"Delete selected" "Delete selected",
"Highlight stale"
] ]
self.active_button = None
for l in labels: for l in labels:
button = Gtk.Button(label=l) button = Gtk.Button(label=l)
button.set_margin_start(10) button.set_margin_start(10)
@ -2339,22 +2360,57 @@ class ModSelectionPanel(Gtk.Box):
self.pack_start(button, False, True, 0) self.pack_start(button, False, True, 0)
def _on_button_clicked(self, button): def _on_button_clicked(self, button):
self.active_button = button
label = button.get_label() label = button.get_label()
widgets = relative_widget(self) widgets = relative_widget(self)
parent = widgets["outer"] parent = widgets["outer"]
treeview = widgets["treeview"] treeview = widgets["treeview"]
(model, pathlist) = treeview.get_selection().get_selected_rows()
match label: match label:
case "Select all": case "Select all":
treeview.toggle_selection(True) treeview.toggle_selection(True)
case "Unselect all": case "Unselect all":
treeview.toggle_selection(False) treeview.toggle_selection(False)
case "Delete selected": case "Delete selected":
(model, pathlist) = treeview.get_selection().get_selected_rows()
ct = len(pathlist) ct = len(pathlist)
if ct < 1: if ct < 1:
return return
self._iterate_mod_deletion(model, pathlist, ct) self._iterate_mod_deletion(model, pathlist, ct)
case "Highlight stale":
process_tree_option([treeview.view, RowType.HIGHLIGHT], treeview)
case "Unhighlight stale":
self.colorize_cells(None, False)
def colorize_cells(self, mods, bool):
def _colorize(path, color):
mod_store[path][4] = color
widgets = relative_widget(self)
parent = widgets["outer"]
treeview = widgets["treeview"]
(model, pathlist) = treeview.get_selection().get_selected_rows()
if bool is False:
default = None
for i in range (0, len(mod_store)):
path = Gtk.TreePath(i)
it = mod_store.get_iter(path)
_colorize(path, None)
self.active_button.set_label("Highlight stale")
return
with open(stale_mods_temp_file, "r") as infile:
lines = [line.rstrip('\n') for line in infile]
for i in range (0, len(mod_store)):
red = "#FF0000"
path = Gtk.TreePath(i)
it = mod_store.get_iter(path)
if model.get_value(it, 2) not in lines:
_colorize(path, red)
treeview.toggle_selection(False)
self.active_button.set_label("Unhighlight stale")
def _iterate_mod_deletion(self, model, pathlist, ct): def _iterate_mod_deletion(self, model, pathlist, ct):
# hedge against large number of arguments # hedge against large number of arguments