From d10ae4ee26c83cad5a86bcfc5bda8634f1d049d0 Mon Sep 17 00:00:00 2001 From: Ian Leonard Date: Sat, 20 May 2023 14:33:39 -0400 Subject: [PATCH 1/3] releases.py: add --legacy for old-style format Signed-off-by: Ian Leonard --- releases.py | 48 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/releases.py b/releases.py index b3f34c4..e14c09f 100755 --- a/releases.py +++ b/releases.py @@ -359,7 +359,10 @@ def UpdateFile(self): # Add train data to json for train in trains: - self.update_json[train] = {'canary': CANARY_PERIOD, 'url': url} + if args.legacy: + self.update_json[train] = {'url': url} + else: + self.update_json[train] = {'canary': CANARY_PERIOD, 'url': url} self.update_json[train]['prettyname_regex'] = self._prettyname self.update_json[train]['project'] = {} @@ -396,7 +399,10 @@ def UpdateFile(self): # *.tar if release_file[0].endswith('.tar'): uboot = [] - entry['file'] = {'name': release_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': release_file[6], 'subpath': file_subpath} + if args.legacy: + entry['file'] = {'name': release_file[0], 'sha256': file_digest, 'size': file_size} + else: + entry['file'] = {'name': release_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': release_file[6], 'subpath': file_subpath} list_of_files.remove(release_file) list_of_filenames.remove(release_file[0]) # check for image files with same base name to add @@ -407,7 +413,10 @@ def UpdateFile(self): # don't combine lchops; generates incorrect file_subpath for files not in subdir file_subpath = self.lchop(image_file[5], self._indir) file_subpath = self.lchop(file_subpath, '/') - entry['image'] = {'name': image_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': image_file[6], 'subpath': file_subpath} + if args.legacy: + entry['image'] = {'name': image_file[0], 'sha256': file_digest, 'size': file_size} + else: + entry['image'] = {'name': image_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': image_file[6], 'subpath': file_subpath} list_of_files.remove(image_file) list_of_filenames.remove(image_file[0]) # tar goes to a device using uboot image files @@ -419,7 +428,10 @@ def UpdateFile(self): # don't combine lchops; generates incorrect file_subpath for files not in subdir file_subpath = self.lchop(uboot_file[5], self._indir) file_subpath = self.lchop(file_subpath, '/') - uboot.append({'name': uboot_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': uboot_file[6], 'subpath': file_subpath}) + if args.legacy: + uboot.append({'name': uboot_file[0], 'sha256': file_digest, 'size': file_size}) + else: + uboot.append({'name': uboot_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': uboot_file[6], 'subpath': file_subpath}) list_of_files.remove(uboot_file) list_of_filenames.remove(uboot_file[0]) if uboot: @@ -429,7 +441,10 @@ def UpdateFile(self): # XXX: Quirk for LE 9.0: Skip uboot image inclusion as they weren't used in that release but generated images will be swept up in search. elif release_file[4] and train != 'LibreELEC-9.0': uboot = [] - uboot.append({'name': release_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': release_file[6], 'subpath': file_subpath}) + if args.legacy: + uboot.append({'name': release_file[0], 'sha256': file_digest, 'size': file_size}) + else: + uboot.append({'name': release_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': release_file[6], 'subpath': file_subpath}) list_of_files.remove(release_file) list_of_filenames.remove(release_file[0]) # check for similar uboot releases @@ -442,7 +457,10 @@ def UpdateFile(self): # don't combine lchops; generates incorrect file_subpath for files not in subdir file_subpath = self.lchop(image_file[5], self._indir) file_subpath = self.lchop(file_subpath, '/') - entry['file'] = {'name': image_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': image_file[6], 'subpath': file_subpath} + if args.legacy: + entry['file'] = {'name': image_file[0], 'sha256': file_digest, 'size': file_size} + else: + entry['file'] = {'name': image_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': image_file[6], 'subpath': file_subpath} list_of_files.remove(image_file) list_of_filenames.remove(image_file[0]) # other uboot images @@ -451,14 +469,20 @@ def UpdateFile(self): # don't combine lchops; generates incorrect file_subpath for files not in subdir file_subpath = self.lchop(image_file[5], self._indir) file_subpath = self.lchop(file_subpath, '/') - uboot.append({'name': image_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': image_file[6], 'subpath': file_subpath}) + if args.legacy: + uboot.append({'name': image_file[0], 'sha256': file_digest, 'size': file_size}) + else: + uboot.append({'name': image_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': image_file[6], 'subpath': file_subpath}) list_of_files.remove(image_file) list_of_filenames.remove(image_file[0]) entry['uboot'] = uboot # *.img.gz elif release_file[0].endswith('.img.gz'): - entry['image'] = {'name': release_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': release_file[6], 'subpath': file_subpath} + if args.legacy: + entry['image'] = {'name': release_file[0], 'sha256': file_digest, 'size': file_size} + else: + entry['image'] = {'name': release_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': release_file[6], 'subpath': file_subpath} list_of_files.remove(release_file) list_of_filenames.remove(release_file[0]) # check for tarball files with same name so they may be added @@ -468,7 +492,10 @@ def UpdateFile(self): # don't combine lchops; generates incorrect file_subpath if not in subdir file_subpath = self.lchop(tarball_file[5], self._indir) file_subpath = self.lchop(file_subpath, '/') - entry['file'] = {'name': tarball_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': tarball_file[6], 'subpath': file_subpath} + if args.legacy: + entry['file'] = {'name': tarball_file[0], 'sha256': file_digest, 'size': file_size} + else: + entry['file'] = {'name': tarball_file[0], 'sha256': file_digest, 'size': file_size, 'timestamp': tarball_file[6], 'subpath': file_subpath} list_of_files.remove(tarball_file) list_of_filenames.remove(tarball_file[0]) @@ -545,6 +572,9 @@ def WriteFile(self): help=f'Directory to parsed (release files, and any existing {JSON_FILE}). By default, {JSON_FILE} will be ' \ 'written into this directory. Required property.') +parser.add_argument('-l', '--legacy', action='store_true', \ + help='Generate legacy formatted json') + parser.add_argument('-u', '--url', metavar='URL', required=True, \ help=f'Base URL for {JSON_FILE}. Required property.') From 18a24a70a51d06ed490581586c0a9e92d320d956 Mon Sep 17 00:00:00 2001 From: Ian Leonard Date: Sat, 20 May 2023 14:38:35 -0400 Subject: [PATCH 2/3] releases.py: fix indent Signed-off-by: Ian Leonard --- releases.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/releases.py b/releases.py index e14c09f..2e78423 100755 --- a/releases.py +++ b/releases.py @@ -66,10 +66,10 @@ def hash_bytestr_iter(bytesiter, hasher, ashexstr=True): @staticmethod def file_as_blockiter(afile, blocksize=65536): with afile: - block = afile.read(blocksize) - while len(block) > 0: - yield block - block = afile.read(blocksize) + block = afile.read(blocksize) + while len(block) > 0: + yield block + block = afile.read(blocksize) # Calculate sha256 hash for a file @staticmethod From 15f350b0c37582152ebabab9429151c3f21eb65b Mon Sep 17 00:00:00 2001 From: Ian Leonard Date: Sat, 20 May 2023 14:55:07 -0400 Subject: [PATCH 3/3] releases.py: permit taking json name as cli argument Signed-off-by: Ian Leonard --- releases.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/releases.py b/releases.py index 2e78423..766b65e 100755 --- a/releases.py +++ b/releases.py @@ -48,7 +48,6 @@ ] BUILDS_PER_DEVICE=10 -JSON_FILE = 'releases.json' DISTRO_NAME = 'LibreELEC' CANARY_PERIOD = 21 # Days PRETTYNAME = f'^{DISTRO_NAME}-.*-([0-9]+\.[0-9]+\.[0-9]+)' @@ -94,7 +93,7 @@ def rchop(self, s, suffix): return s def __init__(self, args): - self._json_file = JSON_FILE + self._json_file = args.json if args.json else 'releases.json' self._indir = self.rchop(args.input, os.path.sep) self._url = self.rchop(args.url, '/') self._outdir = self.rchop(args.output, os.path.sep) if args.output else self._indir @@ -565,25 +564,28 @@ def WriteFile(self): VERSIONS = _ -parser = argparse.ArgumentParser(description=f'Update {DISTRO_NAME} {JSON_FILE} with available tar/img.gz files.', \ +parser = argparse.ArgumentParser(description=f'Update {DISTRO_NAME} release json file with available tar/img.gz files.', \ formatter_class=lambda prog: argparse.HelpFormatter(prog,max_help_position=25,width=90)) parser.add_argument('-i', '--input', metavar='DIRECTORY', required=True, \ - help=f'Directory to parsed (release files, and any existing {JSON_FILE}). By default, {JSON_FILE} will be ' \ - 'written into this directory. Required property.') + help=f'Directory to parsed (release files, and any existing json file (with the same name). By default, ' \ + 'the json file will be written into this directory. Required property.') + +parser.add_argument('-j', '--json', metavar='JSONNAME', required=False, \ + help='Filename of generated json file.') parser.add_argument('-l', '--legacy', action='store_true', \ help='Generate legacy formatted json') -parser.add_argument('-u', '--url', metavar='URL', required=True, \ - help=f'Base URL for {JSON_FILE}. Required property.') - parser.add_argument('-o', '--output', metavar='DIRECTORY', required=False, \ - help=f'Optional directory into which {JSON_FILE} will be written. Defaults to same directory as --input.') + help=f'Optional directory into which json file will be written. Defaults to same directory as --input.') parser.add_argument('-p', '--prettyname', metavar='REGEX', required=False, \ help=f'Optional prettyname regex, default is {PRETTYNAME}') +parser.add_argument('-u', '--url', metavar='URL', required=True, \ + help=f'Base URL for json file. Required property.') + parser.add_argument('-v', '--verbose', action="store_true", help='Enable verbose output (ignored files etc.)') args = parser.parse_args()