From 6aa0b34216c4c10ee7345dae88c5b445c6198a57 Mon Sep 17 00:00:00 2001 From: Emiliano Vavassori Date: Sun, 20 Mar 2022 23:57:45 +0100 Subject: [PATCH] Prima versione riscritta. --- lib/loappimage-helpers/__init__.py | 187 ----------------------- lib/loappimage-helpers/versions.py | 88 ----------- loaih/__init__.py | 230 +++++++++++++++++++++++++++++ loaih/versions.py | 76 ++++++++++ scripts/loaih-build | 42 ++++++ scripts/loaih-getversion | 102 +++---------- setup.py | 18 +++ 7 files changed, 390 insertions(+), 353 deletions(-) delete mode 100644 lib/loappimage-helpers/__init__.py delete mode 100644 lib/loappimage-helpers/versions.py create mode 100644 loaih/__init__.py create mode 100644 loaih/versions.py create mode 100644 scripts/loaih-build create mode 100644 setup.py diff --git a/lib/loappimage-helpers/__init__.py b/lib/loappimage-helpers/__init__.py deleted file mode 100644 index 1dda163..0000000 --- a/lib/loappimage-helpers/__init__.py +++ /dev/null @@ -1,187 +0,0 @@ -#!/usr/bin/env python3 - -import urllib.request -from lxml import etree -import tempfile, os, sys, glob, subprocess, shutil - -class Build(object): - LANGSTD = [ 'ar', 'de', 'en-GB', 'es', 'fr', 'it', 'ja', 'ko', 'pt', 'pt-BR', 'ru', 'zh-CN', 'zh-TW' ] - - def __init__(self, query, arch, url, downloaddir = '/var/tmp/downloads'): - """Build all versions that can be found in the indicated repo.""" - self.__query__ = query - self.__arch__ = arch - self.__url__ = url - self.__downloaddir__ = downloaddir - - # Creating a tempfile - self.__builddir__ = tempfile.mkdtemp() - self.__tarballs__ = [] - self.__appname__ = '' - self.__version__ = '' - - if self.__url__ == '-': - print("Cannot find this version for arch {arch}.".format(arch = self.__arch__)) - return False - - - def download(self): - """Downloads the contents of the URL as it was a folder.""" - - # Let's start with defining which files are to be downloaded. - # Let's explore the remote folder. - contents = etree.HTML(urllib.request.urlopen(self.__url__).read()).xpath("//td/a") - self.__tarballs__ = [ x.text for x in contents if x.text.endswith('tar.gz') ] - maintarball = self.__tarballs__[0] - main_arr = maintarball.split('_') - self.__appname__ = main_arr[0] - self.__version__ = main_arr[1] - - os.makedirs(self.__downloaddir__, exist_ok = True) - os.chdir(self.__downloaddir__) - for archive in self.__tarballs__: - # If the archive is already there, do not do anything. - if os.path.exists(os.path.join(self.__downloaddir__, archive)): - print("Archive %s is already there! Sweet" % archive) - continue - - # Download the archive - try: - urllib.request.urlretrieve(self.__url__ + archive, archive) - except: - print("Failed to download {archive}.".format(archive = archive)) - - print("Got %s." % archive) - - - def build(self): - """Building all the versions.""" - # We have 4 builds to do: - # * standard languages, no help - # * standard languages + offline help - # * all languages, no help - # * all languages + offline help - - # Preparation tasks - self.appnamedir = os.path.join(self.__builddir__, self.__appname__) - self.appimagedir = os.path.join(self.__builddir__, self.__appname__, self.__appname__ + '.AppDir') - os.makedirs(self.appimagedir, exist_ok = True) - # And then cd to the appname folder. - os.chdir(self.appnamedir) - # Download appimagetool from github - appimagetoolurl = "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-{arch}.AppImage".format(arch = self.__arch__) - urllib.request.urlretrieve(appimagetoolurl, 'appimagetool') - os.chmod('appimagetool', 0o755) - - # Run to build standard no help - self.__unpackbuild__('standard', False) - - # Run to build standard full help - self.__unpackbuild__('standard', True) - - # Build full no help - self.__unpackbuild__('full', False) - - # Full with help - self.__unpackbuild__('full', True) - - def __unpackbuild__(self, languageset = 'full', offlinehelp = False): - # We start by filtering out tarballs from the list - buildtarballs = [ self.__tarballs__[0] ] - - # Let's process standard languages and append results to the - # buildtarball - if languageset == 'standard': - for lang in Build.LANGSTD: - buildtarballs.extend([ x for x in self.__tarballs__ if ('langpack_' + lang) in x ]) - if offlinehelp: - buildtarballs.extend([ x for x in self.__tarballs__ if ('helppack_' + lang) in x ]) - else: - # In any other cases, we build with all languages - if not offlinehelp: - buildtarballs.extend([ x for x in self.__tarballs__ if 'langpack_' in x ]) - else: - # We need also all help. Let's replace buildtarball with the - # whole bunch - buildtarballs = self.__tarballs__ - - # Unpacking the tarballs - for archive in buildtarballs: - subprocess.run("tar xzf {folder}/{archive}".format(folder = self.__downloaddir__, archive = archive), shell=True) - - os.chdir(self.appnamedir) - os.makedirs(self.appimagedir, exist_ok = True) - # At this point, let's decompress the deb packages - subprocess.run("find .. -iname '*.deb' -exec dpkg -x {} . \;", shell=True, cwd=self.appimagedir) - # Changing desktop file - subprocess.run("find . -iname startcenter.desktop -exec cp {} . \;", shell=True, cwd=self.appimagedir) - appname = 'LibreOffice' if not self.__query__ == 'daily' else 'LibreOfficeDev' - subprocess.run("sed -i -e 's:^Name=.*$:Name=%s:' startcenter.desktop" % appname, shell=True, cwd=self.appimagedir) - - subprocess.run("find . -name '*startcenter.png' -path '*hicolor*48x48*' -exec cp {} . \;", shell=True, cwd=self.appimagedir) - - # Find the name of the binary called in the desktop file. - binaryname = subprocess.check_output("awk 'BEGIN { FS = \"=\" } /^Exec/ { print $2; exit }' startcenter.desktop | awk '{ print $1 }'", shell=True, cwd=self.appimagedir).decode('utf-8').strip('\n') - - bindir=os.path.join(self.appimagedir, 'usr', 'bin') - os.makedirs(bindir, exist_ok = True) - subprocess.run("find ../../opt -iname soffice -path '*program*' -exec ln -sf {} ./%s \;" % binaryname, shell=True, cwd=bindir) - - # Download AppRun from github - apprunurl = "https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-{arch}".format(arch = self.__arch__) - dest = os.path.join(self.appimagedir, 'AppRun') - urllib.request.urlretrieve(apprunurl, dest) - os.chmod(dest, 0o755) - - # Setting app version - appversion = self.__version__ + '.' + languageset - if offlinehelp: - appversion += '.help' - - # Building app - subprocess.run("VERSION={version} ./appimagetool -v ./{appname}.AppDir/".format(version = appversion, appname = self.__appname__), shell=True) - - print("Built AppImage version {version}".format(version = appversion)) - - # Cleanup phase, before new run. - for deb in glob.glob(self.appnamedir + '/*.deb'): - os.remove(deb) - subprocess.run("find . -type d -maxdepth 1 -exec rm -rf {} \+", shell=True) - - def checksums(self): - """Create checksums of the built versions.""" - os.chdir(self.appnamedir) - for appimage in glob.glob('*.AppImage'): - # See if a checksum already exist - if not os.path.exists(appimage + '.md5'): - subprocess.run("md5sum {appimage} > {appimage}.md5".format(appimage = appimage), shell=True) - - - def move(self, outdir): - """Moves built versions to definitive storage.""" - os.chdir(self.appnamedir) - subprocess.run("find . -iname '*.AppImage*' -exec cp {} %s \;" % outdir, shell=True) - - def __del__(self): - """Destructor""" - # Cleaning up build directory - shutil.rmtree(self.__builddir__) - - -if __name__ == '__main__': - # Run if it is run as a program. - # 1 -> query - # 2 -> arch - # 3 -> url - # 4 -> outdir - - if not len(sys.argv) == 5: - print("Please launch with this parameters: build.py query arch url outputdir") - sys.exit(255) - - b = Build(sys.argv[1], sys.argv[2], sys.argv[3]) - b.download() - b.build() - b.checksums() - b.move(sys.argv[4]) - del b diff --git a/lib/loappimage-helpers/versions.py b/lib/loappimage-helpers/versions.py deleted file mode 100644 index b6acdd8..0000000 --- a/lib/loappimage-helpers/versions.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -import urllib.request -from lxml import etree -from packaging.version import parse as parse_version -import re, sys, json - -ARCHIVE = "https://downloadarchive.documentfoundation.org/libreoffice/old/" -RELEASE = "https://download.documentfoundation.org/libreoffice/stable/" -DAILY = "https://dev-builds.libreoffice.org/daily/master/Linux-rpm_deb-x86_64@tb87-TDF/current/" - -def getlatestrel(basever): - """Search in downloadarchive for the latest version matching baseversion.""" - versionlist = etree.HTML(urllib.request.urlopen(ARCHIVE).read()).xpath('//td/a') - # Getting a more polished matching list - cleanlist = list(dict.fromkeys([x.text.strip('/') for x in versionlist if x.text.startswith(basever)])) - - # Sorting, then returning the last version - return sorted(cleanlist)[-1] - -def getbranchrel(branch): - """Based on branch names, get the release number.""" - basedirurl = {} - version = '' - if branch == 'daily': - basedirurl = { 'x86_64': DAILY, 'x86': '-' } - version = etree.HTML(urllib.request.urlopen(DAILY).read()).xpath('//td/a')[1].text.split('_')[1] - - return { 'version': version, 'basedirurl': basedirurl } - - versions = etree.HTML(urllib.request.urlopen(RELEASE).read()).xpath('//td/a') - index = 1 - if branch == 'still': - index = 2 - elif branch == 'fresh': - index = 3 - version = getlatestrel(versions[index].text.strip('/')) - - return { 'version': version, 'basedirurl': getbaseurl(version) } - -def getbaseurl(version): - """Returns the links based on the numeric version.""" - basediriurl = {} - url = ARCHIVE + '/' + version + '/deb/' - # x86 binaries are not anymore offered after 6.3.0. - if parse_version(version) < parse_version('6.3.0'): - basedirurl['x86'] = url + 'x86/' - else: - basedirurl['x86'] = '-' - - basedirurl['x86_64'] = url + 'x86_64/' - - return basedirurl - -if __name__ == '__main__': - # Preparing variables for outputting - version = '' - basedirurl = {} - basever = 'fresh' - - # At the end of the checks, we need a version string and a basedirurl, which - # should be a dictionaly for x86, x86_64 with the base of the directory where - # to download the files. - if len(sys.argv) > 1: - # A version has been specified. - basever = sys.argv[1] - - # Once overridden with Argv, parse the inputs - if '.' in basever: - # Numbered version. Let's check it is a 4 dotted release - if len(basever.split('.')) == 4: - version = basever - else: - version = getlatestrel(basever) - - basedirurl = getbaseurl(version) - else: - # String versions. - a = getbranchrel(basever) - version = a['version'] - basedirurl = a['basedirurl'] - - output = """RUNDECK:DATA: query = %s -RUNDECK:DATA: version = %s -RUNDECK:DATA: x86 = %s -RUNDECK:DATA: x86_64 = %s""" % (basever, version, basedirurl['x86'] or '-', basedirurl['x86_64']) -print(output) diff --git a/loaih/__init__.py b/loaih/__init__.py new file mode 100644 index 0000000..76afa7b --- /dev/null +++ b/loaih/__init__.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 + +import urllib.request +import loaih.versions as versions +from lxml import etree +import tempfile, os, sys, glob, subprocess, shutil + +class Build(object): + LANGSTD = [ 'ar', 'de', 'en-GB', 'es', 'fr', 'it', 'ja', 'ko', 'pt', 'pt-BR', 'ru', 'zh-CN', 'zh-TW' ] + LANGBASIC = [ 'en-GB' ] + + def __init__(self, query, arch): + """Build all versions that can be found in the indicated repo.""" + self.query = query + self.arch = arch + self.url = '' + self.language = 'basic' + self.offline_help = False + self.portable = False + self.updatable = True + self.storage_path = '/srv/http/appimage.sys42.eu' + self.download_path = '/var/tmp/downloads' + + # Getting versions and so on + v = versions.BuildVersion(self.query) + + # Building expected AppImageName + languagepart = "." + if ',' in self.language: + languagepart += self.language.replace(',', '-') + + self.appimagefilename['x86'] = 'LibreOffice' if not self.query == 'daily' else 'LibreOfficeDev' + '-' + v.version + languagepart + '.help' if self.offline_help else '' + '-x86.AppImage' + self.appimagefilename['x86_64'] = 'LibreOffice' if not self.query == 'daily' else 'LibreOfficeDev' + '-' + v.version + languagepart + '.help' if self.offline_help else '' + '-x86_64.AppImage' + + # Creating a tempfile + self.builddir = tempfile.mkdtemp() + self.tarballs = [] + self.appname = 'LibreOffice' if not self.query == 'daily' else 'LibreOfficeDev' + self.version = v.version + self.url = v.basedirurl + self.built = False + + def check(self, storage_path): + """Checking if the requested AppImage has been already built.""" + self.storage_path = storage_path + + if self.portable: + self.storage_path += "/portable" + + for arch in self.arch: + res = subprocess.check_output("find {path} -name '{appimage}'".format( + path = self.storage_path, + appimage = self.appimagefilename[arch] + '.zsync' if self.updatable else '' + ), shell=True).decode('utf-8').strip('\n') + if len(res) > 1: + self.built = True + + if self.built: + print("The requested AppImage already exists on storage. I'll skip downloading, building and moving the results.") + + def download(self, download_path): + """Downloads the contents of the URL as it was a folder.""" + if self.built: + return + + # Let's start with defining which files are to be downloaded. + # Let's explore the remote folder. + self.download_path = download_path + + for a in self.arch: + contents = etree.HTML(urllib.request.urlopen(self.url[a]).read()).xpath("//td/a") + self.tarballs = [ x.text for x in contents if x.text.endswith('tar.gz') ] + maintarball = self.tarballs[0] + mainarr = maintarball.split('') + self.appname = mainarr[0] + self.version = mainarr[1] + + os.makedirs(self.downloaddir, existok = True) + os.chdir(self.downloaddir) + for archive in self.tarballs: + # If the archive is already there, do not do anything. + if os.path.exists(os.path.join(self.downloaddir, archive)): + print("Archive %s is already there! Sweet" % archive) + continue + + # Download the archive + try: + urllib.request.urlretrieve(self.url + archive, archive) + except: + print("Failed to download {archive}.".format(archive = archive)) + + print("Got %s." % archive) + + def build(self): + """Building all the versions.""" + if self.built: + return + + # We have 4 builds to do: + # * standard languages, no help + # * standard languages + offline help + # * all languages, no help + # * all languages + offline help + + if self.portable and not 'portable' in self.storage_path: + self.storage_path += "/portable" + + # Incompatibilities - if portable and updatable are asked together, + # only portable will be built. + if self.portable and self.updatable: + print("Upgradable and portable options were required together. Building only portable.") + self.updatable = False + + for arch in self.arch: + # Preparation tasks + self.appnamedir = os.path.join(self.builddir, self.appname) + self.appimagedir = os.path.join(self.builddir, self.appname, self.appname + '.AppDir') + os.makedirs(self.appimagedir, exist_ok = True) + # And then cd to the appname folder. + os.chdir(self.appnamedir) + # Download appimagetool from github + appimagetoolurl = "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-{arch}.AppImage".format(arch = arch) + urllib.request.urlretrieve(appimagetoolurl, 'appimagetool') + os.chmod('appimagetool', 0o755) + + # Build the requested version. + self.__unpackbuild__() + + def __unpackbuild__(self, languageset = 'full', offlinehelp = False): + # We start by filtering out tarballs from the list + buildtarballs = [ self.__tarballs__[0] ] + + # Let's process standard languages and append results to the + # buildtarball + if self.language == 'basic': + buildtarballs.extend([ x for x in self.tarballs if 'langpack_en-GB' in x]) + if self.offline_help: + buildtarballs.extend([ x for x in self.tarballs if 'helppack_en-GB' in x ]) + if self.language == 'standard': + for lang in Build.LANGSTD: + buildtarballs.extend([ x for x in self.tarballs if ('langpack' + lang) in x ]) + if self.offlinehelp: + buildtarballs.extend([ x for x in self.tarballs if ('helppack' + lang) in x ]) + else: + # In any other cases, we build with all languages + if not self.offlinehelp: + buildtarballs.extend([ x for x in self.tarballs if 'langpack' in x ]) + else: + # We need also all help. Let's replace buildtarball with the + # whole bunch + buildtarballs = self.tarballs + + # Unpacking the tarballs + for archive in buildtarballs: + subprocess.run("tar xzf {folder}/{archive}".format(folder = self.download_path, archive = archive), shell=True) + + os.chdir(self.appnamedir) + os.makedirs(self.appimagedir, exist_ok = True) + # At this point, let's decompress the deb packages + subprocess.run("find .. -iname '*.deb' -exec dpkg -x {} . \;", shell=True, cwd=self.appimagedir) + # Changing desktop file + subprocess.run("find . -iname startcenter.desktop -exec cp {} . \;", shell=True, cwd=self.appimagedir) + appname = 'LibreOffice' if not self.__query__ == 'daily' else 'LibreOfficeDev' + subprocess.run("sed -i -e 's:^Name=.*$:Name=%s:' startcenter.desktop" % appname, shell=True, cwd=self.appimagedir) + + subprocess.run("find . -name '*startcenter.png' -path '*hicolor*48x48*' -exec cp {} . \;", shell=True, cwd=self.appimagedir) + + # Find the name of the binary called in the desktop file. + binaryname = subprocess.check_output("awk 'BEGIN { FS = \"=\" } /^Exec/ { print $2; exit }' startcenter.desktop | awk '{ print $1 }'", shell=True, cwd=self.appimagedir).decode('utf-8').strip('\n') + + bindir=os.path.join(self.appimagedir, 'usr', 'bin') + os.makedirs(bindir, exist_ok = True) + subprocess.run("find ../../opt -iname soffice -path '*program*' -exec ln -sf {} ./%s \;" % binaryname, shell=True, cwd=bindir) + + # Download AppRun from github + apprunurl = "https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-{arch}".format(arch = arch) + dest = os.path.join(self.appimagedir, 'AppRun') + urllib.request.urlretrieve(apprunurl, dest) + os.chmod(dest, 0o755) + + # Setting app version + appversion = self.version + '.' + self.language if not ',' in self.language else self.language.replace(',', '-') + if self.offline_help: + appversion += '.help' + + # Building app + if self.updatable: + zsync = self.appimagefilename[arch] + '.zsync' + subprocess.run("VERSION={version} ./appimagetool -u 'zsync|{zsync}' -v ./{appname}.AppDir/".format(version = appversion, zsync = zsync, appname = self.__appname__), shell=True) + + else: + subprocess.run("VERSION={version} ./appimagetool -v ./{appname}.AppDir/".format(version = appversion, appname = self.appname), shell=True) + + print("Built AppImage version {version}".format(version = appversion)) + + # Cleanup phase, before new run. + for deb in glob.glob(self.appnamedir + '/*.deb'): + os.remove(deb) + subprocess.run("find . -type d -maxdepth 1 -exec rm -rf {} \+", shell=True) + + def checksums(self): + """Create checksums of the built versions.""" + if self.built: + return + + os.chdir(self.appnamedir) + for appimage in glob.glob('*.AppImage*'): + # See if a checksum already exist + if not os.path.exists(appimage + '.md5'): + subprocess.run("md5sum {appimage} > {appimage}.md5".format(appimage = appimage), shell=True) + + + def move(self, outdir): + """Moves built versions to definitive storage.""" + if self.built: + return + if not outdir in self.storage_path: + # Let's create an updated storage_path + if self.portable: + self.storage_path = outdir + '/portable' + else: + self.storage_path = outdir + + os.chdir(self.appnamedir) + subprocess.run("find . -iname '*.AppImage*' -exec cp {} %s \;" % self.storage_path, shell=True) + + def __del__(self): + """Destructor""" + # Cleaning up build directory + shutil.rmtree(self.builddir) diff --git a/loaih/versions.py b/loaih/versions.py new file mode 100644 index 0000000..7def95d --- /dev/null +++ b/loaih/versions.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import urllib.request +from lxml import etree +from packaging.version import parse as parse_version + +class BuildVersion(object): + ARCHIVE = "https://downloadarchive.documentfoundation.org/libreoffice/old/" + RELEASE = "https://download.documentfoundation.org/libreoffice/stable/" + DAILY = "https://dev-builds.libreoffice.org/daily/master/Linux-rpm_deb-x86_64@tb87-TDF/current/" + + def __init__(self, query): + self.query = query + self.version = '' + self.basedirurl = {} + + # Parsing the query input. + if '.' in self.query: + # Numbered self.version. Let's check it is a 4 dotted release + if len(self.query.split('.')) == 4: + self.version = self.query + else: + # If not 4 dotted, let's search for the 4 dotted version + self.version = self.__getlatestrel(self.query) + + self.basedirurl = self.__getbaseurl(self.version) + else: + # String self.versions. + a = self.__getbranchrel(self.query) + self.version = a['version'] + self.basedirurl = a['basedirurl'] + + def __getlatestrel(self, basever): + """Search in downloadarchive for the latest version matching baseversion.""" + versionlist = etree.HTML(urllib.request.urlopen(BuildVersion.ARCHIVE).read()).xpath('//td/a') + # Getting a more polished matching list + cleanlist = list(dict.fromkeys([x.text.strip('/') for x in versionlist if x.text.startswith(basever)])) + + # Sorting, then returning the last version + return sorted(cleanlist)[-1] + + def __getbranchrel(self, branch): + """Based on branch names, get the release number.""" + basedirurl = {} + version = '' + if branch == 'daily': + basedirurl = { 'x86_64': BuildVersion.DAILY, 'x86': '-' } + version = etree.HTML(urllib.request.urlopen(BuildVersion.DAILY).read()).xpath('//td/a')[1].text.split('_')[1] + + return { 'version': version, 'basedirurl': basedirurl } + + versions = etree.HTML(urllib.request.urlopen(BuildVersion.RELEASE).read()).xpath('//td/a') + index = 1 + if branch == 'still': + index = 2 + elif branch == 'fresh': + index = 3 + version = self.__getlatestrel(versions[index].text.strip('/')) + + return { 'version': version, 'basedirurl': self.__getbaseurl(version) } + + def __getbaseurl(self, version): + """Returns the links based on the numeric version.""" + basedirurl = {} + url = BuildVersion.ARCHIVE + '/' + version + '/deb/' + + # x86 binaries are not anymore offered after 6.3.0. + if parse_version(version) < parse_version('6.3.0'): + basedirurl['x86'] = url + 'x86/' + else: + basedirurl['x86'] = '-' + + basedirurl['x86_64'] = url + 'x86_64/' + + return basedirurl diff --git a/scripts/loaih-build b/scripts/loaih-build new file mode 100644 index 0000000..8392b37 --- /dev/null +++ b/scripts/loaih-build @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import click +import loaih + +@click.command() +@click.option('-a', '--arch', 'arch', type=click.Choice(['x86', 'x86_64', 'all'], case_sensitive=False), default='all', help="Build the AppImage for a specific architecture. If there is no specific options, the process will build for both architectures (if available). Default: all") +@click.option('-l', '--language', 'language', default = 'basic', type=str, help="Languages to be included. Options: basic, standard, full, a language string (e.g. 'it') or a list of languages comma separated (e.g.: 'en-US,en-GB,it'). Default: basic") +@click.option('-o/-O', '--offline-help/--no-offline-help', 'offline', default = False, help="Include or not the offline help for the chosen languages. Default: no offline help") +@click.option('-p/-P', '--portable/--no-portable', 'portable', default = False, help="Create a portable version of the AppImage or not. Default: no portable") +@click.option('-u/-U', '--updatable/--no-updatable', 'updatable', default = True, help="Create an updatable version of the AppImage or not. Default: updatable") +@click.option('-d', '--download-path', 'download', default = '/var/tmp/downloads', type=str, help="Path to the download folder. Default: /var/tmp/downloads") +@click.option('-s', '--storage-path', 'storage', default = '/srv/http/appimage.sys42.eu', type=str, help="Path to the final storage of the AppImage. Default: /srv/http/appimage.sys42.eu") +@click.option('-c/-C', '--check/--no-check', 'check', default=True, help="Check in the final storage if the queried version is existent. Default: check") +@click.argument('query') +def build(arch, language, offline, portable, updatable, download, storage, check, query): + # Parsing options + if arch.lower() == 'all': + # We need to build it twice. + arches = [ 'x86', 'x86_64' ] + else: + arches = [ arch.lower() ] + + for arch in arches: + obj = loaih.build(query, arch) + + obj.language = language + obj.offline_help = offlinehelp + obj.portable = portable + obj.updatable = updatable + + if check: + obj.check(storage) + obj.download(download) + obj.build() + obj.checksums() + obj.move(storage) + del obj + +if __name__ == '__main__': + build() diff --git a/scripts/loaih-getversion b/scripts/loaih-getversion index b6acdd8..59d03ae 100644 --- a/scripts/loaih-getversion +++ b/scripts/loaih-getversion @@ -1,88 +1,34 @@ #!/usr/bin/env python # encoding: utf-8 -import urllib.request -from lxml import etree -from packaging.version import parse as parse_version +import click +from loaih.versions import BuildVersion import re, sys, json -ARCHIVE = "https://downloadarchive.documentfoundation.org/libreoffice/old/" -RELEASE = "https://download.documentfoundation.org/libreoffice/stable/" -DAILY = "https://dev-builds.libreoffice.org/daily/master/Linux-rpm_deb-x86_64@tb87-TDF/current/" +@click.command() +@click.option('-o', '--output', default = 'rundeck', type=click.Choice(['rundeck', 'json', 'text' ], case_sensitive=False), help="Output format, defaulting to Rundeck Key/Value data format. Options: rundeck,json,text") +@click.argument('query') +def getversion(query, output): + b = BuildVersion(query) -def getlatestrel(basever): - """Search in downloadarchive for the latest version matching baseversion.""" - versionlist = etree.HTML(urllib.request.urlopen(ARCHIVE).read()).xpath('//td/a') - # Getting a more polished matching list - cleanlist = list(dict.fromkeys([x.text.strip('/') for x in versionlist if x.text.startswith(basever)])) - - # Sorting, then returning the last version - return sorted(cleanlist)[-1] - -def getbranchrel(branch): - """Based on branch names, get the release number.""" - basedirurl = {} - version = '' - if branch == 'daily': - basedirurl = { 'x86_64': DAILY, 'x86': '-' } - version = etree.HTML(urllib.request.urlopen(DAILY).read()).xpath('//td/a')[1].text.split('_')[1] - - return { 'version': version, 'basedirurl': basedirurl } - - versions = etree.HTML(urllib.request.urlopen(RELEASE).read()).xpath('//td/a') - index = 1 - if branch == 'still': - index = 2 - elif branch == 'fresh': - index = 3 - version = getlatestrel(versions[index].text.strip('/')) - - return { 'version': version, 'basedirurl': getbaseurl(version) } - -def getbaseurl(version): - """Returns the links based on the numeric version.""" - basediriurl = {} - url = ARCHIVE + '/' + version + '/deb/' - # x86 binaries are not anymore offered after 6.3.0. - if parse_version(version) < parse_version('6.3.0'): - basedirurl['x86'] = url + 'x86/' + if output.lower() == 'rundeck': + print("""RUNDECK:DATA: query = {query} +RUNDECK:DATA: version = {version} +RUNDECK:DATA: x86 = {x86_url} +RUNDECK:DATA: x86_64 = {x86_64_url}""".format(query = query, version = b.version, x86_url = b.basedirurl['x86'], x86_64_url = b.basedirurl['x86_64'])) + elif output.lower() == 'json': + output = { + 'query': query, + 'version': b.version, + 'basedirurl': b.basedirurl + } + print(json.dumps(output)) else: - basedirurl['x86'] = '-' - - basedirurl['x86_64'] = url + 'x86_64/' + print("""query: {query} +version: {version} +x86: {x86_url} +x86_64: {x86_64_url}""".format(query = query, version = b.version, x86_url = b.basedirurl['x86'], x86_64_url = b.basedirurl['x86_64'])) - return basedirurl if __name__ == '__main__': - # Preparing variables for outputting - version = '' - basedirurl = {} - basever = 'fresh' - - # At the end of the checks, we need a version string and a basedirurl, which - # should be a dictionaly for x86, x86_64 with the base of the directory where - # to download the files. - if len(sys.argv) > 1: - # A version has been specified. - basever = sys.argv[1] - - # Once overridden with Argv, parse the inputs - if '.' in basever: - # Numbered version. Let's check it is a 4 dotted release - if len(basever.split('.')) == 4: - version = basever - else: - version = getlatestrel(basever) - - basedirurl = getbaseurl(version) - else: - # String versions. - a = getbranchrel(basever) - version = a['version'] - basedirurl = a['basedirurl'] - - output = """RUNDECK:DATA: query = %s -RUNDECK:DATA: version = %s -RUNDECK:DATA: x86 = %s -RUNDECK:DATA: x86_64 = %s""" % (basever, version, basedirurl['x86'] or '-', basedirurl['x86_64']) -print(output) + getversion() diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..0f9a07d --- /dev/null +++ b/setup.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# encoding: utf-8 +# vim:sts=4:sw=4 + +from setuptools import setup,find_packages + +setup( + name="loaih", + version="1.0.0", + description="LOAIH - LibreOffice AppImage Helpers, help build a LibreOffice AppImage", + author="Emiliano Vavassori", + author_email="syntaxerrormmm@libreoffice.org", + packages=find_packages(exclude=['contrib', 'docs', 'tests']), + scripts=[ 'scripts/loaih-getversion', 'scripts/loaih-build' ], + install_requires=[ 'click', ], + license='MIT', + url='https://git.libreitalia.org/LibreItalia/loappimage-helpers/', +)