Compare commits

..
25 Commits
Author SHA1 Message Date
aclist dac02d75f6 Merge pull request #319 from aclist/feat/test-writeable
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
feat: disallow updates if binary path is not writeable
2026-05-29 01:09:25 +09:00
aclist 3a5c061dbf chore: update docstring 2026-05-29 01:03:29 +09:00
aclist 3851b76ca0 docs: update changelog 2026-05-29 00:44:35 +09:00
aclist 387930b147 chore: update strings file 2026-05-29 00:44:17 +09:00
aclist c0c3ee8c64 fix: catch error if no GTK theme is available (headless installs) 2026-05-29 00:44:00 +09:00
aclist 1212c09110 feat: add tooltip to load menu button 2026-05-29 00:43:34 +09:00
aclist 86e2249a23 change: enable empty/full filters on first run of LAN page 2026-05-29 00:43:01 +09:00
aclist 302a43e65e change: enable empty/full filters on first run of LAN page 2026-05-29 00:42:43 +09:00
aclist 3dc58c1a69 fix: abort if deps could not be installed in cpython distribution 2026-05-29 00:41:47 +09:00
aclist 9af2145ee8 fix: use dedicated LAN error message 2026-05-29 00:41:24 +09:00
aclist 7b4382b178 chore: bump version 2026-05-28 05:52:46 +09:00
aclist ea3631072b chore: add typehint ignore 2026-05-28 05:49:16 +09:00
aclist 67bae3c3e0 chore: uncomment connection logic 2026-05-28 05:48:25 +09:00
aclist 1ea30270ce fix: break after 10th record 2026-05-28 05:47:59 +09:00
aclist 2c9b36ba84 fix: append history queue (WIP) 2026-05-28 05:24:23 +09:00
aclist fd9eb33714 feat: load direct to menu 2026-05-28 03:34:11 +09:00
aclist 15d928026a feat: add file module 2026-05-28 02:41:41 +09:00
aclist 24d3bc8209 chore: drop comment 2026-05-28 02:41:26 +09:00
aclist 881847cee9 feat: disallow updates if binary path is not writeable 2026-05-28 02:40:13 +09:00
aclist d3a06cf970 Merge pull request #318 from aclist/docs/MTU
docs: update DZG-001 (#315)
2026-05-28 02:18:43 +09:00
aclist 741344e75e docs: update DZG-001 (#315) 2026-05-28 02:18:08 +09:00
aclist a8a7aba338 Merge pull request #317 from aclist/chore/update-actions
chore: update checkout action to v5
2026-05-28 02:11:48 +09:00
aclist fafd4c6000 chore: update checkout action to v5 2026-05-28 02:10:49 +09:00
aclist 7e5e326ebe Merge pull request #316 from aclist/chore/geofile-stripping
chore: add geofile test
2026-05-28 02:09:45 +09:00
aclist e7644b49f5 chore: add geofile test 2026-05-28 02:07:39 +09:00
25 changed files with 223 additions and 57 deletions

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@ jobs:
mirror-to-codeberg:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: pixta-dev/repository-mirroring-action@v1
+2 -1
View File
@@ -36,6 +36,7 @@
- Preconnect warnings/failsafes like filesize
- Save filters per server context between sessions
- Preboot progress dialog
- Choose to jump into splash screen instead of server
## Changed
@@ -52,6 +53,7 @@
- Embed Workshop link in Options menu
- Disable overlay scrollbars on server tables
- Reduce size of geolocation DB on disk (~100MB)
- Enable LAN page Empty/Full filters on first run of app
## Dropped
- Debug mode
@@ -67,7 +69,6 @@
## Unreleased
- Load offline mods
- Choose to jump into splash screen instead of server
- Local documentation
- Raw debug command in context menu
+11 -6
View File
@@ -3,16 +3,21 @@ Knowledge Base
.. _DZG-001:
DZG-001: Periodically getting dropped from servers, or servers appear unreachable
DZG-001: Periodically getting dropped from servers, or servers time out in DZGUI
------------------------------------------------------------------------------------
It is a longstanding issue in DayZ that the game opens a large number of connections when querying servers and/or while connected to servers.
This can result in excess traffic on the user's PC which, depending on how much headroom your network has, can lead to getting dropped, unresponsiveness, or a timeout.
DayZ opens a large number of connections while querying/connected to servers.
If you are on Wi-Fi, try switching to a wired connection and see if the problem resolves itself. If it does, your wireless router settings do not have enough headroom for max simultaneous connections. Use a wired connection, or update your network settings to a more permissive setup.
In addition, packets sent from server responses are expected to be a standard size (see warning below).
Bohemia has acknowledged this issue going back 10+ years and stated that DayZ has a heavy impact on the network, but there is as yet no proposed solution on the DayZ side.
If your network does not have enough headroom or has settings departing from defaults, this may lead to getting dropped from servers,
unresponsiveness, or a timeout.
This issue is frequently seen on Steam Deck, due to the tendency for users to use it in an untethered Wi-Fi setup.
If you are on Wi-Fi, try switching to a wired connection and see if the problem resolves itself. Consumer Wi-Fi routers
tend to have less headroom than their wired counterparts.
.. important::
Ensure that MTU (maximum tranmission unit) on your network is set to the standard size of 1,500 bytes.
If your network preferences or router have "jumbo" frames enabled, packets may be dropped, causing server queries to time out.
.. _DZG-002:
+1 -2
View File
@@ -456,6 +456,5 @@ def get_pretty_version(steam_path: Path, appid: int) -> str | None:
vers = get_dayz_version(pe_file_path)
dayz_version = dayz_version_to_str(vers)
return dayz_version
except Exception as e:
print(e)
except Exception:
return None
+6
View File
@@ -61,6 +61,8 @@ class Details:
@dataclass(slots=True)
class Record:
# TODO: investigate whether this enum is still being used;
# can this be frozen?
"""
The gameport field is manipulated by the RowType.CONN_BY_IP method
"""
@@ -509,6 +511,10 @@ def fqip_to_record(addr: str) -> Optional[Record]:
return Record(r[0], int(r[1]), int(r[2]))
def record_to_fqip(record: Record) -> str:
return f"{record.ip}:{record.gameport}:{record.qport}"
def response_to_fqip(res: dict) -> str:
ip = res["addr"].split(":")[0]
gameport = res["gameport"]
+17
View File
@@ -146,6 +146,23 @@ def connect(client: str, addr: str, appid: int, name: str, mods: list[str]) -> i
return proc.returncode
def load_to_menu(client: str, addr: str, appid: int, name: str, mods: list[str]) -> int:
"""Loads to the menu screen with the selected mods; used for AFK/pre-joining"""
concat = concat_mods(mods)
client_args = concat_bash_args(client)
params = [
"-applaunch",
str(appid),
"-nolauncher",
"-nosplash",
"-skipintro",
f"-name={name}",
f"-mod={concat}",
]
proc = subprocess.run([*client_args, *params])
return proc.returncode
def find_user_id(path: Path) -> str | None:
resolved_path = path / "config" / "loginusers.vdf"
try:
+8 -2
View File
@@ -409,9 +409,12 @@ class Controller(GObject.GObject):
saved_tree = self.get_servers().get_saved()
ServerModelManager(self, saved_tree).remove_by_record(record)
def add_to_history(self, record: dict[str, Any]) -> None:
def add_to_history(self, row: dict[str, Any], record: "Record") -> None:
tv = self.get_servers().get_recent()
ServerModelManager(self, tv).add_to_history(record)
ServerModelManager(self, tv).add_to_history((row, record))
# def append_to_history(self, record: "Record") -> None:
# self.config_man.append_to_history_file(record)
def remove_from_history(self, record: "Record") -> None:
# NOTE: remove action is only possible from history tree context menu,
@@ -508,6 +511,9 @@ class Controller(GObject.GObject):
ind = self.config_man.get_start_tab()
self.get_servers().notebook.set_current_page(ind)
def update_and_load_to_menu(self, raise_window: bool) -> None:
self.connection_man.update_and_connect(raise_window, menu_only=True)
def update_and_connect(self, raise_window: bool) -> None:
self.connection_man.update_and_connect(raise_window)
+3 -1
View File
@@ -36,6 +36,7 @@
- Preconnect warnings/failsafes like filesize
- Save filters per server context between sessions
- Preboot progress dialog
- Choose to jump into splash screen instead of server
## Changed
@@ -51,6 +52,8 @@
- Suppress log messages from imported modules
- Embed Workshop link in Options menu
- Disable overlay scrollbars on server tables
- Reduce size of geolocation DB on disk (~100MB)
- Enable LAN page Empty/Full filters on first run of app
## Dropped
- Debug mode
@@ -66,7 +69,6 @@
## Unreleased
- Load offline mods
- Choose to jump into splash screen instead of server
- Local documentation
- Raw debug command in context menu
+19 -4
View File
@@ -1,6 +1,7 @@
import logging
import traceback
from collections import deque
from typing import Any, TYPE_CHECKING
from dzgui.const.constants import (
@@ -52,11 +53,25 @@ class ConfigManager:
ips.append(record)
self.update_config(Preferences.IP_LIST, ips)
def update_history_file(self, records: list[Any]) -> None:
def update_history_file(self, fqip: str) -> None:
with open(self.prefs.paths.history, "r") as f:
ips = [line.rstrip() for line in f.readlines()]
seen = set()
ips.append(fqip)
# NOTE: Preserve linear order of records while deduplicating
unique = deque(maxlen=10) # type: ignore
for i in range(len(ips) - 1, -1, -1):
if ips[i] not in seen:
seen.add(ips[i])
unique.appendleft(ips[i])
# NOTE: appendleft will push 11th item off right edge
if len(unique) == 10:
break
with open(self.prefs.paths.history, "w") as f:
for record in records:
addr = f"{record[7]}:{record[8]}"
f.write(f"{addr}\n")
for record in unique:
f.write(f"{record}\n")
def remove_saved_server(self, record: str) -> None:
ips = self.lookup(Preferences.IP_LIST)
+27 -8
View File
@@ -15,6 +15,7 @@ from dzgui.api.steam import (
enqueue_mod,
get_remote_signatures,
get_needs_update,
load_to_menu,
)
from dzgui.api.mods import (
@@ -74,6 +75,7 @@ class Prerequisites:
steam_proc: SteamProcess
mods: list[list[str]]
game_mode: bool
is_last_server: bool
class ConnectionManager:
@@ -172,6 +174,8 @@ class ConnectionManager:
game_mode = prefs.is_game_mode
is_last = self.is_last_server()
prereqs = Prerequisites(
name=info.server_name,
appid=info.game_id,
@@ -186,11 +190,23 @@ class ConnectionManager:
steam_proc=steam_proc,
mods=remote_mods,
game_mode=game_mode,
is_last_server=is_last,
)
func = StoredFunc(self.controller.open_connection_assistant, prereqs)
self.thread_man.set_cleanup_func(func, destroy_first=True)
def is_last_server(self) -> bool:
prefs = self.controller.get_prefs()
history = prefs.paths.history
try:
lines = history.read_text().splitlines()
last = lines[-1]
current = Servers.record_to_fqip(self.record)
return last == current
except Exception:
return False
@call_on_thread(dialog.querying)
def query_details(self, record: Servers.Record) -> None:
details = Servers.get_details(record)
@@ -245,11 +261,14 @@ class ConnectionManager:
dialog = ExceptionDialog(self.controller, server_timeout)
dialog.run()
def _connect_steam(self) -> None:
def _connect_steam(self, menu_only: bool) -> None:
addr = f"{self.record.ip}:{self.record.gameport}"
playername = self.controller.query_config(Preferences.NAME)
client = self.controller.query_config(Preferences.CLIENT)
rc = connect(client, addr, self.appid, playername, self.remote_mod_ids)
if menu_only:
rc = load_to_menu(client, addr, self.appid, playername, self.remote_mod_ids)
else:
rc = connect(client, addr, self.appid, playername, self.remote_mod_ids)
if rc != 0:
# TODO: log/pop the error
func = StoredFunc(self.controller.update_status)
@@ -271,10 +290,10 @@ class ConnectionManager:
self.thread_man.set_cleanup_func(func)
def _add_to_history_and_return(self) -> None:
self.controller.add_to_history(self.history)
self.controller.add_to_history(self.history, self.record)
self.controller.open_page(NotebookPage.SERVERS)
def _update_mods(self, raise_window: bool) -> None:
def _update_mods(self, raise_window: bool, menu_only: bool = False) -> None:
# NOTE: fast enqueue all mods in auto mode
prefs = self.controller.get_prefs()
@@ -312,11 +331,11 @@ class ConnectionManager:
update_signatures(self.missing_mods, prefs.paths.version)
# TODO: just push steam path directly
rebuild_symlinks(prefs.paths.config)
self._connect_steam()
self._connect_steam(menu_only)
@call_on_thread(waiting_for_mods, show_cancel=True)
def update_and_connect(self, raise_window: bool) -> None:
def update_and_connect(self, raise_window: bool, menu_only: bool = False) -> None:
if len(self.missing_mods) > 0:
self._update_mods(raise_window)
self._update_mods(raise_window, menu_only)
else:
self._connect_steam()
self._connect_steam(menu_only)
+3 -3
View File
@@ -9,7 +9,7 @@ if TYPE_CHECKING:
class FilterManager:
def __init__(self) -> None:
def __init__(self, show_empty: bool = False, show_full: bool = False) -> None:
self.map_store = ModelFactory().make_map_store()
@@ -17,10 +17,10 @@ class FilterManager:
self.default_filters = {
strings.filter_1pp: True,
strings.filter_day: True,
strings.filter_empty: False,
strings.filter_empty: show_empty,
strings.filter_3pp: True,
strings.filter_night: True,
strings.filter_full: False,
strings.filter_full: show_full,
strings.filter_lowpop: True,
strings.filter_nonascii: False,
strings.filter_duplicate: False,
+3 -2
View File
@@ -85,8 +85,9 @@ class ProxyModelManager:
if found is False:
self.control_model.append(history)
if len(self.control_model) == 11:
del self.control_model[0]
# if len(self.control_model) == 11:
# del self.control_model[0]
self.filter(FilterMode.INITIAL, skip_cache=True)
+22 -9
View File
@@ -14,6 +14,7 @@ from dzgui.const.constants import (
)
from dzgui.const.enum import FilterMode, Preferences, ServerTab
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
from dzgui.strings import dialogs
from dzgui.util.strings import api_warn_msg, dialog
from dzgui.views.dialogs.generic import ExceptionDialog
@@ -23,7 +24,7 @@ gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
if TYPE_CHECKING:
from dzgui.api.servers import A2SInfo
from dzgui.api.servers import A2SInfo, Record
from dzgui.controllers.mc import Controller
from dzgui.model.proxy_model import ProxyModelManager
from dzgui.views.trees.tree_servers import ServerTreeView
@@ -130,7 +131,7 @@ class ServerModelManager:
servers = []
ports = range(1, 256)
failure_func = StoredFunc(self._cleanup_on_failure)
failure_func = StoredFunc(self._cleanup_on_lan_failure)
event = threading.Event()
with ThreadPoolExecutor() as executor:
@@ -225,15 +226,12 @@ class ServerModelManager:
) = None,
) -> None:
proxy_man = self._get_proxy_man()
config_man = self.controller.get_config_man()
if rows is not None:
records = rows
else:
control_model = proxy_man.get_control()
records = control_model
config_man.update_history_file(records)
config_man.update_history_file(records)
self._sort_unique_maps(records)
proxy = proxy_man.get_proxy_model()
self.tv.set_model(proxy)
@@ -249,15 +247,20 @@ class ServerModelManager:
self.emitter.emit("load_maps", store)
# self.emitter.emit("servers_loaded_init")
def add_to_history(self, record: dict[str, Any]) -> None:
# TODO: dataclass for record rows; check for other dict annotations
def add_to_history(self, data: tuple[dict[str, Any], "Record"]) -> None:
row, record = data
proxy_man = self._get_proxy_man()
rows = Servers.parse_json([record])
rows = Servers.parse_json([row])
try:
proxy_man.append_row_to_history(rows[0])
self.update_history()
except Exception:
self.update_history(rows)
return
self.update_history()
fqip = Servers.record_to_fqip(record)
config_man = self.controller.get_config_man()
config_man.update_history_file(fqip)
def remove_from_history(self, record: Servers.Record) -> None:
proxy_man = self._get_proxy_man()
@@ -403,6 +406,16 @@ class ServerModelManager:
if self.first_iteration:
self._update_maps()
def _cleanup_on_lan_failure(self, show_dialog: bool = True) -> None:
if self.preserve_on_fail is False:
self.tv.set_model(None)
filter_man = self.tv.get_filter_man()
filter_man.set_unique_maps([])
if show_dialog:
dialog = ExceptionDialog(self.controller, dialogs.load_error_lan)
dialog.run()
def _cleanup_on_failure(self, show_dialog: bool = True) -> None:
# TODO: disable map, keyword, and filter widgets if model is None
# signal driven (servers_empty, servers_failed_to_load)
+2
View File
@@ -4,3 +4,5 @@ waiting_for_mods = "Waiting for Steam to update mods"
fetching_update = "Fetching update"
failed_to_update = "Failed to update DZGUI executable"
update_success = "Updated successfully. Please exit and relaunch."
load_error_lan = "Failed to find any servers on your network.\nCheck the server query port or your firewall settings."
+4
View File
@@ -1,5 +1,9 @@
update_mods = "Update mods and connect"
connect = "Connect"
connect_last = "Load to menu screen"
connect_last_tooltip = (
"Launch DayZ with these mods (if any) and\ngo to the menu screen without connecting."
)
back = "Back"
cancel = "Cancel"
warnings = "Warnings"
+15
View File
@@ -0,0 +1,15 @@
from datetime import datetime
from pathlib import Path
def is_writeable(path: "Path") -> bool:
now = int(datetime.now().timestamp())
suffix = ".dzgtmp"
file = str(now) + suffix
filepath = Path(str(path) + "_" + file)
try:
filepath.touch()
filepath.unlink()
return True
except OSError:
return False
+1
View File
@@ -611,6 +611,7 @@ atomic_buttons = AtomicButton(
keys_tooltip="Toggles the keybindings dialog",
)
gtk_theme_missing = "No GTK theme provided"
steam_icon_missing = "Steam icon not found in IconTheme"
missing_changelog = "Error: failed to read changelog"
+9 -5
View File
@@ -323,8 +323,12 @@ class App(Gtk.Application):
MainController = Controller()
theme = Gtk.IconTheme.get_default()
icons = theme.list_icons(None)
if STEAM_ICON not in icons:
logger.warn(strings.steam_icon_missing)
warnings.warn(strings.steam_icon_missing, stacklevel=2)
try:
theme = Gtk.IconTheme.get_default()
icons = theme.list_icons(None)
if STEAM_ICON not in icons:
logger.warn(strings.steam_icon_missing)
warnings.warn(strings.steam_icon_missing, stacklevel=2)
except Exception as e:
logger.warning(e)
warnings.warn(strings.gtk_theme_missing, stacklevel=2)
+9 -6
View File
@@ -1,6 +1,7 @@
import logging
import os
from pathlib import Path
from typing import Literal, TYPE_CHECKING
from dzgui.const.constants import (
@@ -13,6 +14,7 @@ from dzgui.const.constants import (
from dzgui.const.enum import ServerTab
from dzgui.managers.update import UpdateManager
from dzgui.util.clip import copy_clipboard
from dzgui.util.file import is_writeable
from dzgui.views.components.buttonbox import ButtonBox
from dzgui.views.components.filter_panel import FilterPanel
from dzgui.views.components.mod_panel import ModSelectionPanel
@@ -87,11 +89,12 @@ class RightPanel(Gtk.Box):
)
exe_path = os.getenv("PYAPP")
if exe_path and update is not None:
self.update_button.set_halign(Gtk.Align.END)
self.gutter_box.add(self.update_button)
self.update_button.connect(
"clicked", self._on_update_button_clicked, exe_path, update
)
if is_writeable(Path(exe_path)) is True:
self.update_button.set_halign(Gtk.Align.END)
self.gutter_box.add(self.update_button)
self.update_button.connect(
"clicked", self._on_update_button_clicked, exe_path, update
)
self.gutter_box.add(eb)
self.pack_start(self.gutter_box, NO_EXPAND, FILL, NO_PADDING)
@@ -108,7 +111,7 @@ class RightPanel(Gtk.Box):
return
self.filters_vbox.set_sensitive(False)
# TODO: unless it is lan page
#self.refresh_button.set_sensitive(False)
# self.refresh_button.set_sensitive(False)
def _on_lan_page_init(self, emitter: "Emitter") -> None:
self.filters_vbox.set_sensitive(False)
+13 -1
View File
@@ -106,6 +106,9 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
label=preconnect.back, halign=Gtk.Align.END, hexpand=True
)
self.ok = Gtk.Button(label=preconnect.update_mods, halign=Gtk.Align.END)
self.connect_last = Gtk.Button(
label=preconnect.connect_last, halign=Gtk.Align.END, tooltip_text=preconnect.connect_last_tooltip
)
# TODO: abstract
self.raise_window = Gtk.CheckButton(
@@ -126,13 +129,14 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
spacing=5,
)
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
for button in self.back, self.ok:
for button in self.back, self.ok, self.connect_last:
box.add(button)
for el in self.raise_window, box:
self.button_box.add(el)
self.back.connect("clicked", self._on_back_clicked)
self.ok.connect("clicked", self._on_ok_clicked)
self.connect_last.connect("clicked", self._on_connect_last_clicked)
self.title = Gtk.Label(label="")
add_class(self.title, "preconnect-heading")
@@ -213,6 +217,9 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
if event.keyval == Gdk.KEY_u:
self.ok.emit("clicked")
def _on_connect_last_clicked(self, button: Gtk.Button) -> None:
self.controller.update_and_load_to_menu(self.raise_window.get_active())
def _on_ok_clicked(self, button: Gtk.Button) -> None:
self.controller.update_and_connect(self.raise_window.get_active())
@@ -308,6 +315,11 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
prefix = preconnect.total_mods
self.mod_count.set_text(f"{prefix}{str(total_mods)}.{suffix}")
if prereqs.is_last_server:
self.connect_last.show()
else:
self.connect_last.hide()
self._process_warnings(prereqs)
if self.tree.is_visible():
self.tree.grab_focus()
+7 -1
View File
@@ -47,7 +47,13 @@ class ServerNotebook(Gtk.ScrolledWindow):
self.recent = ServerTreeView(
controller, ServerTab.RECENT, ContextMenuGroup.RECENT
)
self.lan = ServerTreeView(controller, ServerTab.LAN, ContextMenuGroup.SCAN_LAN)
self.lan = ServerTreeView(
controller,
ServerTab.LAN,
ContextMenuGroup.SCAN_LAN,
show_empty=True,
show_full=True,
)
tabs = [
(self.browser, server_labels.browser),
+7 -2
View File
@@ -38,7 +38,12 @@ QUEUE_CHECK_DELAY = 200
class ServerTreeView(ContextMixin, TreeView): # type: ignore
def __init__(
self, controller: "Controller", enum: ServerTab, menu: ContextMenuGroup
self,
controller: "Controller",
enum: ServerTab,
menu: ContextMenuGroup,
show_empty: bool = False,
show_full: bool = False,
) -> None:
super().__init__(controller, menu=menu)
@@ -48,7 +53,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
self.loaded = False
self.filter_man = FilterManager()
self.filter_man = FilterManager(show_empty, show_full)
self.proxy_man = ProxyModelManager(self.filter_man)
model = self.proxy_man.get_proxy_model()
self.set_model(model)
+1 -1
View File
@@ -4,7 +4,7 @@ description = "DayZ server browser and mod manager for Linux"
authors = [
{name = "aclist"}
]
version = "7.0.0b7"
version = "7.0.0b8"
license = "GPL-3.0-or-later"
license-files = ["LICENSE"]
readme = "README.md"
+5 -2
View File
@@ -53,7 +53,8 @@ def untar(file: str, glob: str, renamed: str) -> None:
def install_deps() -> None:
pip = build_dir.joinpath(f"{CPYTHON_BUILD}/bin/pip")
subprocess.run([pip, "install", root])
proc = subprocess.run([pip, "install", root])
return proc.returncode
def repackage() -> None:
@@ -66,7 +67,9 @@ def repackage() -> None:
def rebuild_cpython() -> None:
if cpython_dir.is_dir() is False:
get_cpython()
install_deps()
code = install_deps()
if code != 0:
return
repackage()
return get_packaged_version()
+27
View File
@@ -0,0 +1,27 @@
from dzgui.config.ipdb import get_ipdb
from pathlib import Path
import os
import pytest
import tempfile
@pytest.mark.slow
def test_stripping():
d = tempfile.TemporaryDirectory()
path = Path(d.name).joinpath("ips.csv")
get_ipdb(path)
with open(path, "rb") as f:
first = f.readline().decode().rstrip()
try:
f.seek(-2, os.SEEK_END)
while f.read(1) != b"\n":
f.seek(-2, os.SEEK_CUR)
except OSError:
f.seek(0)
last = f.read().decode().rstrip()
first_els = first.split(",")
last_els = last.split(",")
assert first_els[0] == "0.0.0.0"
assert last_els[0] == "224.0.0.0"