Skip to content

Commit bf6bdbf

Browse files
authored
Ctmod: Add Proton-Sarek (#518)
* Ctmod: Add Proton-Sarek * Proton-Sarek: Allow async and non-async builds * util: Allow `fetch_project_releases` to take a conditional for adding assets This allows for ctmods, such as Proton-Sarek, to specify how to include additional assets that may not conform to the tagged release name. * Proton-Sarek: Simplify release and GitHub data fetching * Use new functionality in `util#fetch_project_releases` to specify condition to include `-async` tags * Remove override of `__get_data`, instead manage checking whether a release is async inside of `__fetch_github_data` * Use one `asset_condition` to check for assets inside of `__fetch_github_data` * util: Change `extra_asset_condition` to return `list[str]` * Proton-Sarek: Enable downloading for Lutris
1 parent b728fca commit bf6bdbf

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# pupgui2 compatibility tools module
2+
# pythonlover02's Proton-Sarek
3+
# Copyright (C) 2025 DavidoTek, partially based on AUNaseef's protonup
4+
5+
from typing import Callable
6+
7+
8+
from PySide6.QtCore import QCoreApplication
9+
10+
from pupgui2.util import fetch_project_release_data, fetch_project_releases
11+
12+
from pupgui2.resources.ctmods.ctmod_00protonge import CtInstaller as GEProtonInstaller
13+
14+
15+
CT_NAME = 'Proton-Sarek'
16+
CT_LAUNCHERS = ['steam', 'lutris', 'heroicproton', 'bottles', 'advmode']
17+
CT_DESCRIPTION = {'en': QCoreApplication.instance().translate('ctmod_protonsarek', '''A custom Proton build with <a href="https://github.com/pythonlover02/DXVK-Sarek">DXVK-Sarek</a> for users with GPUs that support Vulkan 1.1+ but not Vulkan 1.3, or for those with non-Vulkan support who want a plug-and-play option featuring personal patches.''')}
18+
19+
20+
class CtInstaller(GEProtonInstaller):
21+
22+
BUFFER_SIZE = 65536
23+
CT_URL = 'https://api.github.com/repos/pythonlover02/Proton-Sarek/releases'
24+
CT_INFO_URL = 'https://github.com/pythonlover02/Proton-Sarek/releases/tag/'
25+
26+
def __init__(self, main_window = None) -> None:
27+
28+
super().__init__(main_window)
29+
30+
self.release_format: str = 'tar.gz'
31+
self.async_suffix = '-async'
32+
33+
def fetch_releases(self, count: int = 100, page: int = 1) -> list[str]:
34+
35+
"""
36+
List available releases
37+
Return Type: str[]
38+
"""
39+
40+
include_extra_asset: Callable[..., list[str]] = lambda release: [str(release.get('tag_name', '')) + self.async_suffix for asset in release.get('assets', {}) if self.async_suffix in asset.get('name', '')]
41+
return fetch_project_releases(self.CT_URL, self.rs, count=count, page=page, include_extra_asset=include_extra_asset)
42+
43+
def __fetch_github_data(self, tag: str) -> dict:
44+
45+
"""
46+
Fetch GitHub release information
47+
Return Type: dict
48+
Content(s):
49+
'version', 'date', 'download', 'size'
50+
"""
51+
52+
# Exclude async builds by default -- Maybe 'get_download_url_from_asset' needs to be stricter?
53+
asset_condition = lambda asset: self.async_suffix in asset['name'] if self.async_suffix in tag else self.async_suffix not in asset['name']
54+
return fetch_project_release_data(self.CT_URL, self.release_format, self.rs, tag=tag.replace(self.async_suffix, ''), asset_condition=asset_condition)
55+
56+
def get_info_url(self, version: str) -> str:
57+
58+
"""
59+
Get link with info about version (eg. GitHub release page)
60+
Return Type: str
61+
"""
62+
63+
return super().get_info_url(version.replace(self.async_suffix, ''))

pupgui2/util.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ def is_online(host: str = 'https://api.github.com/rate_limit/', timeout: int = 5
609609

610610

611611
# Only used for dxvk and dxvk-async right now, but is potentially useful to more ctmods?
612-
def fetch_project_releases(releases_url: str, rs: requests.Session, count=100, page=1) -> list[str]:
612+
def fetch_project_releases(releases_url: str, rs: requests.Session, count: int = 100, page: int = 1, include_extra_asset: Callable[..., list[str]] | None = None) -> list[str]:
613613

614614
"""
615615
List available releases for a given project URL hosted using requests.
@@ -628,7 +628,20 @@ def fetch_project_releases(releases_url: str, rs: requests.Session, count=100, p
628628
else:
629629
return [] # Unknown API, cannot fetch releases!
630630

631-
return [release[tag_key] for release in releases if tag_key in release]
631+
releases_list: list[str] = []
632+
for release in releases:
633+
if tag_key in release:
634+
releases_list.append(release[tag_key])
635+
636+
if 'assets' not in release or len(release['assets']) <= 0:
637+
continue
638+
639+
if not include_extra_asset:
640+
continue
641+
642+
releases_list.extend([asset for asset in include_extra_asset(release)])
643+
644+
return releases_list
632645

633646

634647
def get_assets_from_release(release_url: str, release: dict) -> dict:

0 commit comments

Comments
 (0)