diff --git a/install.ps1 b/install.ps1 index 41ff5d5c1..345d07c29 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2" + $defaultInstallSha256 = "1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 2d35e99ba..de16057b6 100644 --- a/install.py +++ b/install.py @@ -18308,8 +18308,9 @@ def _plan_rows(state: TuiState) -> list[TuiRow]: # The size the pack can give: "Install 6.6 GB" from a pack holding # none of the files. lacking = set(_tui_pack_lacks(state, [event["dest"] for event in state.files])) - size = check.get("bytes_needed", 0) - sum(event["size"] for event in state.files - if event["dest"] in lacking) + size = (_ticked_estimate(state)[1] if _tui_estimating(state) + else check.get("bytes_needed", 0) - sum(event["size"] for event in state.files + if event["dest"] in lacking)) label = (f"{TUI_INSTALL_ROW} {format_size(size)}" if size >= CONFIRM_FROM_BYTES else TUI_INSTALL_ROW) rows = [TuiRow("install", label)] @@ -21849,20 +21850,17 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: # The headline counts the systems ticked, as the list just did: at # 40x12 the line below it was dropped, and the plan showed the # total of all of them. Their data files too, as line mode's head. - chosen = _ticked_files(state) # One total, the data files in it, the kinds under the folder # adding up to it. - lines[0] = _styled(f"About {_plural(len(chosen) + data, 'file')}, " - f"{format_size(sum(e['size'] for e in chosen) + (data_size or 0))}" + count, size = _ticked_estimate(state) + lines[0] = _styled(f"About {_plural(count, 'file')}, {format_size(size)}" f", for {len(state.ticked)} of {len(state.systems)} systems", "title") if _offline_only(): # Offline, what the folders copied from hold of the systems # ticked: the plan counted the whole list beside "For your 1 of # 11 systems". - took = {event["dest"] for events in _tui_found_elsewhere(state).values() - for event in events} - held = [event for event in chosen if event["dest"] in took] - rest = len(chosen) - len(held) + data + held = _ticked_held(state) + rest = len(_ticked_files(state)) - len(held) + data # Nothing at hand: the head the whole list's plan says, for the # systems ticked. "About 0 files, 0 B" stood over 20 files the # internet would bring. @@ -21870,8 +21868,8 @@ def _view_plan(state: TuiState, width: int, height: int) -> tuple: f"{agree(rest, 'file needs', 'files need')} the internet, which " f"{offline_named()} does not use, for {len(state.ticked)} of " f"{len(state.systems)} systems", "title") if not held else _styled( - f"About {_plural(len(held), 'file')}, " - f"{format_size(sum(e['size'] for e in held))}, for {len(state.ticked)} of " + f"About {_plural(count, 'file')}, " + f"{format_size(size)}, for {len(state.ticked)} of " f"{len(state.systems)} systems" + (f", {agree(rest, 'needs', 'need')} the internet " f"({offline_named()})" if rest else ""), "title") @@ -22116,6 +22114,27 @@ def _ticked_files(state: TuiState) -> list[dict]: or (not event["systems"] and OTHER_SYSTEMS in state.ticked)] +def _ticked_held(state: TuiState) -> list[dict]: + """Offline, the files of the systems ticked that the folders copied + from hold: all an install without the internet brings.""" + took = {event["dest"] for events in _tui_found_elsewhere(state).values() + for event in events} + return [event for event in _ticked_files(state) if event["dest"] in took] + + +def _ticked_estimate(state: TuiState) -> tuple[int, int]: + """The files and bytes the systems ticked since the check bring, their + data files in them, or offline what the folders copied from hold: the + plan's headline and its Install row both say it. One system ticked, + the headline said 82.2 MB and Install 6.6 GB, the whole list's size.""" + if _offline_only(): + held = _ticked_held(state) + return len(held), sum(event["size"] for event in held) + chosen = _ticked_files(state) + data, data_size = _plan_data(state, state.check or {}) + return len(chosen) + data, sum(event["size"] for event in chosen) + (data_size or 0) + + def _view_systems(state: TuiState, width: int, height: int) -> tuple: rows = tui_rows(state) whole_rows = rows diff --git a/install.sh b/install.sh index 8126910bd..5742d9a2f 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2" +DEFAULT_INSTALL_SHA256="1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index 109e8c2a6..a0c5a8eb9 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1125652, - "sha256": "7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2", + "size": 1126510, + "sha256": "1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1179279, - "sha256": "bce18e6f5457057162d0c9113a9c41bd6dad53bd5badaa46d44b62e7fd7a9299" + "size": 1180137, + "sha256": "193463b29e96c5380fe026134c8d0c76aa79b938b7f40de4a579bda7cec2b630" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1125652, - "sha256": "7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2", + "size": 1126510, + "sha256": "1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1125652, - "sha256": "7bfcc3b63b3d8c34998e021d84f873a49c91837fc266e593e918ac7871ef78b2", + "size": 1126510, + "sha256": "1d6c36d12d2cb728020e8a4cf0994e7c1779a5f2903163a83ed4caea6c54cc42", "executable": false }, { diff --git a/tests/test_install_tui.py b/tests/test_install_tui.py index 610c70221..9431b4a78 100644 --- a/tests/test_install_tui.py +++ b/tests/test_install_tui.py @@ -1722,6 +1722,23 @@ class TicksBarAndPaths(unittest.TestCase): rows = install.tui_rows(state) return rows[state.focus[state.screen]] + def test_install_says_the_size_the_headline_says(self): + """One system ticked: the headline said About 3479 files, 82.2 MB + and the row Install 6.6 GB, the whole list's size.""" + big = 6 * 1024 ** 3 + state = checked_state() + state.files[0] = {**state.files[0], "size": big} + state.check = {**state.check, "bytes_needed": state.check["bytes_needed"] + big} + self.assertEqual(install.tui_rows(state)[0].label, "Install 6.0 GB") + for system, label, head in (("nintendo-gba", "Install", "About 1 file, 16.0 KB"), + ("sony-playstation", "Install 6.0 GB", + "About 3 files, 6.0 GB")): + with self.subTest(system=system): + state.ticked = {system} + self.assertTrue(install._tui_estimating(state)) + self.assertEqual(install.tui_rows(state)[0].label, label) + self.assertIn(head, "\n".join(install.tui_view(state, 80, 24))) + def test_the_filter_never_changes_the_ticks(self): state = self.systems() press(state, "n")