install: download from GitHub Releases
This commit is contained in:
parent
1eb6516f16
commit
560472e4e5
@ -23,12 +23,15 @@ import urllib.parse
|
||||
|
||||
|
||||
class GithubApi:
|
||||
"""
|
||||
Warpper for some select calls to GitHub Json/REST API.
|
||||
"""Wrapper for some select calls to GitHub Json/REST API.
|
||||
|
||||
This class wraps some calls to api.github.com. This is not intended to be a
|
||||
general API wrapper. Instead it's purpose is to return pre-filtered and
|
||||
transformed data that's playing well with other fdroidserver functions.
|
||||
|
||||
With the GitHub API, the token is optional, but it has pretty
|
||||
severe rate limiting.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, api_token, repo_path):
|
||||
@ -41,9 +44,10 @@ class GithubApi:
|
||||
def _req(self, url, data=None):
|
||||
h = {
|
||||
"Accept": "application/vnd.github+json",
|
||||
"Authorization": f"Bearer {self._api_token}",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
}
|
||||
if self._api_token:
|
||||
h["Authorization"] = f"Bearer {self._api_token}"
|
||||
return urllib.request.Request(
|
||||
url,
|
||||
headers=h,
|
||||
@ -65,6 +69,17 @@ class GithubApi:
|
||||
released_tags = self.list_released_tags()
|
||||
return [x for x in all_tags if x not in released_tags]
|
||||
|
||||
def get_latest_apk(self):
|
||||
req = self._req(
|
||||
f"https://api.github.com/repos/{self._repo_path}/releases/latest"
|
||||
)
|
||||
with urllib.request.urlopen(req) as resp: # nosec CWE-22 disable bandit warning
|
||||
assets = json.load(resp)['assets']
|
||||
for asset in assets:
|
||||
url = asset.get('browser_download_url')
|
||||
if url and url.endswith('.apk'):
|
||||
return url
|
||||
|
||||
def tag_exists(self, tag):
|
||||
"""
|
||||
Check if git tag is present on github.
|
||||
|
@ -30,7 +30,7 @@ from pathlib import Path
|
||||
from urllib.parse import urlencode, urlparse, urlunparse
|
||||
|
||||
from . import _
|
||||
from . import common, index, net
|
||||
from . import common, github, index, net
|
||||
from .exception import FDroidException
|
||||
|
||||
|
||||
@ -106,6 +106,17 @@ def download_fdroid_apk(privacy_mode=False): # pylint: disable=unused-argument
|
||||
return net.download_using_mirrors([mirror])
|
||||
|
||||
|
||||
def download_fdroid_apk_from_github(privacy_mode=False):
|
||||
"""Download F-Droid.apk from F-Droid's GitHub Releases."""
|
||||
if common.config and not privacy_mode:
|
||||
token = common.config.get('github_token')
|
||||
else:
|
||||
token = None
|
||||
gh = github.GithubApi(token, 'https://github.com/f-droid/fdroidclient')
|
||||
latest_apk = gh.get_latest_apk()
|
||||
return net.download_file(latest_apk)
|
||||
|
||||
|
||||
def download_fdroid_apk_from_ipns(privacy_mode=False):
|
||||
"""Download the F-Droid APK from an IPNS repo."""
|
||||
cid = 'k51qzi5uqu5dl4hbcksbdmplanu9n4hivnqsupqe6vzve1pdbeh418ssptldd3'
|
||||
@ -161,11 +172,13 @@ def install_fdroid_apk(privacy_mode=False):
|
||||
download_methods = [
|
||||
download_fdroid_apk_from_maven,
|
||||
download_fdroid_apk_from_ipns,
|
||||
download_fdroid_apk_from_github,
|
||||
]
|
||||
else:
|
||||
download_methods = [
|
||||
download_apk,
|
||||
download_fdroid_apk_from_maven,
|
||||
download_fdroid_apk_from_github,
|
||||
download_fdroid_apk_from_ipns,
|
||||
download_fdroid_apk,
|
||||
]
|
||||
|
@ -177,56 +177,65 @@ class InstallTest(unittest.TestCase):
|
||||
|
||||
@patch('fdroidserver.install.download_apk')
|
||||
@patch('fdroidserver.install.download_fdroid_apk')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_github')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_ipns')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_maven')
|
||||
def test_install_fdroid_apk_privacy_mode_true(
|
||||
self, maven, ipns, download_fdroid_apk, download_apk
|
||||
self, maven, ipns, github, download_fdroid_apk, download_apk
|
||||
):
|
||||
download_apk.side_effect = self._download_raise
|
||||
download_fdroid_apk.side_effect = self._download_raise
|
||||
github.side_effect = self._download_raise
|
||||
ipns.side_effect = self._download_raise
|
||||
maven.side_effect = self._download_raise
|
||||
fdroidserver.common.config = {'jarsigner': 'fakepath'}
|
||||
install.install_fdroid_apk(privacy_mode=True)
|
||||
download_apk.assert_not_called()
|
||||
download_fdroid_apk.assert_not_called()
|
||||
github.assert_called_once()
|
||||
ipns.assert_called_once()
|
||||
maven.assert_called_once()
|
||||
|
||||
@patch('fdroidserver.install.download_apk')
|
||||
@patch('fdroidserver.install.download_fdroid_apk')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_github')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_ipns')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_maven')
|
||||
def test_install_fdroid_apk_privacy_mode_false(
|
||||
self, maven, ipns, download_fdroid_apk, download_apk
|
||||
self, maven, ipns, github, download_fdroid_apk, download_apk
|
||||
):
|
||||
download_apk.side_effect = self._download_raise
|
||||
download_fdroid_apk.side_effect = self._download_raise
|
||||
github.side_effect = self._download_raise
|
||||
ipns.side_effect = self._download_raise
|
||||
maven.side_effect = self._download_raise
|
||||
fdroidserver.common.config = {'jarsigner': 'fakepath'}
|
||||
install.install_fdroid_apk(privacy_mode=False)
|
||||
download_apk.assert_called_once()
|
||||
download_fdroid_apk.assert_called_once()
|
||||
github.assert_called_once()
|
||||
ipns.assert_called_once()
|
||||
maven.assert_called_once()
|
||||
|
||||
@patch('fdroidserver.install.download_apk')
|
||||
@patch('fdroidserver.install.download_fdroid_apk')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_github')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_ipns')
|
||||
@patch('fdroidserver.install.download_fdroid_apk_from_maven')
|
||||
@patch('locale.getlocale', lambda: ('zh_CN', 'UTF-8'))
|
||||
def test_install_fdroid_apk_privacy_mode_locale_auto(
|
||||
self, maven, ipns, download_fdroid_apk, download_apk
|
||||
self, maven, ipns, github, download_fdroid_apk, download_apk
|
||||
):
|
||||
download_apk.side_effect = self._download_raise
|
||||
download_fdroid_apk.side_effect = self._download_raise
|
||||
github.side_effect = self._download_raise
|
||||
ipns.side_effect = self._download_raise
|
||||
maven.side_effect = self._download_raise
|
||||
fdroidserver.common.config = {'jarsigner': 'fakepath'}
|
||||
install.install_fdroid_apk(privacy_mode=None)
|
||||
download_apk.assert_not_called()
|
||||
download_fdroid_apk.assert_not_called()
|
||||
github.assert_called_once()
|
||||
ipns.assert_called_once()
|
||||
maven.assert_called_once()
|
||||
|
||||
@ -249,6 +258,11 @@ class InstallTest(unittest.TestCase):
|
||||
f = install.download_fdroid_apk_from_ipns()
|
||||
self.assertTrue(Path(f).exists())
|
||||
|
||||
@unittest.skipUnless(os.getenv('test_download_fdroid_apk'), 'requires net access')
|
||||
def test_download_fdroid_apk_from_github(self):
|
||||
f = install.download_fdroid_apk_from_github()
|
||||
self.assertTrue(Path(f).exists())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
|
Loading…
x
Reference in New Issue
Block a user