mirror of
https://github.com/aclist/dztui.git
synced 2024-12-28 21:32:36 +01:00
feat: highlight stale mods (#162)
This commit is contained in:
parent
e9cd457233
commit
08af994361
4 changed files with 92 additions and 14 deletions
|
@ -1,5 +1,11 @@
|
|||
# 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
|
||||
### Added
|
||||
- Application header bar and controls
|
||||
|
|
6
dzgui.sh
6
dzgui.sh
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
set -o pipefail
|
||||
|
||||
version=5.6.0-beta.4
|
||||
version=5.6.0-beta.5
|
||||
|
||||
#CONSTANTS
|
||||
aid=221100
|
||||
|
@ -569,10 +569,10 @@ fetch_helpers_by_sum(){
|
|||
[[ -f "$config_file" ]] && source "$config_file"
|
||||
declare -A sums
|
||||
sums=(
|
||||
["ui.py"]="549b0415af9ccad6a882b640615b9a22"
|
||||
["ui.py"]="15fd3fc32e96db8345c5a3ac8564ecc2"
|
||||
["query_v2.py"]="55d339ba02512ac69de288eb3be41067"
|
||||
["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397"
|
||||
["funcs"]="75afe0be7e73af2fb6a7e423b5ac9159"
|
||||
["funcs"]="d1f0d32e3ad34a34d561305ffa597e79"
|
||||
["lan"]="c62e84ddd1457b71a85ad21da662b9af"
|
||||
)
|
||||
local author="aclist"
|
||||
|
|
|
@ -39,6 +39,7 @@ lock_file="$state_path/$prefix.lock"
|
|||
cache_dir="$HOME/.cache/$app_name"
|
||||
_cache_servers="$cache_dir/$prefix.servers"
|
||||
_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_my_servers="$cache_dir/$prefix.my_servers"
|
||||
_cache_history="$cache_dir/$prefix.history"
|
||||
|
@ -95,6 +96,7 @@ else
|
|||
fi
|
||||
|
||||
declare -A funcs=(
|
||||
["Highlight stale"]="find_stale_mods"
|
||||
["My servers"]="dump_servers"
|
||||
["Change player name"]="update_config_val"
|
||||
["Change Steam API key"]="update_config_val"
|
||||
|
@ -144,6 +146,20 @@ lan_scan(){
|
|||
printf "%s\n" "$res"
|
||||
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(){
|
||||
shift
|
||||
local res
|
||||
|
|
|
@ -34,8 +34,8 @@ checks = list()
|
|||
map_store = Gtk.ListStore(str)
|
||||
row_store = Gtk.ListStore(str)
|
||||
modlist_store = Gtk.ListStore(str, str, str)
|
||||
#cf. mod_cols
|
||||
mod_store = Gtk.ListStore(str, str, str, float)
|
||||
#cf. mod_cols, last column holds hex color
|
||||
mod_store = Gtk.ListStore(str, str, str, float, str)
|
||||
#cf. log_cols
|
||||
log_store = Gtk.ListStore(str, str, str, str)
|
||||
#cf. browser_cols
|
||||
|
@ -53,6 +53,7 @@ changelog_path = '%s/CHANGELOG.md' %(state_path)
|
|||
geometry_path = '%s/dzg.cols.json' %(state_path)
|
||||
funcs = '%s/funcs' %(helpers_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__)
|
||||
log_file = '%s/DZGUI_DEBUG.log' %(log_path)
|
||||
|
@ -77,7 +78,8 @@ mod_cols = [
|
|||
"Mod",
|
||||
"Symlink",
|
||||
"Dir",
|
||||
"Size (MiB)"
|
||||
"Size (MiB)",
|
||||
"Color"
|
||||
]
|
||||
log_cols = [
|
||||
"Timestamp",
|
||||
|
@ -121,6 +123,11 @@ class RowType(EnumWithAttrs):
|
|||
"label": None,
|
||||
"tooltip": None,
|
||||
}
|
||||
HIGHLIGHT = {
|
||||
"label": "Highlight stale",
|
||||
"tooltip": None,
|
||||
"wait_msg": "Looking for stale mods"
|
||||
}
|
||||
HANDSHAKE = {
|
||||
"label": "Handshake",
|
||||
"tooltip": None,
|
||||
|
@ -519,8 +526,9 @@ def parse_mod_rows(data):
|
|||
lines = data.stdout.splitlines()
|
||||
hits = len(lines)
|
||||
reader = csv.reader(lines, delimiter=delimiter)
|
||||
# Nonetype inherits default GTK color
|
||||
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:
|
||||
return 1
|
||||
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
|
||||
toggle_signal(treeview, treeview, '_on_keypress', False)
|
||||
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:
|
||||
# final handoff before launch
|
||||
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)
|
||||
|
||||
# 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:
|
||||
match command:
|
||||
case RowType.CHANGELOG:
|
||||
|
@ -1589,12 +1605,14 @@ class TreeView(Gtk.TreeView):
|
|||
|
||||
for i, column_title in enumerate(cols):
|
||||
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 i == 3:
|
||||
column.set_cell_data_func(renderer, self._format_float, func_data=None)
|
||||
column.set_sort_column_id(i)
|
||||
self.append_column(column)
|
||||
# hidden color property column
|
||||
if i != 4:
|
||||
self.append_column(column)
|
||||
|
||||
widgets = relative_widget(self)
|
||||
grid = widgets["grid"]
|
||||
|
@ -1848,7 +1866,7 @@ class GenericDialog(Gtk.MessageDialog):
|
|||
text=header_text,
|
||||
secondary_text=textwrap.fill(text, 50),
|
||||
buttons=button_type,
|
||||
title=app_name,
|
||||
title="DZGUI - Dialog",
|
||||
modal=True,
|
||||
)
|
||||
|
||||
|
@ -1939,7 +1957,7 @@ class LanDialog(Gtk.MessageDialog):
|
|||
buttons=Gtk.ButtonsType.OK_CANCEL,
|
||||
text=text,
|
||||
secondary_text="Select the query port",
|
||||
title=app_name,
|
||||
title="DZGUI - Dialog",
|
||||
modal=True,
|
||||
)
|
||||
|
||||
|
@ -2328,9 +2346,12 @@ class ModSelectionPanel(Gtk.Box):
|
|||
labels = [
|
||||
"Select all",
|
||||
"Unselect all",
|
||||
"Delete selected"
|
||||
"Delete selected",
|
||||
"Highlight stale"
|
||||
]
|
||||
|
||||
self.active_button = None
|
||||
|
||||
for l in labels:
|
||||
button = Gtk.Button(label=l)
|
||||
button.set_margin_start(10)
|
||||
|
@ -2339,22 +2360,57 @@ class ModSelectionPanel(Gtk.Box):
|
|||
self.pack_start(button, False, True, 0)
|
||||
|
||||
def _on_button_clicked(self, button):
|
||||
self.active_button = button
|
||||
label = button.get_label()
|
||||
widgets = relative_widget(self)
|
||||
parent = widgets["outer"]
|
||||
treeview = widgets["treeview"]
|
||||
(model, pathlist) = treeview.get_selection().get_selected_rows()
|
||||
match label:
|
||||
case "Select all":
|
||||
treeview.toggle_selection(True)
|
||||
case "Unselect all":
|
||||
treeview.toggle_selection(False)
|
||||
case "Delete selected":
|
||||
(model, pathlist) = treeview.get_selection().get_selected_rows()
|
||||
ct = len(pathlist)
|
||||
if ct < 1:
|
||||
return
|
||||
|
||||
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):
|
||||
# hedge against large number of arguments
|
||||
|
|
Loading…
Reference in a new issue