From: Daniel Martí Date: Sun, 4 Oct 2015 07:03:02 +0000 (-0700) Subject: Add basic yaml metadata writing X-Git-Tag: 0.5.0~60 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=1aa891c4fda45662b249e37bdc5d04199c9cd71f;p=fdroidserver.git Add basic yaml metadata writing --- diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 1e3e7639..26be3139 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -369,10 +369,10 @@ def read_app_args(args, allapps, allow_vercodes=False): def get_extension(filename): - _, ext = os.path.splitext(filename) + base, ext = os.path.splitext(filename) if not ext: - return '' - return ext.lower()[1:] + return base, '' + return base, ext.lower()[1:] def has_extension(filename, ext): diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index da6970f6..61ceeca5 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -877,8 +877,6 @@ def parse_txt_metadata(apps, metadatapath): value = pv == 'yes' if value: thisbuild[pk] = True - else: - logging.debug("...ignoring bool flag %s" % p) else: raise MetaDataException("Unrecognised build flag type '%s' at %s in %s" @@ -1038,23 +1036,89 @@ def parse_txt_metadata(apps, metadatapath): return (appid, thisinfo) +def write_metadata(mf, app, w_comment, w_field, w_build): + + def w_field_nonempty(field, value=None): + if value is None: + value = app[field] + if value: + w_field(field, value) + + w_field_nonempty('Disabled') + if app['AntiFeatures']: + w_field('AntiFeatures') + w_field_nonempty('Provides') + w_field('Categories') + w_field('License') + w_field('Web Site') + w_field('Source Code') + w_field('Issue Tracker') + w_field_nonempty('Changelog') + w_field_nonempty('Donate') + w_field_nonempty('FlattrID') + w_field_nonempty('Bitcoin') + w_field_nonempty('Litecoin') + mf.write('\n') + w_field_nonempty('Name') + w_field_nonempty('Auto Name') + w_field('Summary') + w_field('Description', description_txt(app['Description'])) + mf.write('\n') + if app['Requires Root']: + w_field('Requires Root', 'yes') + mf.write('\n') + if app['Repo Type']: + w_field('Repo Type') + w_field('Repo') + if app['Binaries']: + w_field('Binaries') + mf.write('\n') + + for build in sorted_builds(app['builds']): + + if build['version'] == "Ignore": + continue + + w_comment('build:' + build['vercode']) + w_build(build) + mf.write('\n') + + if app['Maintainer Notes']: + w_field('Maintainer Notes', app['Maintainer Notes']) + mf.write('\n') + + w_field_nonempty('Archive Policy') + w_field('Auto Update Mode') + w_field('Update Check Mode') + w_field_nonempty('Update Check Ignore') + w_field_nonempty('Vercode Operation') + w_field_nonempty('Update Check Name') + w_field_nonempty('Update Check Data') + if app['Current Version']: + w_field('Current Version') + w_field('Current Version Code') + mf.write('\n') + if app['No Source Since']: + w_field('No Source Since') + mf.write('\n') + w_comment(None) + + # Write a metadata file in txt format. # # 'mf' - Writer interface (file, StringIO, ...) # 'app' - The app data def write_txt_metadata(mf, app): - def writecomments(key): + def w_comment(key): written = 0 for pf, comment in app['comments']: if pf == key: mf.write("%s\n" % comment) written += 1 - if written > 0: - logging.debug("...writing comments for " + (key or 'EOF')) - def writefield(field, value=None): - writecomments(field) + def w_field(field, value=None): + w_comment(field) if value is None: value = app[field] t = metafieldtype(field) @@ -1067,96 +1131,84 @@ def write_txt_metadata(mf, app): value = '\n' + value + '\n.' mf.write("%s:%s\n" % (field, value)) - def writefield_nonempty(field, value=None): - if value is None: - value = app[field] - if value: - writefield(field, value) - - writefield_nonempty('Disabled') - if app['AntiFeatures']: - writefield('AntiFeatures') - writefield_nonempty('Provides') - writefield('Categories') - writefield('License') - writefield('Web Site') - writefield('Source Code') - writefield('Issue Tracker') - writefield_nonempty('Changelog') - writefield_nonempty('Donate') - writefield_nonempty('FlattrID') - writefield_nonempty('Bitcoin') - writefield_nonempty('Litecoin') - mf.write('\n') - writefield_nonempty('Name') - writefield_nonempty('Auto Name') - writefield('Summary') - writefield('Description', description_txt(app['Description'])) - mf.write('\n') - if app['Requires Root']: - writefield('Requires Root', 'yes') - mf.write('\n') - if app['Repo Type']: - writefield('Repo Type') - writefield('Repo') - if app['Binaries']: - writefield('Binaries') - mf.write('\n') - for build in sorted_builds(app['builds']): - - if build['version'] == "Ignore": - continue - - writecomments('build:' + build['vercode']) + def w_build(build): mf.write("Build:%s,%s\n" % (build['version'], build['vercode'])) - def write_builditem(key, value): - - if key in ['version', 'vercode']: - return - + for key in flag_defaults: + value = build[key] + if not value: + continue if value == flag_defaults[key]: - return + continue t = flagtype(key) - - logging.debug("...writing {0} : {1}".format(key, value)) - outline = ' %s=' % key - + v = ' %s=' % key if t == 'string': - outline += value + v += value elif t == 'bool': - outline += 'yes' + v += 'yes' elif t == 'script': - outline += '&& \\\n '.join([s.lstrip() for s in value.split('&& ')]) + v += '&& \\\n '.join([s.lstrip() for s in value.split('&& ')]) elif t == 'list': - outline += ','.join(value) if type(value) == list else value + v += ','.join(value) if type(value) == list else value - outline += '\n' - mf.write(outline) + mf.write(v) + mf.write('\n') - for flag in flag_defaults: - value = build[flag] - if value: - write_builditem(flag, value) - mf.write('\n') + write_metadata(mf, app, w_comment, w_field, w_build) - if app['Maintainer Notes']: - writefield('Maintainer Notes', app['Maintainer Notes']) - mf.write('\n') - writefield_nonempty('Archive Policy') - writefield('Auto Update Mode') - writefield('Update Check Mode') - writefield_nonempty('Update Check Ignore') - writefield_nonempty('Vercode Operation') - writefield_nonempty('Update Check Name') - writefield_nonempty('Update Check Data') - if app['Current Version']: - writefield('Current Version') - writefield('Current Version Code') - mf.write('\n') - if app['No Source Since']: - writefield('No Source Since') - mf.write('\n') - writecomments(None) +def write_yaml_metadata(mf, app): + + def w_comment(key): + pass + + def w_field(field, value=None, prefix='', t=None): + w_comment(field) + if value is None: + value = app[field] + if t is None: + t = metafieldtype(field) + v = '' + if t == 'list': + v = '\n' + for e in value: + v += prefix + ' - ' + e + '\n' + elif t == 'multiline': + v = ' |\n' + lines = [] + if type(value) == list: + lines = value + else: + lines = value.splitlines() + for l in lines: + if l: + v += prefix + ' ' + l + '\n' + else: + v += '\n' + else: + v = ' ' + value + '\n' + + mf.write("%s%s:%s" % (prefix, field, v)) + + global first_build + first_build = True + + def w_build(build): + global first_build + if first_build: + mf.write("builds:\n") + first_build = False + + w_field('versionName', build['version'], ' - ', 'string') + w_field('versionCode', build['vercode'], ' ', 'strsng') + for key in flag_defaults: + value = build[key] + if not value: + continue + if value == flag_defaults[key]: + continue + + w_field(key, value, ' ', flagtype(key)) + + write_metadata(mf, app, w_comment, w_field, w_build) diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 1fe766cb..9c6fe62c 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -19,6 +19,7 @@ # along with this program. If not, see . from argparse import ArgumentParser +import sys import logging import StringIO @@ -38,6 +39,8 @@ def main(): common.setup_global_opts(parser) parser.add_argument("-l", "--list", action="store_true", default=False, help="List files that would be reformatted") + parser.add_argument("-t", "--to", default='txt', + help="Rewrite to a specific format") parser.add_argument("appid", nargs='*', help="app-id in the form APPID") options = parser.parse_args() @@ -47,12 +50,14 @@ def main(): allapps = metadata.read_metadata(xref=True) apps = common.read_app_args(options.appid, allapps, False) + if options.list and options.to: + parser.error("Cannot use --list and --to at the same time") + for appid, app in apps.iteritems(): metadatapath = app['metadatapath'] - ext = common.get_extension(metadatapath) - if ext not in ['txt']: - logging.info("Ignoring %s file at '%s'" - % (ext.upper(), metadatapath)) + base, ext = common.get_extension(metadatapath) + if not options.to and ext not in ['txt', 'yaml']: + logging.info("Ignoring %s file at '%s'" % (ext, metadatapath)) continue logging.debug("Rewriting " + metadatapath) if options.list: @@ -66,9 +71,16 @@ def main(): s.close() if content != cur_content: print(metadatapath) - else: - with open(metadatapath, 'w') as f: + continue + + if options.to == 'txt': + with open(base+'.txt', 'w') as f: metadata.write_txt_metadata(f, app) + elif options.to == 'yaml': + # with open(base+'.yaml', 'w') as f: + # metadata.write_yaml_metadata(f, app) + metadata.write_yaml_metadata(sys.stdout, app) + break logging.debug("Finished.")