From: Hans-Christoph Steiner Date: Tue, 21 Jul 2015 18:50:49 +0000 (-0700) Subject: support app metadata in JSON format X-Git-Tag: 0.5.0~140^2~19 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=84c9777e9e586e9a52325178b9f8b4d278f9e5fa;p=fdroidserver.git support app metadata in JSON format While the current text metadata format is good for human readability and editability, it is difficult to produce and parse using code. JSON is a widespread standard format for easy automatic parsing and creating, while having decent human readability. --- diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 83bdbc4e..c9a39dc7 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -17,6 +17,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import json import os import re import glob @@ -488,6 +489,11 @@ def read_metadata(xref=True): check_metadata(appinfo) apps[appid] = appinfo + for metafile in sorted(glob.glob(os.path.join('metadata', '*.json'))): + appid, appinfo = parse_json_metadata(metafile) + check_metadata(appinfo) + apps[appid] = appinfo + if xref: # Parse all descriptions at load time, just to ensure cross-referencing # errors are caught early rather than when they hit the build server. @@ -595,6 +601,56 @@ def get_default_app_info_list(): # 'descriptionlines' - original lines of description as formatted in the # metadata file. # + + +def parse_json_metadata(metafile): + + appid = os.path.basename(metafile)[0:-5] # strip path and .json + thisinfo = get_default_app_info_list() + thisinfo['id'] = appid + + # fdroid metadata is only strings and booleans, no floats or ints. And + # json returns unicode, and fdroidserver still uses plain python strings + jsoninfo = json.load(open(metafile, 'r'), + parse_int=lambda s: s, + parse_float=lambda s: s) + supported_metadata = app_defaults.keys() + ['builds', 'comments'] + for k, v in jsoninfo.iteritems(): + if k == 'Requires Root': + if isinstance(v, basestring): + if re.match('^\s*(yes|true).*', v, flags=re.IGNORECASE): + jsoninfo[k] = 'Yes' + elif re.match('^\s*(no|false).*', v, flags=re.IGNORECASE): + jsoninfo[k] = 'No' + if isinstance(v, bool): + if v: + jsoninfo[k] = 'Yes' + else: + jsoninfo[k] = 'No' + if k not in supported_metadata: + logging.warn(metafile + ' contains unknown metadata key, ignoring: ' + k) + thisinfo.update(jsoninfo) + + for build in thisinfo['builds']: + for k, v in build.iteritems(): + if k in ('buildjni', 'gradle', 'maven', 'kivy'): + # convert standard types to mixed datatype legacy format + if isinstance(v, bool): + if v: + build[k] = ['yes'] + else: + build[k] = ['no'] + elif k == 'versionCode': + build['vercode'] = v + del build['versionCode'] + elif k == 'versionName': + build['version'] = v + del build['versionName'] + + # TODO create schema using https://pypi.python.org/pypi/jsonschema + return (appid, thisinfo) + + def parse_txt_metadata(metafile): appid = None