1
0
Fork 0
mirror of https://github.com/aclist/dztui.git synced 2024-12-28 13:22:35 +01:00

Merge pull request #173 from aclist/release/5.6.0-beta.10

Release/5.6.0-beta.10
This commit is contained in:
aclist 2024-12-05 08:25:19 +09:00 committed by GitHub
commit 3adac2a211
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 107 additions and 39 deletions

View file

@ -1,5 +1,13 @@
# Changelog
## [5.6.0-beta.10] 2024-12-04
### Fixed
- Untoggle highlight button when repopulating mod list
- Resolve remote IP when saving records for game servers with multiple hosts
- Update statusbar when removing servers from list/repopulating
### Added:
- "Select stale" button to bulk select mods marked as obsolete
## [5.6.0-beta.9] 2024-12-03
### Fixed
- Normalize user locale when parsing floats

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -o pipefail
version=5.6.0-beta.9
version=5.6.0-beta.10
#CONSTANTS
aid=221100
@ -569,10 +569,10 @@ fetch_helpers_by_sum(){
[[ -f "$config_file" ]] && source "$config_file"
declare -A sums
sums=(
["ui.py"]="1c6e5b996eccd891a3e56930e28246da"
["ui.py"]="3b90cd522e52131e7ae396671e1c1ad2"
["query_v2.py"]="55d339ba02512ac69de288eb3be41067"
["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397"
["funcs"]="d98d8626a1d61b2d5947b53155a14928"
["funcs"]="62f6b3fb2dcb56a78b7642c0f0aa7abe"
["lan"]="c62e84ddd1457b71a85ad21da662b9af"
)
local author="aclist"

View file

@ -343,7 +343,7 @@ list_mods(){
local base_dir
local size
if [[ -z $(installed_mods) ]] || [[ -z $(find $workshop_dir -maxdepth 2 -name "*.cpp" | grep .cpp) ]]; then
echo "No mods currently installed or incorrect path set."
printf "No mods currently installed or incorrect path set."
logger WARN "Found no locally installed mods"
return 1
else
@ -930,7 +930,7 @@ remove_from_favs(){
break
fi
done
if [[ ${#ip_list} -gt 0 ]]; then
if [[ ${#ip_list[@]} -gt 0 ]]; then
readarray -t ip_list < <(printf "%s\n" "${ip_list[@]}")
fi
update_config
@ -938,6 +938,7 @@ remove_from_favs(){
local cache="$(< "$_cache_my_servers")"
<<< "$cache" grep -v -P "$r$" > $_cache_my_servers
logger INFO "Removed the record $record from saved servers"
echo "Removed $record from saved servers"
return 90
}
update_favs_from_table(){
@ -1019,7 +1020,7 @@ open_workshop_page(){
shift
local id="$1"
local workshop_uri="steam://url/CommunityFilePage/$id"
$steam_cmd "$workshop_uri" $id
$steam_cmd "$workshop_uri" $id &
}
open_link(){
shift

View file

@ -123,6 +123,11 @@ class RowType(EnumWithAttrs):
"label": None,
"tooltip": None,
}
RESOLVE_IP = {
"label": "Resolve IP",
"tooltip": None,
"wait_msg": "Resolving remote IP"
}
HIGHLIGHT = {
"label": "Highlight stale",
"tooltip": None,
@ -156,7 +161,7 @@ class RowType(EnumWithAttrs):
}
RECENT_SERVERS = {
"label": "Recent servers",
"tooltip": "Shows the last to servers you connected to (includes attempts)",
"tooltip": "Shows the last 10 servers you connected to (includes attempts)",
}
CONN_BY_IP = {
"label": "Connect by IP",
@ -539,19 +544,14 @@ def parse_mod_rows(data):
def parse_server_rows(data):
sum = 0
lines = data.stdout.splitlines()
reader = csv.reader(lines, delimiter=delimiter)
hits = len(lines)
try:
rows = [[row[0], row[1], row[2], row[3], int(row[4]), int(row[5]), int(row[6]), row[7], int(row[8])] for row in reader if row]
except IndexError:
return 1
for row in rows:
server_store.append(row)
players = int(row[4])
sum += players
return [sum, hits]
def query_config(widget, key=""):
@ -642,16 +642,35 @@ def process_shell_return_code(transient_parent, msg, code, original_input):
spawn_dialog(transient_parent, msg, Popup.NOTIFY)
return
case 95:
# reload mods list
# successful mod deletion
spawn_dialog(transient_parent, msg, Popup.NOTIFY)
treeview = transient_parent.grid.scrollable_treelist.treeview
grid = treeview.get_parent().get_parent()
(model, pathlist) = treeview.get_selection().get_selected_rows()
for p in reversed(pathlist):
it = model.get_iter(p)
model.remove(it)
total_size = 0
total_mods = len(model)
for row in model:
total_size += row[3]
size = locale.format_string('%.3f', total_size, grouping=True)
pretty = pluralize("mods", total_mods)
grid.update_statusbar(f"Found {total_mods:n} {pretty} taking up {size} MiB")
# untoggle selection for visibility of other stale rows
treeview.toggle_selection(False)
case 96:
# unsuccessful mod deletion
spawn_dialog(transient_parent, msg, Popup.NOTIFY)
# re-block this signal before redrawing table contents
treeview = transient_parent.grid.scrollable_treelist.treeview
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(True)
panel.toggle_select_stale_button(True)
case 100:
# final handoff before launch
final_conf = spawn_dialog(transient_parent, msg, Popup.CONFIRM)
@ -701,6 +720,11 @@ def process_tree_option(input, treeview):
msg = out[-1]
process_shell_return_code(transient_parent, msg, rc, input)
if command == RowType.RESOLVE_IP:
record = "%s:%s" %(treeview.get_column_at_index(7), treeview.get_column_at_index(8))
wait_msg = command.dict["wait_msg"]
call_on_thread(True, cmd_string, wait_msg, record)
return
# help pages
if context == WindowContext.TABLE_MODS and command == RowType.HIGHLIGHT:
wait_msg = command.dict["wait_msg"]
@ -1090,6 +1114,7 @@ class TreeView(Gtk.TreeView):
def _on_menu_click(self, menu_item):
#TODO: context menus use old stringwise parsing
# use enumerated contexts
parent = self.get_outer_window()
context = self.get_first_col()
value = self.get_column_at_index(0)
@ -1099,12 +1124,10 @@ class TreeView(Gtk.TreeView):
match context_menu_label:
case "Add to my servers" | "Remove from my servers":
record = "%s:%s" %(self.get_column_at_index(7), self.get_column_at_index(8))
proc = call_out(parent, context_menu_label, record)
process_tree_option([self.view, RowType.RESOLVE_IP], self)
if context == "Name (My saved servers)":
iter = self.get_current_iter()
server_store.remove(iter)
msg = proc.stdout
res = spawn_dialog(parent, msg, Popup.NOTIFY)
case "Remove from history":
record = "%s:%s" %(self.get_column_at_index(7), self.get_column_at_index(8))
call_out(parent, context_menu_label, record)
@ -1128,18 +1151,20 @@ class TreeView(Gtk.TreeView):
success_msg = "Successfully deleted the mod '%s'." %(value)
fail_msg = "An error occurred during deletion. Aborting."
res = spawn_dialog(parent, conf_msg, Popup.CONFIRM)
if res == 0:
mods = []
symlink = self.get_column_at_index(1)
dir = self.get_column_at_index(2)
concat = symlink + " " + dir + "\n"
mods.append(concat)
with open(mods_temp_file, "w") as outfile:
outfile.writelines(mods)
process_tree_option([self.view, RowType.DELETE_SELECTED], self)
if res != 0:
return
mods = []
symlink = self.get_column_at_index(1)
dir = self.get_column_at_index(2)
concat = symlink + " " + dir + "\n"
mods.append(concat)
with open(mods_temp_file, "w") as outfile:
outfile.writelines(mods)
process_tree_option([self.view, RowType.DELETE_SELECTED], self)
case "Open in Steam Workshop":
record = self.get_column_at_index(2)
call_out(parent, "open_workshop_page", record)
base_cmd = "open_workshop_page"
subprocess.Popen(['/usr/bin/env', 'bash', funcs, base_cmd, record])
def toggle_selection(self, bool):
l = len(mod_store)
@ -1147,12 +1172,10 @@ class TreeView(Gtk.TreeView):
case True:
for i in range (0, l):
path = Gtk.TreePath(i)
it = mod_store.get_iter(path)
self.get_selection().select_path(path)
case False:
for i in range (0, l):
path = Gtk.TreePath(i)
it = mod_store.get_iter(path)
self.get_selection().unselect_path(path)
def _on_button_release(self, widget, event):
@ -1259,8 +1282,11 @@ class TreeView(Gtk.TreeView):
if self.view == WindowContext.TABLE_API or self.view == WindowContext.TABLE_SERVER:
addr = self.get_column_at_index(7)
if addr is None:
server_tooltip[0] = format_tooltip()
grid.update_statusbar(server_tooltip[0])
return
if addr in cache:
server_tooltip[0] = format_tooltip()
dist = format_distance(cache[addr][0])
ping = format_ping(cache[addr][1])
@ -1388,7 +1414,7 @@ class TreeView(Gtk.TreeView):
self.grab_focus()
for column in self.get_columns():
column.connect("notify::width", self._on_col_width_changed)
if hits == 0:
if len(server_store) == 0:
call_out(self, "start_cooldown", "", "")
api_warn_msg = """\
No servers returned. Possible network issue or API key on cooldown?
@ -1403,10 +1429,8 @@ class TreeView(Gtk.TreeView):
data = call_out(self, "dump_servers", mode, *filters)
toggle_signal(self, self.selected_row, '_on_tree_selection_changed', False)
row_metadata = parse_server_rows(data)
sum = row_metadata[0]
hits = row_metadata[1]
server_tooltip[0] = format_tooltip(sum, hits)
parse_server_rows(data)
server_tooltip[0] = format_tooltip()
grid.update_statusbar(server_tooltip[0])
map_data = call_out(self, "get_unique_maps", mode)
@ -1426,6 +1450,7 @@ class TreeView(Gtk.TreeView):
right_panel.set_filter_visibility(False)
else:
grid.sel_panel.set_visible(True)
grid.sel_panel.initialize()
self.set_model(mod_store)
self.grab_focus()
@ -1721,6 +1746,8 @@ class TreeView(Gtk.TreeView):
cooldown = call_out(self, "test_cooldown", "", "")
if cooldown.returncode == 1:
spawn_dialog(outer, cooldown.stdout, Popup.NOTIFY)
# reset context to main menu if navigation was blocked
self.view = WindowContext.MAIN_MENU
return 1
for check in checks:
toggle_signal(filters_vbox, check, '_on_check_toggle', False)
@ -1786,7 +1813,11 @@ def format_metadata(row_sel):
return prefix
def format_tooltip(players, hits):
def format_tooltip():
hits = len(server_store)
players = 0
for row in server_store:
players+= row[4]
hits_pretty = pluralize("matches", hits)
players_pretty = pluralize("players", players)
tooltip = f"Found {hits:n} {hits_pretty} with {players:n} {players_pretty}"
@ -1796,10 +1827,8 @@ def format_tooltip(players, hits):
def filter_servers(transient_parent, filters_vbox, treeview, context):
def filter(dialog):
def clear_and_destroy():
row_metadata = parse_server_rows(data)
sum = row_metadata[0]
hits = row_metadata[1]
server_tooltip[0] = format_tooltip(sum, hits)
parse_server_rows(data)
server_tooltip[0] = format_tooltip()
transient_parent.grid.update_statusbar(server_tooltip[0])
toggle_signal(treeview, treeview.selected_row, '_on_tree_selection_changed', True)
@ -2275,6 +2304,7 @@ class Grid(Gtk.Grid):
self.scrollable_treelist.treeview.terminate_process()
def _on_calclat_started(self, treeview):
server_tooltip[0] = format_tooltip()
server_tooltip[1] = server_tooltip[0] + "| Distance: calculating..."
self.update_statusbar(server_tooltip[1])
@ -2363,6 +2393,19 @@ class ModSelectionPanel(Gtk.Box):
button.connect("clicked", self._on_button_clicked)
self.pack_start(button, False, True, 0)
def initialize(self):
l = len(self.get_children())
last = self.get_children()[l-1]
last_label = last.get_label()
for i in self.get_children():
match i.get_label():
case "Select stale":
i.destroy()
case "Unhighlight stale":
i.set_label("Highlight stale")
def _on_button_clicked(self, button):
self.active_button = button
label = button.get_label()
@ -2384,6 +2427,22 @@ class ModSelectionPanel(Gtk.Box):
process_tree_option([treeview.view, RowType.HIGHLIGHT], treeview)
case "Unhighlight stale":
self.colorize_cells(False)
self._remove_last_button()
case "Select stale":
for i in range (0, len(mod_store)):
if mod_store[i][4] == "#FF0000":
path = Gtk.TreePath(i)
treeview.get_selection().select_path(path)
def toggle_select_stale_button(self, bool):
if bool is True:
button = Gtk.Button(label="Select stale")
button.set_margin_start(10)
button.set_margin_end(10)
button.connect("clicked", self._on_button_clicked)
self.pack_start(button, False, True, 0)
self.show_all()
def colorize_cells(self, bool):
def _colorize(path, color):
@ -2417,7 +2476,6 @@ class ModSelectionPanel(Gtk.Box):
def _iterate_mod_deletion(self, model, pathlist, ct):
# hedge against large number of arguments
widgets = relative_widget(self)
parent = widgets["outer"]
treeview = widgets["treeview"]
@ -2438,6 +2496,7 @@ class ModSelectionPanel(Gtk.Box):
path = model.get_value(it, 2)
concat = symlink + " " + path + "\n"
mods.append(concat)
# hedge against large number of arguments passed to shell
with open(mods_temp_file, "w") as outfile:
outfile.writelines(mods)
process_tree_option([treeview.view, RowType.DELETE_SELECTED], treeview)