Represent multiline fields as str, not list

Only keep lists in metadata files in the json format, since they don't
support multiline strings that are readable.

This makes the internal code easier, and a bit faster.
This commit is contained in:
Daniel Martí 2015-12-03 11:36:15 +01:00
parent c8cc054c8b
commit 088929711c
6 changed files with 5952 additions and 6039 deletions

View file

@ -107,15 +107,16 @@ def check_regexes(app):
for f, checks in regex_checks.iteritems(): for f, checks in regex_checks.iteritems():
for m, r in checks: for m, r in checks:
v = app.get_field(f) v = app.get_field(f)
if type(v) == str: t = metadata.metafieldtype(f)
if t == 'multiline':
for l in v.splitlines():
if m.match(l):
yield "%s at line '%s': %s" % (f, l, r)
else:
if v is None: if v is None:
continue continue
if m.match(v): if m.match(v):
yield "%s '%s': %s" % (f, v, r) yield "%s '%s': %s" % (f, v, r)
elif type(v) == list:
for l in v:
if m.match(l):
yield "%s at line '%s': %s" % (f, l, r)
def get_lastbuild(builds): def get_lastbuild(builds):
@ -152,8 +153,7 @@ def check_char_limits(app):
yield "Summary of length %s is over the %i char limit" % ( yield "Summary of length %s is over the %i char limit" % (
summ_chars, limits['Summary']) summ_chars, limits['Summary'])
desc_charcount = sum(len(l) for l in app.Description) if len(app.Description) > limits['Description']:
if desc_charcount > limits['Description']:
yield "Description of length %s is over the %i char limit" % ( yield "Description of length %s is over the %i char limit" % (
desc_charcount, limits['Description']) desc_charcount, limits['Description'])
@ -244,7 +244,7 @@ def check_duplicates(app):
yield "Description '%s' is just the app's summary" % app.Summary yield "Description '%s' is just the app's summary" % app.Summary
seenlines = set() seenlines = set()
for l in app.Description: for l in app.Description.splitlines():
if len(l) < 1: if len(l) < 1:
continue continue
if l in seenlines: if l in seenlines:
@ -268,7 +268,7 @@ def check_bulleted_lists(app):
validchars = ['*', '#'] validchars = ['*', '#']
lchar = '' lchar = ''
lcount = 0 lcount = 0
for l in app.Description: for l in app.Description.splitlines():
if len(l) < 1: if len(l) < 1:
lcount = 0 lcount = 0
continue continue

View file

@ -109,12 +109,12 @@ class App():
self.Name = None self.Name = None
self.AutoName = '' self.AutoName = ''
self.Summary = '' self.Summary = ''
self.Description = [] self.Description = ''
self.RequiresRoot = False self.RequiresRoot = False
self.RepoType = '' self.RepoType = ''
self.Repo = '' self.Repo = ''
self.Binaries = None self.Binaries = None
self.MaintainerNotes = [] self.MaintainerNotes = ''
self.ArchivePolicy = None self.ArchivePolicy = None
self.AutoUpdateMode = 'None' self.AutoUpdateMode = 'None'
self.UpdateCheckMode = 'None' self.UpdateCheckMode = 'None'
@ -623,9 +623,9 @@ class DescriptionFormatter:
# Parse multiple lines of description as written in a metadata file, returning # Parse multiple lines of description as written in a metadata file, returning
# a single string in text format and wrapped to 80 columns. # a single string in text format and wrapped to 80 columns.
def description_txt(lines): def description_txt(s):
ps = DescriptionFormatter(None) ps = DescriptionFormatter(None)
for line in lines: for line in s.splitlines():
ps.parseline(line) ps.parseline(line)
ps.end() ps.end()
return ps.text_txt return ps.text_txt
@ -634,9 +634,9 @@ def description_txt(lines):
# Parse multiple lines of description as written in a metadata file, returning # Parse multiple lines of description as written in a metadata file, returning
# a single string in wiki format. Used for the Maintainer Notes field as well, # a single string in wiki format. Used for the Maintainer Notes field as well,
# because it's the same format. # because it's the same format.
def description_wiki(lines): def description_wiki(s):
ps = DescriptionFormatter(None) ps = DescriptionFormatter(None)
for line in lines: for line in s.splitlines():
ps.parseline(line) ps.parseline(line)
ps.end() ps.end()
return ps.text_wiki return ps.text_wiki
@ -644,9 +644,9 @@ def description_wiki(lines):
# Parse multiple lines of description as written in a metadata file, returning # Parse multiple lines of description as written in a metadata file, returning
# a single string in HTML format. # a single string in HTML format.
def description_html(lines, linkres): def description_html(s, linkres):
ps = DescriptionFormatter(linkres) ps = DescriptionFormatter(linkres)
for line in lines: for line in s.splitlines():
ps.parseline(line) ps.parseline(line)
ps.end() ps.end()
return ps.text_html return ps.text_html
@ -824,15 +824,8 @@ def post_metadata_parse(app):
if isinstance(v, bool) and v: if isinstance(v, bool) and v:
build.__dict__[k] = 'yes' build.__dict__[k] = 'yes'
# convert to the odd internal format
for f in ('Description', 'Maintainer Notes'):
v = app.get_field(f)
if isinstance(v, basestring):
text = v.rstrip().lstrip()
app.set_field(f, text.split('\n'))
if not app.Description: if not app.Description:
app.Description = ['No description available'] app.Description = 'No description available'
app.builds = sorted_builds(app.builds) app.builds = sorted_builds(app.builds)
@ -929,6 +922,9 @@ def parse_json_metadata(metadatapath):
parse_int=lambda s: s, parse_int=lambda s: s,
parse_float=lambda s: s) parse_float=lambda s: s)
app.update_fields(jsoninfo) app.update_fields(jsoninfo)
for f in ['Description', 'Maintainer Notes']:
v = app.get_field(f)
app.set_field(f, '\n'.join(v))
return app return app
@ -1047,6 +1043,7 @@ def parse_txt_metadata(metadatapath):
mode = 0 mode = 0
buildlines = [] buildlines = []
multiline_lines = []
curcomments = [] curcomments = []
build = None build = None
vc_seen = {} vc_seen = {}
@ -1134,8 +1131,10 @@ def parse_txt_metadata(metadatapath):
elif mode == 1: # Multiline field elif mode == 1: # Multiline field
if line == '.': if line == '.':
mode = 0 mode = 0
app.set_field(f, '\n'.join(multiline_lines))
del multiline_lines[:]
else: else:
app.append_field(f, line) multiline_lines.append(line)
elif mode == 2: # Line continuation mode in Build Version elif mode == 2: # Line continuation mode in Build Version
if line.endswith("\\"): if line.endswith("\\"):
buildlines.append(line[:-1]) buildlines.append(line[:-1])
@ -1253,10 +1252,7 @@ def write_txt_metadata(mf, app):
if t == 'list': if t == 'list':
v = ','.join(v) v = ','.join(v)
elif t == 'multiline': elif t == 'multiline':
if type(v) == list: v = '\n' + v + '\n.'
v = '\n' + '\n'.join(v) + '\n.'
else:
v = '\n' + v + '\n.'
mf.write("%s:%s\n" % (f, v)) mf.write("%s:%s\n" % (f, v))
def w_build(build): def w_build(build):
@ -1306,10 +1302,7 @@ def write_yaml_metadata(mf, app):
v += prefix + ' - ' + escape(e) + '\n' v += prefix + ' - ' + escape(e) + '\n'
elif t == 'multiline': elif t == 'multiline':
v = ' |\n' v = ' |\n'
lines = v for l in v.splitlines():
if type(v) == str:
lines = v.splitlines()
for l in lines:
if l: if l:
v += prefix + ' ' + l + '\n' v += prefix + ' ' + l + '\n'
else: else:

View file

@ -29,427 +29,397 @@ sS'Archive Policy'
p15 p15
NsS'Description' NsS'Description'
p16 p16
(lp17 S"Osmand~'s features can be extended by enabling the plugins via the settings,\nwhich include online maps from many sources, tracking, OpenStreetMap (OSM) editing and\naccessibility enhancements.\n\nMap data of both vector and raster types can be stored on the phone memory\ncard for offline usage, and navigation by default uses offline methods. Map\ndata packages for many territories can be downloaded from within the app and\nthere is a desktop program available on the website as well for creating your\nown.\n\nAnti-Features: Tracking - It will send your device and application specs to an\nAnalytics server upon downloading the list of maps you can download.\n\n[https://osmandapp.github.io/changes.html Changelog]\n"
S"Osmand~'s features can be extended by enabling the plugins via the settings," p17
sS'Requires Root'
p18 p18
aS'which include online maps from many sources, tracking, OpenStreetMap (OSM) editing and'
p19
aS'accessibility enhancements.'
p20
aS''
p21
aS'Map data of both vector and raster types can be stored on the phone memory'
p22
aS'card for offline usage, and navigation by default uses offline methods. Map'
p23
aS'data packages for many territories can be downloaded from within the app and'
p24
aS'there is a desktop program available on the website as well for creating your'
p25
aS'own.'
p26
ag21
aS'Anti-Features: Tracking - It will send your device and application specs to an'
p27
aS'Analytics server upon downloading the list of maps you can download.'
p28
ag21
aS'[https://osmandapp.github.io/changes.html Changelog]'
p29
asS'Requires Root'
p30
I00 I00
sS'lastupdated' sS'lastupdated'
p31 p19
NsS'id' NsS'id'
p32 p20
S'net.osmand.plus' S'net.osmand.plus'
p33 p21
sS'Repo' sS'Repo'
p34 p22
S'https://github.com/mvdan/OsmAnd-submodules' S'https://github.com/mvdan/OsmAnd-submodules'
p35 p23
sS'No Source Since' sS'No Source Since'
p36 p24
g21 S''
p25
sS'Repo Type' sS'Repo Type'
p37 p26
S'git' S'git'
p38 p27
sS'Auto Name' sS'Auto Name'
p39 p28
g21 g25
sS'Categories' sS'Categories'
p40 p29
(lp41 (lp30
S'None' S'None'
p42 p31
aS'Navigation' aS'Navigation'
p43 p32
asS'Source Code' asS'Source Code'
p44 p33
S'https://github.com/osmandapp/Osmand' S'https://github.com/osmandapp/Osmand'
p45 p34
sS'added' sS'added'
p46 p35
NsS'Update Check Ignore' NsS'Update Check Ignore'
p47 p36
NsS'Name' NsS'Name'
p48 p37
S'OsmAnd~' S'OsmAnd~'
p49 p38
sS'License' sS'License'
p50 p39
S'GPLv3' S'GPLv3'
p51 p40
sS'Changelog' sS'Changelog'
p52 p41
g21 g25
sS'Update Check Mode' sS'Update Check Mode'
p53 p42
S'None' S'None'
p54 p43
sS'Summary' sS'Summary'
p55 p44
S'Offline/online maps and navigation' S'Offline/online maps and navigation'
p56 p45
sS'Current Version' sS'Current Version'
p57 p46
S'1.9.5' S'1.9.5'
p58 p47
sS'Maintainer Notes' sS'Maintainer Notes'
p59 p48
(lp60 S"\nNo UCMs apply because git never contains actual releases, only pre-releses.\n\nThe build instructions have been moved to a script in the root of the repo,\n'build'. This way it can be updated along with the submodules.\n "
S'No UCMs apply because git never contains actual releases, only pre-releses.' p49
p61 sS'Current Version Code'
ag21 p50
aS'The build instructions have been moved to a script in the root of the repo,'
p62
aS"'build'. This way it can be updated along with the submodules."
p63
asS'Current Version Code'
p64
S'197' S'197'
p65 p51
sS'Binaries' sS'Binaries'
p66 p52
NsS'builds' NsS'builds'
p67 p53
(lp68 (lp54
(dp69 (dp55
S'submodules' S'submodules'
p70 p56
I01 I01
sS'kivy' sS'kivy'
p71 p57
I00 I00
sS'forceversion' sS'forceversion'
p72 p58
I00 I00
sS'oldsdkloc' sS'oldsdkloc'
p73 p59
I00 I00
sS'antcommands' sS'antcommands'
p74 p60
NsS'scanignore' NsS'scanignore'
p75 p61
(lp76 (lp62
sS'gradle' sS'gradle'
p77 p63
I00 I00
sS'srclibs' sS'srclibs'
p78 p64
(lp79 (lp65
sS'encoding' sS'encoding'
p80 p66
NsS'extlibs' NsS'extlibs'
p81 p67
(lp82 (lp68
sS'init' sS'init'
p83 p69
g21 g25
sS'version' sS'version'
p84 p70
S'1.8.2' S'1.8.2'
p85 p71
sS'subdir' sS'subdir'
p86 p72
S'android/OsmAnd' S'android/OsmAnd'
p87 p73
sS'rm' sS'rm'
p88 p74
(lp89 (lp75
sS'build' sS'build'
p90 p76
S'./old-ndk-build.sh && ant -Dsdk.dir="$ANDROID_SDK" -Dndk.dir="$ANDROID_NDK" -DBLACKBERRY_BUILD=false -DBUILD_SUFFIX= -DAPK_NUMBER_VERSION=182 "-DFEATURES=+play_market +gps_status -parking_plugin -blackberry -amazon -route_nav" -DCLEAN_CPP=false -DPACKAGE_TO_BUILT=net.osmand.plus -DAPK_VERSION=1.8.2 -Dnet.osmand.plus= -Dbuild.version=1.8.2 -Dbuild.version.code=182 -Dnativeoff=false "-DversionFeatures=+play_market +gps_status -parking_plugin -blackberry -amazon -route_nav" clean release' S'./old-ndk-build.sh && ant -Dsdk.dir="$ANDROID_SDK" -Dndk.dir="$ANDROID_NDK" -DBLACKBERRY_BUILD=false -DBUILD_SUFFIX= -DAPK_NUMBER_VERSION=182 "-DFEATURES=+play_market +gps_status -parking_plugin -blackberry -amazon -route_nav" -DCLEAN_CPP=false -DPACKAGE_TO_BUILT=net.osmand.plus -DAPK_VERSION=1.8.2 -Dnet.osmand.plus= -Dbuild.version=1.8.2 -Dbuild.version.code=182 -Dnativeoff=false "-DversionFeatures=+play_market +gps_status -parking_plugin -blackberry -amazon -route_nav" clean release'
p91 p77
sS'vercode' sS'vercode'
p92 p78
S'182' S'182'
p93 p79
sS'forcevercode' sS'forcevercode'
p94 p80
I00 I00
sS'preassemble' sS'preassemble'
p95 p81
(lp96 (lp82
sS'update' sS'update'
p97 p83
NsS'maven' NsS'maven'
p98 p84
I00 I00
sS'disable' sS'disable'
p99 p85
I00 I00
sS'commit' sS'commit'
p100 p86
S'76ada6c8a08afe69acb755503373ac36328ef665' S'76ada6c8a08afe69acb755503373ac36328ef665'
p101 p87
sS'scandelete' sS'scandelete'
p102 p88
(lp103 (lp89
sS'buildjni' sS'buildjni'
p104 p90
S'no' S'no'
p105 p91
sS'ndk' sS'ndk'
p106 p92
NsS'target' NsS'target'
p107 p93
NsS'gradleprops' NsS'gradleprops'
p108 p94
(lp109 (lp95
sS'patch' sS'patch'
p110 p96
(lp111 (lp97
sS'prebuild' sS'prebuild'
p112 p98
S'sed -i \'s/"OsmAnd+"/"OsmAnd~"/g\' build.xml' S'sed -i \'s/"OsmAnd+"/"OsmAnd~"/g\' build.xml'
p113 p99
sS'novcheck' sS'novcheck'
p114 p100
I00 I00
sS'output' sS'output'
p115 p101
S'bin/OsmAnd-release-unsigned.apk' S'bin/OsmAnd-release-unsigned.apk'
p116 p102
sa(dp117 sa(dp103
g70 g56
I01 I01
sg71 sg57
I00 I00
sg72 sg58
I00 I00
sg73 sg59
I00 I00
sg74 sg60
Nsg75 Nsg61
(lp118 (lp104
sg77 sg63
I00 I00
sg78 sg64
(lp119 (lp105
sg80 sg66
Nsg81 Nsg67
(lp120 (lp106
sg83 sg69
g21 g25
sg84 sg70
S'1.8.3' S'1.8.3'
p121 p107
sg86 sg72
S'android/OsmAnd' S'android/OsmAnd'
p122 p108
sg88 sg74
(lp123 (lp109
sg90 sg76
S'../../build' S'../../build'
p124 p110
sg92 sg78
S'183' S'183'
p125 p111
sg94 sg80
I00 I00
sg95 sg81
(lp126 (lp112
sg97 sg83
Nsg98 Nsg84
I00 I00
sg99 sg85
I00 I00
sg100 sg86
S'1.8.3' S'1.8.3'
p127 p113
sg102
(lp128
sg104
S'no'
p129
sg106
Nsg107
Nsg108
(lp130
sg110
(lp131
sg112
g21
sg114
I00
sg115
S'bin/OsmAnd-release-unsigned.apk'
p132
sa(dp133
g70
I01
sg71
I00
sg72
I00
sg73
I00
sg74
Nsg75
(lp134
sg77
I00
sg78
(lp135
sg80
Nsg81
(lp136
sg83
g21
sg84
S'1.9.4'
p137
sg86
S'android/OsmAnd'
p138
sg88 sg88
(lp139 (lp114
sg90 sg90
S'../../build' S'no'
p140 p115
sg92 sg92
Nsg93
Nsg94
(lp116
sg96
(lp117
sg98
g25
sg100
I00
sg101
S'bin/OsmAnd-release-unsigned.apk'
p118
sa(dp119
g56
I01
sg57
I00
sg58
I00
sg59
I00
sg60
Nsg61
(lp120
sg63
I00
sg64
(lp121
sg66
Nsg67
(lp122
sg69
g25
sg70
S'1.9.4'
p123
sg72
S'android/OsmAnd'
p124
sg74
(lp125
sg76
S'../../build'
p126
sg78
S'196' S'196'
p141 p127
sg94
I00
sg95
(lp142
sg97
Nsg98
I00
sg99
I00
sg100
S'1.9.4'
p143
sg102
(lp144
sg104
S'no'
p145
sg106
S'r10d'
p146
sg107
Nsg108
(lp147
sg110
(lp148
sg112
g21
sg114
I00
sg115
S'bin/OsmAnd-release-unsigned.apk'
p149
sa(dp150
g70
I01
sg71
I00
sg72
I00
sg73
I00
sg74
Nsg75
(lp151
sg77
I00
sg78
(lp152
sg80 sg80
Nsg81 I00
(lp153 sg81
(lp128
sg83 sg83
g21 Nsg84
sg84 I00
S'1.9.5' sg85
p154 I00
sg86 sg86
S'android/OsmAnd' S'1.9.4'
p155 p129
sg88 sg88
(lp156 (lp130
sg90 sg90
S'../../build'
p157
sg92
S'197'
p158
sg94
I00
sg95
(lp159
sg97
Nsg98
I00
sg99
I00
sg100
S'1.9.5'
p160
sg102
(lp161
sg104
S'no' S'no'
p162 p131
sg106 sg92
S'r10d' S'r10d'
p163 p132
sg107 sg93
Nsg108 Nsg94
(lp164 (lp133
sg110 sg96
(lp165 (lp134
sg112 sg98
g21 g25
sg114 sg100
I00 I00
sg115 sg101
S'bin/OsmAnd-release-unsigned.apk' S'bin/OsmAnd-release-unsigned.apk'
p166 p135
sa(dp136
g56
I01
sg57
I00
sg58
I00
sg59
I00
sg60
Nsg61
(lp137
sg63
I00
sg64
(lp138
sg66
Nsg67
(lp139
sg69
g25
sg70
S'1.9.5'
p140
sg72
S'android/OsmAnd'
p141
sg74
(lp142
sg76
S'../../build'
p143
sg78
S'197'
p144
sg80
I00
sg81
(lp145
sg83
Nsg84
I00
sg85
I00
sg86
S'1.9.5'
p146
sg88
(lp147
sg90
S'no'
p148
sg92
S'r10d'
p149
sg93
Nsg94
(lp150
sg96
(lp151
sg98
g25
sg100
I00
sg101
S'bin/OsmAnd-release-unsigned.apk'
p152
sasS'FlattrID' sasS'FlattrID'
p167 p153
NsS'metadatapath' NsS'metadatapath'
p168 p154
S'metadata/net.osmand.plus.xml' S'metadata/net.osmand.plus.xml'
p169 p155
sS'Disabled' sS'Disabled'
p170 p156
NsS'Web Site' NsS'Web Site'
p171 p157
S'http://osmand.net' S'http://osmand.net'
p172 p158
sS'Update Check Name' sS'Update Check Name'
p173 p159
NsS'Vercode Operation' NsS'Vercode Operation'
p174 p160
NsS'Auto Update Mode' NsS'Auto Update Mode'
p175 p161
S'None' S'None'
p176 p162
s. s.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff