# GOGUpdater Desktop application (PySide6) for automatic management of GOG.com offline installers. ## Description GOGUpdater authenticates with a GOG account via OAuth2, lets the user select which games to manage, and automatically downloads/updates offline installers (Windows .exe, Linux .sh) to local directories. The user has a clear overview of installer status and can trigger checks and downloads manually. ## Current version **1.0.0** (2026-04-09) ## Architecture ### GUI — 5 tabs 1. **Login** — OAuth2 flow, opens login URL in system browser, user pastes authorization code 2. **Library** — owned games with management checkboxes, DLCs as sub-items; Windows/Linux platform switcher; double-click opens per-game settings 3. **Languages** — select which languages to download globally; disabled when English-only mode is on 4. **Settings** — Windows/Linux installer paths, English-only toggle, bonus content toggle, scan existing installers 5. **Status** — installer status per platform (Windows/Linux switcher), check/download/prune controls; double-click opens version history dialog ### Installer folder structure ``` /path/Game Name/1.63/English/setup_game.exe /path/Game Name/1.63/Czech/setup_game_cs.exe /path/Game Name/1.52/English/setup_game.exe ← old version kept /path/Game Name/Bonus/soundtrack.zip ← bonus content (no version subfolder) ``` Single-language games and English-only mode skip the language subfolder: ``` /path/Game Name/1.63/setup_game.exe ``` DLC installers are stored inside the parent game's folder. ### Folder name sanitization Game titles are sanitized before use as folder names: - `:` → ` - ` - Strips `®`, `™`, `©` - Removes invalid filesystem characters - Collapses multiple spaces ### Metadata Each target path (windows/linux) contains `gogupdater.json` tracking downloaded installers and bonus files. Stale entries (files deleted outside the app) are cleaned automatically on each status check. ```json { "games": { "1207658691": { "name": "Cyberpunk 2077", "latest_version": "1.63", "managed": true, "installers": [ { "filename": "setup_cyberpunk_2077_1.63.exe", "size": 12345678, "version": "1.63", "language": "en", "installer_type": "game", "downloaded_at": "2026-04-09T10:00:00" } ], "bonuses": [], "last_checked": "2026-04-09T10:00:00" } } } ``` ### Application configuration Stored in `~/.config/gogupdater/`: - `auth.json` — OAuth2 tokens - `config.json` — paths, languages, managed games, english_only, include_bonus, per-game overrides ### GOG API endpoints - `GET /user/data/games` — list of owned game IDs - `GET /products/{id}?expand=downloads,expanded_dlcs` — game info, installers, bonus content, DLCs - `POST https://auth.gog.com/token` — OAuth2 authentication and refresh ### Download URL resolution GOG uses a two-level redirect: API downlink → JSON with CDN URL → actual file. The real filename is extracted from the CDN URL path (e.g. `setup_fallout_2.1.0.18.exe`). ### Version comparison - Strips GOG suffixes like `(gog-3)` before comparing - Numeric dot-separated comparison - Ambiguous cases (e.g. `2.2(gog-3)` vs `2.3`) prompt the user via dialog - Non-version strings like `"bonus"` are treated as unversioned ### Per-game settings Each game can override global settings: - Languages (which languages to download) - English-only (skip language subfolder) - Include bonus content Stored as `game_settings` in `config.json`. Default (no override) entries are not saved. ## Modules (src/) - `auth.py` — authentication, token management - `api.py` — GOG API client (installers, bonus content, owned games) - `config.py` — application config, metadata store, scan/verify existing installers - `downloader.py` — installer and bonus file downloads with resume support - `models.py` — data structures (GameRecord, InstallerInfo, BonusContent, GameSettings, ...) - `version_compare.py` — version comparison with ambiguous case detection - `constants.py` — version, app title, debug mode - `ui/main_window.py` — main window with tab layout - `ui/tab_auth.py` — login tab - `ui/tab_library.py` — library tab with platform switcher - `ui/tab_languages.py` — language selection tab - `ui/tab_settings.py` — settings tab - `ui/tab_status.py` — status tab with platform switcher - `ui/dialog_game_settings.py` — per-game settings dialog - `ui/dialog_game_versions.py` — downloaded version history dialog ## Dependencies - PySide6 - requests - python-dotenv - loguru - tqdm