diff --git a/src/loaih/__init__.py b/src/loaih/__init__.py index 4f15c3b..5a2d793 100644 --- a/src/loaih/__init__.py +++ b/src/loaih/__init__.py @@ -9,6 +9,8 @@ import requests import subprocess import shlex from lxml import html +from base64 import b64decode +import tomllib # Constants DOWNLOADPAGE = "https://www.libreoffice.org/download/download/" @@ -18,13 +20,21 @@ DAILY = "https://dev-builds.libreoffice.org/daily/master/" PRERELEASE = "https://dev-builds.libreoffice.org/pre-releases/deb/x86_64/" SELECTORS = { - 'still': { - 'URL': DOWNLOADPAGE, - 'xpath': '(//span[@class="dl_version_number"])[last()]/text()' + 'latest': { + 'URL': '', + 'selector': "latestMajor" }, 'fresh': { - 'URL': DOWNLOADPAGE, - 'xpath': '(//span[@class="dl_version_number"])[1]/text()' + 'URL': '', + 'selector': "latestMajor" + }, + 'previous': { + 'URL': '', + 'selector': "previousMajor" + }, + 'still': { + 'URL': '', + 'selector': "previousMajor" }, 'prerelease': { 'URL': DOWNLOADPAGE, @@ -44,6 +54,13 @@ def match_xpath(url: str, xpath: str): parsed = html.fromstring(resource.content) return parsed.xpath(xpath) +@staticmethod +def get_releases_as_dict() -> dict: + """Official releases of LO via obfuscated releses.toml.""" + RELEASE_OBFUSCATED = "https://git.libreoffice.org/infra/libreofficeorg/+/refs/heads/master/data/releases.toml?format=TEXT" + request = requests.get(RELEASE_OBFUSCATED) + return tomllib.loads(b64decode(request.text).decode('UTF-8')) + # Classes class Version(): @@ -114,7 +131,7 @@ class Solver(): solver = self if self.text in { 'current', 'yesterday', 'daily' }: solver = DailySolver(self.text, self.default_to_current) - elif self.text in { 'still', 'fresh', 'prerelease' }: + elif self.text in { 'still', 'fresh', 'prerelease', 'latest', 'previous' }: solver = NamedSolver(self.text) elif '.' in self.text: solver = NumberedSolver(self.text) @@ -217,25 +234,33 @@ class NamedSolver(Solver): def solve(self): """Get versions from query.""" - xpath_query = SELECTORS[self.text]['xpath'] - results = sorted(match_xpath(self.baseurl, xpath_query)) + + if 'selector' in SELECTORS[self.text].keys(): + # Version parsed from releases.toml. + selector = SELECTORS[self.text]['selector'] + self.generalver = get_releases_as_dict()[selector] + else: + # Release searched via xpath on URL + + xpath_query = SELECTORS[self.text]['xpath'] + results = sorted(match_xpath(self.baseurl, xpath_query)) - if len(results) > 0: - self.generalver = str(results[-1]) + if len(results) > 0: + self.generalver = str(results[-1]) - result: str = self.generalver - xpath_string = f"//td/a[starts-with(text(),'{result}')]/text()" - archived_versions = sorted(match_xpath(ARCHIVE, xpath_string)) + result: str = self.generalver + xpath_string = f"//td/a[starts-with(text(),'{result}')]/text()" + archived_versions = sorted(match_xpath(ARCHIVE, xpath_string)) - if len(archived_versions) == 0: - return self.version + if len(archived_versions) == 0: + return self.version - # Return just the last versions - fullversion: str = str(archived_versions[-1]) - self.baseurl = ARCHIVE + fullversion + 'deb/' - self.version = fullversion.rstrip('/') - if self.branch == 'prerelease': - self.baseurl = PRERELEASE + # Return just the last versions + fullversion: str = str(archived_versions[-1]) + self.baseurl = ARCHIVE + fullversion + 'deb/' + self.version = fullversion.rstrip('/') + if self.branch == 'prerelease': + self.baseurl = PRERELEASE return self.version