if k == 'builds':
d['builds'] = []
for build in v:
- d['builds'].append(build.__dict__)
- else:
- k = App.attr_to_field(k)
- d[k] = v
+ b = {k: v for k, v in build.__dict__.iteritems() if not k.startswith('_')}
+ d['builds'].append(b)
+ elif not k.startswith('_'):
+ f = App.attr_to_field(k)
+ d[f] = v
return d
# Gets the value associated to a field name, e.g. 'Auto Name'
self.submodules = False
self.init = ''
self.patch = []
- self.gradle = False
+ self.gradle = []
self.maven = False
self.kivy = False
self.output = None
self.rm = []
self.extlibs = []
self.prebuild = ''
- self.update = None
+ self.update = []
self.target = None
self.scanignore = []
self.scandelete = []
self.ndk = None
self.preassemble = []
self.gradleprops = []
- self.antcommands = None
+ self.antcommands = []
self.novcheck = False
self._modified = set()
FieldValidator("HTTP link",
r'^http[s]?://', None,
- ["Web Site", "Source Code", "Issue Tracker", "Changelog", "Donate"], []),
+ ["WebSite", "SourceCode", "IssueTracker", "Changelog", "Donate"], []),
FieldValidator("Bitcoin address",
r'^[a-zA-Z0-9]{27,34}$', None,
FieldValidator("Repo Type",
['git', 'git-svn', 'svn', 'hg', 'bzr', 'srclib'], None,
- ["Repo Type"],
+ ["RepoType"],
[]),
FieldValidator("Binaries",
FieldValidator("Archive Policy",
r'^[0-9]+ versions$', None,
- ["Archive Policy"],
+ ["ArchivePolicy"],
[]),
FieldValidator("Anti-Feature",
FieldValidator("Auto Update Mode",
r"^(Version .+|None)$", None,
- ["Auto Update Mode"],
+ ["AutoUpdateMode"],
[]),
FieldValidator("Update Check Mode",
r"^(Tags|Tags .+|RepoManifest|RepoManifest/.+|RepoTrunk|HTTP|Static|None)$", None,
- ["Update Check Mode"],
+ ["UpdateCheckMode"],
[])
}
# Check an app's metadata information for integrity errors
def check_metadata(app):
for v in valuetypes:
- for f in v.fields:
- v.check(app.get_field(f), app.id)
+ for k in v.fields:
+ if k not in app._modified:
+ continue
+ v.check(app.__dict__[k], app.id)
for build in app.builds:
- for f in v.flags:
- v.check(build.get_flag(f), app.id)
+ for k in v.flags:
+ if k not in build._modified:
+ continue
+ v.check(build.__dict__[k], app.id)
# Formatter for descriptions. Create an instance, and call parseline() with
raise MetaDataException('"%s" is not an accepted format, convert to: %s' % (
metadatapath, ', '.join(accepted)))
- app = None
- if ext == 'txt':
- app = parse_txt_metadata(metadatapath)
- elif ext == 'json':
- app = parse_json_metadata(metadatapath)
- elif ext == 'xml':
- app = parse_xml_metadata(metadatapath)
- elif ext == 'yaml':
- app = parse_yaml_metadata(metadatapath)
- else:
- raise MetaDataException('Unknown metadata format: %s' % metadatapath)
+ app = App()
+ app.metadatapath = metadatapath
+ app.id, _ = common.get_extension(os.path.basename(metadatapath))
+
+ with open(metadatapath, 'r') as mf:
+ if ext == 'txt':
+ parse_txt_metadata(mf, app)
+ elif ext == 'json':
+ parse_json_metadata(mf, app)
+ elif ext == 'xml':
+ parse_xml_metadata(mf, app)
+ elif ext == 'yaml':
+ parse_yaml_metadata(mf, app)
+ else:
+ raise MetaDataException('Unknown metadata format: %s' % metadatapath)
post_metadata_parse(app)
return app
-def parse_json_metadata(metadatapath):
-
- app = get_default_app_info(metadatapath)
+def parse_json_metadata(mf, app):
# fdroid metadata is only strings and booleans, no floats or ints. And
# json returns unicode, and fdroidserver still uses plain python strings
# TODO create schema using https://pypi.python.org/pypi/jsonschema
- jsoninfo = None
- with open(metadatapath, 'r') as f:
- jsoninfo = json.load(f, object_hook=_decode_dict,
- parse_int=lambda s: s,
- parse_float=lambda s: s)
+ jsoninfo = json.load(mf, object_hook=_decode_dict,
+ parse_int=lambda s: s,
+ parse_float=lambda s: s)
app.update_fields(jsoninfo)
for f in ['Description', 'Maintainer Notes']:
v = app.get_field(f)
return app
-def parse_xml_metadata(metadatapath):
+def parse_xml_metadata(mf, app):
- app = get_default_app_info(metadatapath)
-
- tree = ElementTree.ElementTree(file=metadatapath)
+ tree = ElementTree.ElementTree(file=mf)
root = tree.getroot()
if root.tag != 'resources':
return app
-def parse_yaml_metadata(metadatapath):
-
- app = get_default_app_info(metadatapath)
+def parse_yaml_metadata(mf, app):
- yamlinfo = None
- with open(metadatapath, 'r') as f:
- yamlinfo = yaml.load(f, Loader=YamlLoader)
+ yamlinfo = yaml.load(mf, Loader=YamlLoader)
app.update_fields(yamlinfo)
return app
build_cont = re.compile(r'^[ \t]')
-def parse_txt_metadata(metadatapath):
+def parse_txt_metadata(mf, app):
linedesc = None
if len(parts) < 3:
raise MetaDataException("Invalid build format: " + v + " in " + metafile.name)
build = Build()
- build.origlines = lines
build.version = parts[0]
build.vercode = parts[1]
if parts[2].startswith('!'):
app.comments[key] = list(curcomments)
del curcomments[:]
- app = get_default_app_info(metadatapath)
- metafile = open(metadatapath, "r")
-
mode = 0
buildlines = []
multiline_lines = []
vc_seen = set()
c = 0
- for line in metafile:
+ for line in mf:
c += 1
- linedesc = "%s:%d" % (metafile.name, c)
+ linedesc = "%s:%d" % (mf.name, c)
line = line.rstrip('\r\n')
if mode == 3:
if build_cont.match(line):
add_comments('build:' + app.builds[-1].vercode)
mode = 0
add_comments(None)
- metafile.close()
# Mode at end of file should always be 0
if mode == 1:
- raise MetaDataException(f + " not terminated in " + metafile.name)
+ raise MetaDataException(f + " not terminated in " + mf.name)
if mode == 2:
raise MetaDataException("Unterminated continuation in " + metafile.name)
if mode == 3: