Added download settings and optimized the downloader system with concurrency.
This commit is contained in:
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
from dataclasses import asdict, dataclass, fields, replace
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
from pathlib import Path
|
||||
import secrets
|
||||
@@ -41,11 +42,19 @@ class Settings:
|
||||
proton_sync: str = "auto"
|
||||
proton_path: str | None = None
|
||||
game_source: str | None = None
|
||||
download_speed_limit_mbps: float | None = None
|
||||
low_bandwidth_mode: bool = False
|
||||
|
||||
@property
|
||||
def source_override(self) -> Path | None:
|
||||
return Path(self.game_source).expanduser().resolve() if self.game_source else None
|
||||
|
||||
@property
|
||||
def download_speed_limit_bytes_per_second(self) -> int | None:
|
||||
if self.download_speed_limit_mbps is None:
|
||||
return None
|
||||
return round(self.download_speed_limit_mbps * 1_000_000)
|
||||
|
||||
|
||||
def load_settings(paths: AppPaths) -> Settings:
|
||||
value = _read_settings_object(paths.settings_file)
|
||||
@@ -153,6 +162,11 @@ def _settings_from_object(value: dict[str, object]) -> Settings:
|
||||
proton_sync=_string(value, "proton_sync", "auto"),
|
||||
proton_path=_optional_string(value, "proton_path"),
|
||||
game_source=_optional_string(value, "game_source"),
|
||||
download_speed_limit_mbps=_optional_positive_number(
|
||||
value,
|
||||
"download_speed_limit_mbps",
|
||||
),
|
||||
low_bandwidth_mode=_boolean(value, "low_bandwidth_mode", False),
|
||||
)
|
||||
_validate(settings)
|
||||
return settings
|
||||
@@ -250,6 +264,17 @@ def _validate(settings: Settings) -> None:
|
||||
raise ValueError(f"unsupported runtime selection: {settings.runtime}")
|
||||
if settings.proton_sync not in {"auto", "fsync", "esync"}:
|
||||
raise ValueError(f"unsupported Proton synchronization mode: {settings.proton_sync}")
|
||||
if (
|
||||
settings.download_speed_limit_mbps is not None
|
||||
and (
|
||||
not math.isfinite(settings.download_speed_limit_mbps)
|
||||
or settings.download_speed_limit_mbps <= 0
|
||||
or settings.download_speed_limit_mbps > 10_000
|
||||
)
|
||||
):
|
||||
raise ValueError(
|
||||
"download_speed_limit_mbps must be greater than 0 and at most 10000, or null"
|
||||
)
|
||||
|
||||
def _boolean(value: dict[str, object], key: str, default: bool) -> bool:
|
||||
item = value.get(key, default)
|
||||
@@ -274,4 +299,16 @@ def _optional_string(value: dict[str, object], key: str) -> str | None:
|
||||
return item
|
||||
|
||||
|
||||
def _optional_positive_number(value: dict[str, object], key: str) -> float | None:
|
||||
item = value.get(key)
|
||||
if item is None:
|
||||
return None
|
||||
if isinstance(item, bool) or not isinstance(item, (int, float)):
|
||||
raise ValueError(f"{key} must be null or a positive number")
|
||||
number = float(item)
|
||||
if not math.isfinite(number) or number <= 0:
|
||||
raise ValueError(f"{key} must be null or a positive number")
|
||||
return number
|
||||
|
||||
|
||||
_SETTINGS_FIELD_NAMES = frozenset(field.name for field in fields(Settings))
|
||||
|
||||
Reference in New Issue
Block a user