chiark / gitweb /
Merge branch 'docs' into 'master'
authorDaniel Martí <mvdan@mvdan.cc>
Thu, 10 Dec 2015 11:50:36 +0000 (11:50 +0000)
committerDaniel Martí <mvdan@mvdan.cc>
Thu, 10 Dec 2015 11:50:36 +0000 (11:50 +0000)
docs: Add information on binary verification

I added a section about `Binaries:` metadata field. However, my information might be wrong or outdated, since I barely used it by now. Maybe even this field was left out on purpose...

See merge request !83

36 files changed:
.gitlab-ci.yml
buildserver/config.buildserver.py
buildserver/cookbooks/android-ndk/recipes/default.rb
buildserver/cookbooks/android-sdk/recipes/default.rb
buildserver/cookbooks/fdroidbuild-general/recipes/default.rb
buildserver/cookbooks/gradle/recipes/default.rb
buildserver/cookbooks/gradle/recipes/gradle
completion/bash-completion
docs/fdroid.texi
examples/config.py
fdroid
fdroidserver/build.py
fdroidserver/checkupdates.py
fdroidserver/common.py
fdroidserver/import.py
fdroidserver/install.py
fdroidserver/lint.py
fdroidserver/metadata.py
fdroidserver/publish.py
fdroidserver/rewritemeta.py
fdroidserver/scanner.py
fdroidserver/stats.py
fdroidserver/update.py
makebuildserver
setup.py
tests/build.TestCase
tests/common.TestCase
tests/import.TestCase
tests/metadata.TestCase
tests/metadata/net.osmand.plus.pickle
tests/metadata/org.adaway.json
tests/metadata/org.adaway.pickle
tests/metadata/org.smssecure.smssecure.pickle
tests/metadata/org.videolan.vlc.pickle
tests/metadata/update-pickle.py [deleted file]
tests/run-tests

index df6e202968edf99fa02966c20dedd9b020b96b21..a1b3148a073d97cb7dbd6ebc510af074194c029f 100644 (file)
@@ -17,15 +17,15 @@ before_script:
   - echo " == Installing packages required by the 32-bit SDK"
   - apt-get -q install -y lib32stdc++6 lib32z1
   - echo " == Installing the Android SDK"
-  - wget -q -O android-sdk.tgz https://dl.google.com/android/android-sdk_r24.3.4-linux.tgz
+  - wget -q -O android-sdk.tgz https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
   - tar -x -z -f android-sdk.tgz
   - mv android-sdk-linux android-sdk
   - export ANDROID_HOME=$PWD/android-sdk
   - export PATH="$ANDROID_HOME/tools:$PATH"
   - echo " == Installing Android SDK components"
-  - echo y | android -s update sdk --no-ui -a -t platform-tools,tools,build-tools-23.0.1
+  - echo y | android -s update sdk --no-ui -a -t platform-tools,tools,build-tools-23.0.2
   - export PATH="$ANDROID_HOME/platform-tools:$PATH"
-  - export PATH="$ANDROID_HOME/build-tools/23.0.1:$PATH"
+  - export PATH="$ANDROID_HOME/build-tools/23.0.2:$PATH"
 
 test:
   script:
index fd6277d4cc858c71efa682b07638e2b26ad4bc38..61c57a3914ff93f9930489cde36acaa54f2f6a18 100644 (file)
@@ -3,3 +3,7 @@ ndk_paths = {
     'r9b': "/home/vagrant/android-ndk/r9b",
     'r10e': "/home/vagrant/android-ndk/r10e",
 }
+java_paths = {
+    '1.7': "/usr/lib/jvm/java-7-openjdk-i386",
+    '1.8': "/usr/lib/jvm/java-8-openjdk-i386",
+}
index 6fe9e11f6d0c47c0f9abbe0fd6b04c73046fa7a3..bc7044795773937b46fb357f26386c277df9c4ea 100644 (file)
@@ -8,11 +8,8 @@ script "setup-android-ndk" do
   user node[:settings][:user]
   cwd "/tmp"
   code "
-    mkdir #{ndk_loc}
+    mkdir -p #{ndk_loc}
   "
-  not_if do
-    File.exists?("#{ndk_loc}")
-  end
 end
 
 script "setup-android-ndk-r9b" do
@@ -30,9 +27,7 @@ script "setup-android-ndk-r9b" do
     tar jxvf /vagrant/cache/android-ndk-r9b-linux-x86$SUFFIX-legacy-toolchains.tar.bz2
     mv android-ndk-r9b #{ndk_loc}/r9b
   "
-  not_if do
-    File.exists?("#{ndk_loc}/r9b")
-  end
+  not_if "test -d #{ndk_loc}/r9b"
 end
 
 script "setup-android-ndk-r10e" do
@@ -50,8 +45,6 @@ script "setup-android-ndk-r10e" do
     /vagrant/cache/android-ndk-r10e-linux-x86$SUFFIX.bin x
     mv android-ndk-r10e #{ndk_loc}/r10e
   "
-  not_if do
-    File.exists?("#{ndk_loc}/r10e")
-  end
+  not_if "test -d #{ndk_loc}/r10e"
 end
 
index 8a8c77b295af16a1b74fd0e46bb95df6acb88228..98aa4dc39282eb7aad0b1a492f9901aac73d9c96 100644 (file)
@@ -8,14 +8,20 @@ script "setup-android-sdk" do
   user user
   cwd "/tmp"
   code "
-    tar zxvf /vagrant/cache/android-sdk_r24.3.4-linux.tgz
+    tar zxvf /vagrant/cache/android-sdk_r24.4.1-linux.tgz
     mv android-sdk-linux #{sdk_loc}
-    #{sdk_loc}/tools/android update sdk --no-ui -t platform-tool
-    #{sdk_loc}/tools/android update sdk --no-ui -t tool
   "
   not_if "test -d #{sdk_loc}"
 end
 
+script "setup-sdk-dirs" do
+  interpreter "bash"
+  user user
+  code "
+    mkdir -p #{sdk_loc}/build-tools
+  "
+end
+
 execute "add-android-sdk-path" do
   user user
   path = "#{sdk_loc}/tools:#{sdk_loc}/platform-tools"
@@ -23,71 +29,49 @@ execute "add-android-sdk-path" do
   not_if "grep PATH-SDK /home/#{user}/.bsenv"
 end
 
-script "add_build_tools" do
-  interpreter "bash"
-  user user
-  ver = "23.0.1"
-  cwd "/tmp"
-  code "
-    if [ -f /vagrant/cache/build-tools/#{ver}.tar.gz ] ; then
-      echo Installing from cache
-      mkdir #{sdk_loc}/build-tools
-      tar -C #{sdk_loc}/build-tools -z -x -f /vagrant/cache/build-tools/#{ver}.tar.gz
-    else
-      #{sdk_loc}/tools/android update sdk --no-ui -a -t build-tools-#{ver} <<X
+%w{
+    tools
+    platform-tools
+    extra-android-support
+    extra-android-m2repository
+}.each do |pkg|
+  script "add_pkg_#{pkg}" do
+    interpreter "bash"
+    user user
+    code "
+      #{sdk_loc}/tools/android update sdk --no-ui -a -t #{pkg} <<X
 y
 
 X
-    fi
-       sed -i '/BTPATH/d' /home/#{user}/.bsenv
-       echo \"export PATH=\\$PATH:#{sdk_loc}/build-tools/#{ver} #BTPATH\" >> /home/#{user}/.bsenv
-  "
-  not_if "test -d #{sdk_loc}/build-tools/#{ver}"
+    "
+  end
 end
 
-script "add_platform_tools" do
-  interpreter "bash"
-  user user
-  cwd "/tmp"
-  code "
-    if [ -f /vagrant/cache/platform-tools.tar.gz ] ; then
-      echo Installing from cache
-      mkdir #{sdk_loc}/platform-tools
-      tar -C #{sdk_loc}/platform-tools -z -x -f /vagrant/cache/platform-tools.tar.gz
-    else
-      #{sdk_loc}/tools/android update sdk --no-ui -a -t platform-tools <<X
-y
-
-X
-    fi
-  "
-  not_if "test -d #{sdk_loc}/platform-tools"
+%w{3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23}.each do |api|
+  script "add_sdk_#{api}" do
+    interpreter "bash"
+    user user
+    cwd "/tmp"
+    code "
+      unzip /vagrant/cache/android-platform-#{api}.zip
+      mv android-*/ #{sdk_loc}/platforms/android-#{api}
+    "
+    not_if "test -d #{sdk_loc}/platforms/android-#{api}"
+  end
 end
 
-%w{android-3 android-4 android-5 android-6 android-7 android-8 android-9
-   android-10 android-11 android-12 android-13 android-14 android-15
-   android-16 android-17 android-18 android-19 android-20 android-21
-   android-22 android-23
-   extra-android-support extra-android-m2repository}.each do |sdk|
-
-  script "add_sdk_#{sdk}" do
+%w{17.0.0 18.0.1 18.1.0 18.1.1 19.0.0 19.0.1 19.0.2 19.0.3 19.1.0
+    20.0.0 21.0.0 21.0.1 21.0.2 21.1.0 21.1.1 21.1.2 22.0.0 22.0.1
+    23.0.0 23.0.1 23.0.2
+}.each do |ver|
+  script "add_btools_#{ver}" do
     interpreter "bash"
     user user
     cwd "/tmp"
     code "
-      if [ -f /vagrant/cache/platforms/#{sdk}.tar.gz ] ; then
-        echo Installing from cache
-        tar -C #{sdk_loc}/platforms -z -x -f /vagrant/cache/platforms/#{sdk}.tar.gz
-      else
-        echo Installing via 'android'
-        #{sdk_loc}/tools/android update sdk --no-ui -a -t #{sdk} <<X
-y
-
-X
-      fi
+      unzip /vagrant/cache/build-tools-#{ver}.zip
+      mv android-*/ #{sdk_loc}/build-tools/#{ver}
     "
-    not_if "test -d #{sdk_loc}/platforms/#{sdk}"
+    not_if "test -d #{sdk_loc}/build-tools/#{ver}"
   end
-
 end
-
index f15e737ab597bb7271f65305f60846a828bb8281..ce46c6b6da1d937e2a6fddf0b9373c3c9bfda2b1 100644 (file)
@@ -6,11 +6,75 @@ execute 'set_debian_mirror' do
   command "sed -i 's,http://ftp.uk.debian.org/debian/,#{debian_mirror},g' /etc/apt/sources.list"
 end
 
+execute "jessie_backports" do
+  command "echo 'deb http://http.debian.net/debian jessie-backports main' > /etc/apt/sources.list.d/backports.list"
+  only_if "grep jessie /etc/apt/sources.list"
+end
+
 execute "apt-get-update" do
   command "apt-get update"
 end
 
-%w{ant ant-contrib autoconf autoconf2.13 automake1.11 autopoint bison bzr cmake curl expect faketime flex gettext git-core git-svn gperf graphviz imagemagick inkscape javacc libarchive-zip-perl liblzma-dev librsvg2-bin libsaxonb-java libssl-dev libssl1.0.0 libtool make maven mercurial nasm openjdk-7-jdk optipng pandoc perlmagick pkg-config python python-yaml python-gnupg python-magic python-setuptools python3-gnupg quilt realpath scons subversion swig texinfo transfig unzip vorbis-tools xsltproc yasm zip}.each do |pkg|
+%w{
+    ant
+    ant-contrib
+    autoconf
+    autoconf2.13
+    automake1.11
+    autopoint
+    bison
+    bzr
+    cmake
+    curl
+    expect
+    faketime
+    flex
+    gettext
+    git-core
+    git-svn
+    gperf
+    graphviz
+    imagemagick
+    inkscape
+    javacc
+    libarchive-zip-perl
+    liblzma-dev
+    librsvg2-bin
+    libsaxonb-java
+    libssl-dev
+    libssl1.0.0
+    libtool
+    make
+    maven
+    mercurial
+    nasm
+    openjdk-7-jdk
+    openjdk-8-jdk
+    optipng
+    pandoc
+    perlmagick
+    pkg-config
+    python
+    python-gnupg
+    python-magic
+    python-setuptools
+    python-yaml
+    python3-gnupg
+    qt5-default
+    qtbase5-dev
+    quilt
+    realpath
+    scons
+    subversion
+    swig
+    texinfo
+    transfig
+    unzip
+    vorbis-tools
+    xsltproc
+    yasm
+    zip
+  }.each do |pkg|
   package pkg do
     action :install
   end
@@ -35,4 +99,7 @@ execute "add-bsenv" do
   not_if "grep bsenv /home/#{user}/.bashrc"
 end
 
+execute "set-default-java" do
+  command "update-java-alternatives --set java-1.7.0-openjdk-i386"
+end
 
index 397b378a94ce6b11e455bede32948ea1d7ebb21a..716bf82fe38341fc3fb6752f387041ae824e2eee 100644 (file)
@@ -18,7 +18,7 @@ script "add-gradle-verdir" do
   not_if "test -d /opt/gradle/versions"
 end
 
-%w{1.4 1.6 1.7 1.8 1.9 1.10 1.11 1.12 2.1 2.2.1 2.3 2.4 2.5 2.6}.each do |ver|
+%w{1.4 1.6 1.7 1.8 1.9 1.10 1.11 1.12 2.1 2.2.1 2.3 2.4 2.5 2.6 2.7 2.8 2.9}.each do |ver|
   script "install-gradle-#{ver}" do
     cwd "/tmp"
     interpreter "bash"
index 3f836312ebd5ab9a38393068bf0d841aaba099fb..1ad3ac3c2e818bcf0fdab866f816790e5b73c067 100755 (executable)
@@ -27,10 +27,10 @@ d_plugin_k=(1.3 1.2   1.1   1.0 0.14 0.13 0.12 0.11 0.10  0.9  0.8 0.7 0.6 0.5 0
 d_plugin_v=(2.4 2.3 2.2.1 2.2.1  2.1  2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4)
 
 # All gradle versions we know about
-plugin_v=(2.6 2.5 2.4 2.3 2.2.1 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4)
+plugin_v=(2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4)
 
 # Find the highest version available
-for v in ${plugin_v}; do
+for v in ${plugin_v[*]}; do
        if contains $v "${v_all[*]}"; then
                v_def=$v
                break
index 09683437b717afe6302bc8e2bdcf4b2e81a0b268..f0ce84a355305a84b1a83c7f1b6b889cd4d7deed 100644 (file)
@@ -37,10 +37,16 @@ __fdroid_init() {
        (( $# >= 1 )) && __complete_${1}
 }
 
-__package() {
-       files=( metadata/*.txt )
+__by_ext() {
+       local ext="$1"
+       files=( metadata/*.$ext )
        files=( ${files[@]#metadata/} )
-       files=${files[@]%.txt}
+       files=${files[@]%.$ext}
+       echo "$files"
+}
+
+__package() {
+       files="$(__by_ext txt) $(__by_ext yaml) $(__by_ext json) $(__by_ext xml)"
        COMPREPLY=( $( compgen -W "$files" -- $cur ) )
 }
 
index cdbbb85b9fe8e3a843bca2e95335073b62159712..7b94dc69e3e2de4f62012308afdd3c6b3042dbd6 100644 (file)
@@ -707,7 +707,7 @@ A litecoin address for donating to the project.
 @cindex Summary
 
 A brief summary of what the application is. Since the summary is only allowed
-one line on the list of the F-Droid client, keeping it to within 50 characters
+one line on the list of the F-Droid client, keeping it to within 80 characters
 will ensure it fits most screens.
 
 @node Description
@@ -1072,9 +1072,9 @@ adding them to 'ndk_paths' in your config file.
 Build with Gradle instead of Ant, specifying what flavours to use. Flavours
 are case sensitive since the path to the output apk is as well.
 
-If only one flavour is given and it is 'yes' or 'main', no flavour will be
-used. Note that for projects with flavours, you must specify at least one
-valid flavour since 'yes' or 'main' will build all of them separately.
+If only one flavour is given and it is 'yes', no flavour will be used.
+Note that for projects with flavours, you must specify at least one
+valid flavour since 'yes' will build all of them separately.
 
 @item maven=yes[@@<dir>]
 Build with Maven instead of Ant. An extra @@<dir> tells F-Droid to run Maven
index 147b73862fe2af468599ebcbf0c2bf041a7747e0..2aaaed1091988af457219d24c581c7fcf667a9f8 100644 (file)
@@ -4,7 +4,7 @@
 # your system configuration.
 
 # Custom path to the Android SDK, defaults to $ANDROID_HOME
-# sdk_path = "/opt/android-sdk"
+# sdk_path = "$ANDROID_HOME"
 
 # Custom paths to various versions of the Android NDK, defaults to 'r10e' set
 # to $ANDROID_NDK. Most users will have the latest at $ANDROID_NDK, which is
 #     'r10e': "$ANDROID_NDK",
 # }
 
+# If you want to build apps that use retrolambda and Java 1.8, you'll need to
+# have both 1.7 and 1.8 installed.
+# java_paths = {
+#     '1.7': "/usr/lib/jvm/java-7-openjdk",
+#     '1.8': None,
+# }
+
 # Build tools version to be used
-# build_tools = "23.0.1"
+# build_tools = "23.0.2"
 
 # Command or path to binary for running Ant
 # ant = "ant"
diff --git a/fdroid b/fdroid
index 9199ee6594313e0e4150dae16184b756a9e9897a..ef3a001a011e90dbc650cf0b1a23e9ad6c5d6a14 100755 (executable)
--- a/fdroid
+++ b/fdroid
@@ -99,12 +99,15 @@ def main():
     verbose = any(s in sys.argv for s in ['-v', '--verbose'])
     quiet = any(s in sys.argv for s in ['-q', '--quiet'])
 
+    # Helpful to differentiate warnings from errors even when on quiet
+    logformat = '%(levelname)s: %(message)s'
+    loglevel = logging.INFO
     if verbose:
-        logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
+        loglevel = logging.DEBUG
     elif quiet:
-        logging.basicConfig(format='%(message)s', level=logging.WARN)
-    else:
-        logging.basicConfig(format='%(message)s', level=logging.INFO)
+        loglevel = logging.WARN
+
+    logging.basicConfig(format=logformat, level=loglevel)
 
     if verbose and quiet:
         logging.critical("Specifying --verbose and --quiet and the same time is silly")
index 7ee0ebd1e9e6b76b7b75fe8cb81c56fec1feeb57..44d48bba93e3888e4bfa2617070830b1168dbb7c 100644 (file)
@@ -245,7 +245,7 @@ def release_vm():
 
 
 # Note that 'force' here also implies test mode.
-def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
+def build_server(app, build, vcs, build_dir, output_dir, force):
     """Do a build on the build server."""
 
     try:
@@ -253,7 +253,7 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
     except NameError:
         raise BuildException("Paramiko is required to use the buildserver")
     if options.verbose:
-        logging.getLogger("paramiko").setLevel(logging.DEBUG)
+        logging.getLogger("paramiko").setLevel(logging.INFO)
     else:
         logging.getLogger("paramiko").setLevel(logging.WARN)
 
@@ -320,11 +320,11 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
         ftp.mkdir('metadata')
         ftp.mkdir('srclibs')
         ftp.chdir('metadata')
-        ftp.put(os.path.join('metadata', app['id'] + '.txt'),
-                app['id'] + '.txt')
+        ftp.put(os.path.join('metadata', app.id + '.txt'),
+                app.id + '.txt')
         # And patches if there are any...
-        if os.path.exists(os.path.join('metadata', app['id'])):
-            send_dir(os.path.join('metadata', app['id']))
+        if os.path.exists(os.path.join('metadata', app.id)):
+            send_dir(os.path.join('metadata', app.id))
 
         ftp.chdir(homedir)
         # Create the build directory...
@@ -333,9 +333,9 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
         ftp.mkdir('extlib')
         ftp.mkdir('srclib')
         # Copy any extlibs that are required...
-        if thisbuild['extlibs']:
+        if build.extlibs:
             ftp.chdir(homedir + '/build/extlib')
-            for lib in thisbuild['extlibs']:
+            for lib in build.extlibs:
                 lib = lib.strip()
                 libsrc = os.path.join('build/extlib', lib)
                 if not os.path.exists(libsrc):
@@ -350,8 +350,8 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
                     ftp.chdir('..')
         # Copy any srclibs that are required...
         srclibpaths = []
-        if thisbuild['srclibs']:
-            for lib in thisbuild['srclibs']:
+        if build.srclibs:
+            for lib in build.srclibs:
                 srclibpaths.append(
                     common.getsrclib(lib, 'build/srclib', basepath=True, prepare=False))
 
@@ -375,7 +375,7 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
         # (no need if it's a srclib)
         if (not basesrclib) and os.path.exists(build_dir):
             ftp.chdir(homedir + '/build')
-            fv = '.fdroidvcs-' + app['id']
+            fv = '.fdroidvcs-' + app.id
             ftp.put(os.path.join('build', fv), fv)
             send_dir(build_dir)
 
@@ -389,7 +389,7 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
             cmdline += ' --force --test'
         if options.verbose:
             cmdline += ' --verbose'
-        cmdline += " %s:%s" % (app['id'], thisbuild['vercode'])
+        cmdline += " %s:%s" % (app.id, build.vercode)
         chan.exec_command('bash -c ". ~/.bsenv && ' + cmdline + '"')
         output = ''
         while not chan.exit_status_ready():
@@ -406,7 +406,7 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
         if returncode != 0:
             raise BuildException(
                 "Build.py failed on server for {0}:{1}".format(
-                    app['id'], thisbuild['version']), output)
+                    app.id, build.version), output)
 
         # Retrieve the built files...
         logging.info("Retrieving build output...")
@@ -414,8 +414,8 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
             ftp.chdir(homedir + '/tmp')
         else:
             ftp.chdir(homedir + '/unsigned')
-        apkfile = common.getapkname(app, thisbuild)
-        tarball = common.getsrcname(app, thisbuild)
+        apkfile = common.getapkname(app, build)
+        tarball = common.getsrcname(app, build)
         try:
             ftp.get(apkfile, os.path.join(output_dir, apkfile))
             if not options.notarball:
@@ -423,7 +423,7 @@ def build_server(app, thisbuild, vcs, build_dir, output_dir, force):
         except:
             raise BuildException(
                 "Build failed for %s:%s - missing output files".format(
-                    app['id'], thisbuild['version']), output)
+                    app.id, build.version), output)
         ftp.close()
 
     finally:
@@ -442,7 +442,7 @@ def adapt_gradle(build_dir):
             if not os.path.isfile(path):
                 continue
             logging.debug("Adapting %s at %s" % (filename, path))
-            common.regsub_file(r"""(\s*)buildToolsVersion([\s=]+)['"].*""",
+            common.regsub_file(r"""(\s*)buildToolsVersion([\s=]+).*""",
                                r"""\1buildToolsVersion\2'%s'""" % config['build_tools'],
                                path)
 
@@ -457,32 +457,33 @@ def capitalize_intact(string):
     return string[0].upper() + string[1:]
 
 
-def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, force, onserver, refresh):
+def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, force, onserver, refresh):
     """Do a build locally."""
 
-    if thisbuild['buildjni'] and thisbuild['buildjni'] != ['no']:
-        if not thisbuild['ndk_path']:
-            logging.critical("Android NDK version '%s' could not be found!" % thisbuild['ndk'])
+    ndk_path = build.ndk_path()
+    if build.buildjni and build.buildjni != ['no']:
+        if not ndk_path:
+            logging.critical("Android NDK version '%s' could not be found!" % build.ndk or 'r10e')
             logging.critical("Configured versions:")
             for k, v in config['ndk_paths'].iteritems():
                 if k.endswith("_orig"):
                     continue
                 logging.critical("  %s: %s" % (k, v))
             sys.exit(3)
-        elif not os.path.isdir(thisbuild['ndk_path']):
-            logging.critical("Android NDK '%s' is not a directory!" % thisbuild['ndk_path'])
+        elif not os.path.isdir(ndk_path):
+            logging.critical("Android NDK '%s' is not a directory!" % ndk_path)
             sys.exit(3)
 
     # Set up environment vars that depend on each build
     for n in ['ANDROID_NDK', 'NDK', 'ANDROID_NDK_HOME']:
-        common.env[n] = thisbuild['ndk_path']
+        common.env[n] = ndk_path
 
     common.reset_env_path()
     # Set up the current NDK to the PATH
-    common.add_to_env_path(thisbuild['ndk_path'])
+    common.add_to_env_path(ndk_path)
 
     # Prepare the source code...
-    root_dir, srclibpaths = common.prepare_source(vcs, app, thisbuild,
+    root_dir, srclibpaths = common.prepare_source(vcs, app, build,
                                                   build_dir, srclib_dir,
                                                   extlib_dir, onserver, refresh)
 
@@ -490,26 +491,27 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
     # different from the default ones
     p = None
     gradletasks = []
-    if thisbuild['type'] == 'maven':
+    method = build.method()
+    if method == 'maven':
         logging.info("Cleaning Maven project...")
         cmd = [config['mvn3'], 'clean', '-Dandroid.sdk.path=' + config['sdk_path']]
 
-        if '@' in thisbuild['maven']:
-            maven_dir = os.path.join(root_dir, thisbuild['maven'].split('@', 1)[1])
+        if '@' in build.maven:
+            maven_dir = os.path.join(root_dir, build.maven.split('@', 1)[1])
             maven_dir = os.path.normpath(maven_dir)
         else:
             maven_dir = root_dir
 
         p = FDroidPopen(cmd, cwd=maven_dir)
 
-    elif thisbuild['type'] == 'gradle':
+    elif method == 'gradle':
 
         logging.info("Cleaning Gradle project...")
 
-        if thisbuild['preassemble']:
-            gradletasks += thisbuild['preassemble']
+        if build.preassemble:
+            gradletasks += build.preassemble
 
-        flavours = thisbuild['gradle']
+        flavours = build.gradle
         if flavours == ['yes']:
             flavours = []
 
@@ -522,8 +524,8 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
             adapt_gradle(libpath)
 
         cmd = [config['gradle']]
-        if thisbuild['gradleprops']:
-            cmd += ['-P'+kv for kv in thisbuild['gradleprops']]
+        if build.gradleprops:
+            cmd += ['-P'+kv for kv in build.gradleprops]
 
         for task in gradletasks:
             parts = task.split(':')
@@ -534,40 +536,53 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
 
         p = FDroidPopen(cmd, cwd=root_dir)
 
-    elif thisbuild['type'] == 'kivy':
+    elif method == 'kivy':
         pass
 
-    elif thisbuild['type'] == 'ant':
+    elif method == 'ant':
         logging.info("Cleaning Ant project...")
         p = FDroidPopen(['ant', 'clean'], cwd=root_dir)
 
     if p is not None and p.returncode != 0:
         raise BuildException("Error cleaning %s:%s" %
-                             (app['id'], thisbuild['version']), p.output)
+                             (app.id, build.version), p.output)
 
     for root, dirs, files in os.walk(build_dir):
-        # Even when running clean, gradle stores task/artifact caches in
-        # .gradle/ as binary files. To avoid overcomplicating the scanner,
-        # manually delete them, just like `gradle clean` should have removed
-        # the build/ dirs.
-        if '.gradle' in dirs:
-            shutil.rmtree(os.path.join(root, '.gradle'))
-        # Don't remove possibly necessary 'gradle' dirs if 'gradlew' is not there
-        if 'gradlew' in files:
-            logging.debug("Getting rid of Gradle wrapper stuff in %s" % root)
-            os.remove(os.path.join(root, 'gradlew'))
-            if 'gradlew.bat' in files:
-                os.remove(os.path.join(root, 'gradlew.bat'))
-            if 'gradle' in dirs:
-                shutil.rmtree(os.path.join(root, 'gradle'))
+
+        def del_dirs(dl):
+            for d in dl:
+                if d in dirs:
+                    shutil.rmtree(os.path.join(root, d))
+
+        def del_files(fl):
+            for f in fl:
+                if f in files:
+                    os.remove(os.path.join(root, f))
+
+        if 'build.gradle' in files:
+            # Even when running clean, gradle stores task/artifact caches in
+            # .gradle/ as binary files. To avoid overcomplicating the scanner,
+            # manually delete them, just like `gradle clean` should have removed
+            # the build/ dirs.
+            del_dirs(['build', '.gradle', 'gradle'])
+            del_files(['gradlew', 'gradlew.bat'])
+
+        if 'pom.xml' in files:
+            del_dirs(['target'])
+
+        if any(f in files for f in ['ant.properties', 'project.properties', 'build.xml']):
+            del_dirs(['bin', 'gen'])
+
+        if 'jni' in dirs:
+            del_dirs(['obj'])
 
     if options.skipscan:
-        if thisbuild['scandelete']:
+        if build.scandelete:
             raise BuildException("Refusing to skip source scan since scandelete is present")
     else:
         # Scan before building...
         logging.info("Scanning source for common problems...")
-        count = scanner.scan_source(build_dir, root_dir, thisbuild)
+        count = scanner.scan_source(build_dir, root_dir, build)
         if count > 0:
             if force:
                 logging.warn('Scanner found %d problems' % count)
@@ -577,7 +592,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
     if not options.notarball:
         # Build the source tarball right before we build the release...
         logging.info("Creating source tarball...")
-        tarname = common.getsrcname(app, thisbuild)
+        tarname = common.getsrcname(app, build)
         tarball = tarfile.open(os.path.join(tmp_dir, tarname), "w:gz")
 
         def tarexc(f):
@@ -586,9 +601,9 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
         tarball.close()
 
     # Run a build command if one is required...
-    if thisbuild['build']:
+    if build.build:
         logging.info("Running 'build' commands in %s" % root_dir)
-        cmd = common.replace_config_vars(thisbuild['build'], thisbuild)
+        cmd = common.replace_config_vars(build.build, build)
 
         # Substitute source library paths into commands...
         for name, number, libpath in srclibpaths:
@@ -599,16 +614,16 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
 
         if p.returncode != 0:
             raise BuildException("Error running build command for %s:%s" %
-                                 (app['id'], thisbuild['version']), p.output)
+                                 (app.id, build.version), p.output)
 
     # Build native stuff if required...
-    if thisbuild['buildjni'] and thisbuild['buildjni'] != ['no']:
+    if build.buildjni and build.buildjni != ['no']:
         logging.info("Building the native code")
-        jni_components = thisbuild['buildjni']
+        jni_components = build.buildjni
 
         if jni_components == ['yes']:
             jni_components = ['']
-        cmd = [os.path.join(thisbuild['ndk_path'], "ndk-build"), "-j1"]
+        cmd = [os.path.join(ndk_path, "ndk-build"), "-j1"]
         for d in jni_components:
             if d:
                 logging.info("Building native code in '%s'" % d)
@@ -627,15 +642,15 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
                 del manifest_text
             p = FDroidPopen(cmd, cwd=os.path.join(root_dir, d))
             if p.returncode != 0:
-                raise BuildException("NDK build failed for %s:%s" % (app['id'], thisbuild['version']), p.output)
+                raise BuildException("NDK build failed for %s:%s" % (app.id, build.version), p.output)
 
     p = None
     # Build the release...
-    if thisbuild['type'] == 'maven':
+    if method == 'maven':
         logging.info("Building Maven project...")
 
-        if '@' in thisbuild['maven']:
-            maven_dir = os.path.join(root_dir, thisbuild['maven'].split('@', 1)[1])
+        if '@' in build.maven:
+            maven_dir = os.path.join(root_dir, build.maven.split('@', 1)[1])
         else:
             maven_dir = root_dir
 
@@ -643,12 +658,12 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
                   '-Dmaven.jar.sign.skip=true', '-Dmaven.test.skip=true',
                   '-Dandroid.sign.debug=false', '-Dandroid.release=true',
                   'package']
-        if thisbuild['target']:
-            target = thisbuild["target"].split('-')[1]
+        if build.target:
+            target = build.target.split('-')[1]
             common.regsub_file(r'<platform>[0-9]*</platform>',
                                r'<platform>%s</platform>' % target,
                                os.path.join(root_dir, 'pom.xml'))
-            if '@' in thisbuild['maven']:
+            if '@' in build.maven:
                 common.regsub_file(r'<platform>[0-9]*</platform>',
                                    r'<platform>%s</platform>' % target,
                                    os.path.join(maven_dir, 'pom.xml'))
@@ -657,7 +672,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
 
         bindir = os.path.join(root_dir, 'target')
 
-    elif thisbuild['type'] == 'kivy':
+    elif method == 'kivy':
         logging.info("Building Kivy project...")
 
         spec = os.path.join(root_dir, 'buildozer.spec')
@@ -677,8 +692,8 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
         modules = bconfig.get('app', 'requirements').split(',')
 
         cmd = 'ANDROIDSDK=' + config['sdk_path']
-        cmd += ' ANDROIDNDK=' + thisbuild['ndk_path']
-        cmd += ' ANDROIDNDKVER=' + thisbuild['ndk']
+        cmd += ' ANDROIDNDK=' + ndk_path
+        cmd += ' ANDROIDNDKVER=' + build.ndk
         cmd += ' ANDROIDAPI=' + str(bconfig.get('app', 'android.api'))
         cmd += ' VIRTUALENV=virtualenv'
         cmd += ' ./distribute.sh'
@@ -689,7 +704,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
             raise BuildException("Distribute build failed")
 
         cid = bconfig.get('app', 'package.domain') + '.' + bconfig.get('app', 'package.name')
-        if cid != app['id']:
+        if cid != app.id:
             raise BuildException("Package ID mismatch between metadata and spec")
 
         orientation = bconfig.get('app', 'orientation', 'landscape')
@@ -699,7 +714,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
         cmd = ['./build.py'
                '--dir', root_dir,
                '--name', bconfig.get('app', 'title'),
-               '--package', app['id'],
+               '--package', app.id,
                '--version', bconfig.get('app', 'version'),
                '--orientation', orientation
                ]
@@ -718,27 +733,27 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
         cmd.append('release')
         p = FDroidPopen(cmd, cwd=distdir)
 
-    elif thisbuild['type'] == 'gradle':
+    elif method == 'gradle':
         logging.info("Building Gradle project...")
 
         # Avoid having to use lintOptions.abortOnError false
-        if thisbuild['gradlepluginver'] >= LooseVersion('0.7'):
+        if build.gradlepluginver >= LooseVersion('0.7'):
             with open(os.path.join(root_dir, 'build.gradle'), "a") as f:
                 f.write("\nandroid { lintOptions { checkReleaseBuilds false } }\n")
 
         cmd = [config['gradle']]
-        if thisbuild['gradleprops']:
-            cmd += ['-P'+kv for kv in thisbuild['gradleprops']]
+        if build.gradleprops:
+            cmd += ['-P'+kv for kv in build.gradleprops]
 
         cmd += gradletasks
 
         p = FDroidPopen(cmd, cwd=root_dir)
 
-    elif thisbuild['type'] == 'ant':
+    elif method == 'ant':
         logging.info("Building Ant project...")
         cmd = ['ant']
-        if thisbuild['antcommands']:
-            cmd += thisbuild['antcommands']
+        if build.antcommands:
+            cmd += build.antcommands
         else:
             cmd += ['release']
         p = FDroidPopen(cmd, cwd=root_dir)
@@ -746,10 +761,10 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
         bindir = os.path.join(root_dir, 'bin')
 
     if p is not None and p.returncode != 0:
-        raise BuildException("Build failed for %s:%s" % (app['id'], thisbuild['version']), p.output)
-    logging.info("Successfully built version " + thisbuild['version'] + ' of ' + app['id'])
+        raise BuildException("Build failed for %s:%s" % (app.id, build.version), p.output)
+    logging.info("Successfully built version " + build.version + ' of ' + app.id)
 
-    if thisbuild['type'] == 'maven':
+    if method == 'maven':
         stdout_apk = '\n'.join([
             line for line in p.output.splitlines() if any(
                 a in line for a in ('.apk', '.ap_', '.jar'))])
@@ -769,14 +784,14 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
             raise BuildException('Failed to find output')
         src = m.group(1)
         src = os.path.join(bindir, src) + '.apk'
-    elif thisbuild['type'] == 'kivy':
+    elif method == 'kivy':
         src = os.path.join('python-for-android', 'dist', 'default', 'bin',
                            '{0}-{1}-release.apk'.format(
                                bconfig.get('app', 'title'),
                                bconfig.get('app', 'version')))
-    elif thisbuild['type'] == 'gradle':
+    elif method == 'gradle':
 
-        if thisbuild['gradlepluginver'] >= LooseVersion('0.11'):
+        if build.gradlepluginver >= LooseVersion('0.11'):
             apks_dir = os.path.join(root_dir, 'build', 'outputs', 'apk')
         else:
             apks_dir = os.path.join(root_dir, 'build', 'apk')
@@ -788,14 +803,14 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
         if len(apks) < 1:
             raise BuildException('Failed to find gradle output in %s' % apks_dir)
         src = apks[0]
-    elif thisbuild['type'] == 'ant':
+    elif method == 'ant':
         stdout_apk = '\n'.join([
             line for line in p.output.splitlines() if '.apk' in line])
         src = re.match(r".*^.*Creating (.+) for release.*$.*", stdout_apk,
                        re.S | re.M).group(1)
         src = os.path.join(bindir, src)
-    elif thisbuild['type'] == 'raw':
-        src = os.path.join(root_dir, thisbuild['output'])
+    elif method == 'raw':
+        src = os.path.join(root_dir, build.output)
         src = os.path.normpath(src)
 
     # Make sure it's not debuggable...
@@ -837,18 +852,18 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
         nativecode = nativecode.strip()
         nativecode = None if not nativecode else nativecode
 
-    if thisbuild['buildjni'] and thisbuild['buildjni'] != ['no']:
+    if build.buildjni and build.buildjni != ['no']:
         if nativecode is None:
             raise BuildException("Native code should have been built but none was packaged")
-    if thisbuild['novcheck']:
-        vercode = thisbuild['vercode']
-        version = thisbuild['version']
+    if build.novcheck:
+        vercode = build.vercode
+        version = build.version
     if not version or not vercode:
         raise BuildException("Could not find version information in build in output")
     if not foundid:
         raise BuildException("Could not find package ID in output")
-    if foundid != app['id']:
-        raise BuildException("Wrong package ID - build " + foundid + " but expected " + app['id'])
+    if foundid != app.id:
+        raise BuildException("Wrong package ID - build " + foundid + " but expected " + app.id)
 
     # Some apps (e.g. Timeriffic) have had the bonkers idea of
     # including the entire changelog in the version number. Remove
@@ -858,13 +873,13 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
     if index != -1:
         version = version[:index]
 
-    if (version != thisbuild['version'] or
-            vercode != thisbuild['vercode']):
+    if (version != build.version or
+            vercode != build.vercode):
         raise BuildException(("Unexpected version/version code in output;"
                               " APK: '%s' / '%s', "
                               " Expected: '%s' / '%s'")
-                             % (version, str(vercode), thisbuild['version'],
-                                str(thisbuild['vercode']))
+                             % (version, str(vercode), build.version,
+                                str(build.vercode))
                              )
 
     # Add information for 'fdroid verify' to be able to reproduce the build
@@ -882,7 +897,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
 
     # Copy the unsigned apk to our destination directory for further
     # processing (by publish.py)...
-    dest = os.path.join(output_dir, common.getapkname(app, thisbuild))
+    dest = os.path.join(output_dir, common.getapkname(app, build))
     shutil.copyfile(src, dest)
 
     # Move the source tarball into the output directory...
@@ -891,7 +906,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
                     os.path.join(output_dir, tarname))
 
 
-def trybuild(app, thisbuild, build_dir, output_dir, also_check_dir, srclib_dir, extlib_dir,
+def trybuild(app, build, build_dir, output_dir, also_check_dir, srclib_dir, extlib_dir,
              tmp_dir, repo_dir, vcs, test, server, force, onserver, refresh):
     """
     Build a particular version of an application, if it needs building.
@@ -910,7 +925,7 @@ def trybuild(app, thisbuild, build_dir, output_dir, also_check_dir, srclib_dir,
     :returns: True if the build was done, False if it wasn't necessary.
     """
 
-    dest_apk = common.getapkname(app, thisbuild)
+    dest_apk = common.getapkname(app, build)
 
     dest = os.path.join(output_dir, dest_apk)
     dest_repo = os.path.join(repo_dir, dest_apk)
@@ -924,20 +939,20 @@ def trybuild(app, thisbuild, build_dir, output_dir, also_check_dir, srclib_dir,
             if os.path.exists(dest_also):
                 return False
 
-    if thisbuild['disable'] and not options.force:
+    if build.disable and not options.force:
         return False
 
     logging.info("Building version %s (%s) of %s" % (
-        thisbuild['version'], thisbuild['vercode'], app['id']))
+        build.version, build.vercode, app.id))
 
     if server:
         # When using server mode, still keep a local cache of the repo, by
         # grabbing the source now.
-        vcs.gotorevision(thisbuild['commit'])
+        vcs.gotorevision(build.commit)
 
-        build_server(app, thisbuild, vcs, build_dir, output_dir, force)
+        build_server(app, build, vcs, build_dir, output_dir, force)
     else:
-        build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, force, onserver, refresh)
+        build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, force, onserver, refresh)
     return True
 
 
@@ -1038,7 +1053,7 @@ def main():
 
     apps = common.read_app_args(options.appid, allapps, True)
     for appid, app in apps.items():
-        if (app['Disabled'] and not options.force) or not app['Repo Type'] or not app['builds']:
+        if (app.Disabled and not options.force) or not app.RepoType or not app.builds:
             del apps[appid]
 
     if not apps:
@@ -1046,10 +1061,10 @@ def main():
 
     if options.latest:
         for app in apps.itervalues():
-            for build in reversed(app['builds']):
-                if build['disable'] and not options.force:
+            for build in reversed(app.builds):
+                if build.disable and not options.force:
                     continue
-                app['builds'] = [build]
+                app.builds = [build]
                 break
 
     if options.wiki:
@@ -1065,7 +1080,7 @@ def main():
 
         first = True
 
-        for thisbuild in app['builds']:
+        for build in app.builds:
             wikilog = None
             try:
 
@@ -1073,49 +1088,41 @@ def main():
                 # the source repo. We can reuse it on subsequent builds, if
                 # there are any.
                 if first:
-                    if app['Repo Type'] == 'srclib':
-                        build_dir = os.path.join('build', 'srclib', app['Repo'])
+                    if app.RepoType == 'srclib':
+                        build_dir = os.path.join('build', 'srclib', app.Repo)
                     else:
                         build_dir = os.path.join('build', appid)
 
                     # Set up vcs interface and make sure we have the latest code...
                     logging.debug("Getting {0} vcs interface for {1}"
-                                  .format(app['Repo Type'], app['Repo']))
-                    vcs = common.getvcs(app['Repo Type'], app['Repo'], build_dir)
+                                  .format(app.RepoType, app.Repo))
+                    vcs = common.getvcs(app.RepoType, app.Repo, build_dir)
 
                     first = False
 
-                logging.debug("Checking " + thisbuild['version'])
-                if trybuild(app, thisbuild, build_dir, output_dir,
+                logging.debug("Checking " + build.version)
+                if trybuild(app, build, build_dir, output_dir,
                             also_check_dir, srclib_dir, extlib_dir,
                             tmp_dir, repo_dir, vcs, options.test,
                             options.server, options.force,
                             options.onserver, options.refresh):
 
-                    if app.get('Binaries', None):
+                    if app.Binaries is not None:
                         # This is an app where we build from source, and
                         # verify the apk contents against a developer's
                         # binary. We get that binary now, and save it
                         # alongside our built one in the 'unsigend'
                         # directory.
-                        url = app['Binaries']
-                        url = url.replace('%v', thisbuild['version'])
-                        url = url.replace('%c', str(thisbuild['vercode']))
+                        url = app.Binaries
+                        url = url.replace('%v', build.version)
+                        url = url.replace('%c', str(build.vercode))
                         logging.info("...retrieving " + url)
-                        of = "{0}_{1}.apk.binary".format(app['id'], thisbuild['vercode'])
+                        of = "{0}_{1}.apk.binary".format(app.id, build.vercode)
                         of = os.path.join(output_dir, of)
                         net.download_file(url, local_filename=of)
 
                     build_succeeded.append(app)
                     wikilog = "Build succeeded"
-            except BuildException as be:
-                with open(os.path.join(log_dir, appid + '.log'), 'a+') as f:
-                    f.write(str(be))
-                print("Could not build app %s due to BuildException: %s" % (appid, be))
-                if options.stop:
-                    sys.exit(1)
-                failed_apps[appid] = be
-                wikilog = be.get_wikitext()
             except VCSException as vcse:
                 reason = str(vcse).split('\n', 1)[0] if options.verbose else str(vcse)
                 logging.error("VCS error while building app %s: %s" % (
@@ -1124,6 +1131,14 @@ def main():
                     sys.exit(1)
                 failed_apps[appid] = vcse
                 wikilog = str(vcse)
+            except FDroidException as e:
+                with open(os.path.join(log_dir, appid + '.log'), 'a+') as f:
+                    f.write(str(e))
+                logging.error("Could not build app %s: %s" % (appid, e))
+                if options.stop:
+                    sys.exit(1)
+                failed_apps[appid] = e
+                wikilog = e.get_wikitext()
             except Exception as e:
                 logging.error("Could not build app %s due to unknown error: %s" % (
                     appid, traceback.format_exc()))
@@ -1135,7 +1150,7 @@ def main():
             if options.wiki and wikilog:
                 try:
                     # Write a page with the last build log for this version code
-                    lastbuildpage = appid + '/lastbuild_' + thisbuild['vercode']
+                    lastbuildpage = appid + '/lastbuild_' + build.vercode
                     newpage = site.Pages[lastbuildpage]
                     txt = "Build completed at " + time.strftime("%Y-%m-%d %H:%M:%SZ", time.gmtime()) + "\n\n" + wikilog
                     newpage.save(txt, summary='Build log')
@@ -1146,7 +1161,7 @@ def main():
                     logging.error("Error while attempting to publish build log")
 
     for app in build_succeeded:
-        logging.info("success: %s" % (app['id']))
+        logging.info("success: %s" % (app.id))
 
     if not options.verbose:
         for fa in failed_apps:
index a6b001301de4af0650445d484afb6eef3c6b85c8..d1dfc8ff5f6e37588a6750acde2c7936030e2cfd 100644 (file)
@@ -29,6 +29,7 @@ import traceback
 import HTMLParser
 from distutils.version import LooseVersion
 import logging
+import copy
 
 import common
 import metadata
@@ -43,10 +44,10 @@ def check_http(app):
 
     try:
 
-        if 'Update Check Data' not in app:
+        if not app.UpdateCheckData:
             raise FDroidException('Missing Update Check Data')
 
-        urlcode, codeex, urlver, verex = app['Update Check Data'].split('|')
+        urlcode, codeex, urlver, verex = app.UpdateCheckData.split('|')
 
         vercode = "99999999"
         if len(urlcode) > 0:
@@ -76,19 +77,10 @@ def check_http(app):
         return (version, vercode)
 
     except FDroidException:
-        msg = "Could not complete http check for app {0} due to unknown error: {1}".format(app['id'], traceback.format_exc())
+        msg = "Could not complete http check for app {0} due to unknown error: {1}".format(app.id, traceback.format_exc())
         return (None, msg)
 
 
-def app_matches_packagename(app, package):
-        if not package:
-            return False
-        appid = app['Update Check Name'] or app['id']
-        if appid == "Ignore":
-            return True
-        return appid == package
-
-
 # Check for a new version by looking at the tags in the source repo.
 # Whether this can be used reliably or not depends on
 # the development procedures used by the project's developers. Use it with
@@ -99,30 +91,30 @@ def check_tags(app, pattern):
 
     try:
 
-        if app['Repo Type'] == 'srclib':
-            build_dir = os.path.join('build', 'srclib', app['Repo'])
-            repotype = common.getsrclibvcs(app['Repo'])
+        if app.RepoType == 'srclib':
+            build_dir = os.path.join('build', 'srclib', app.Repo)
+            repotype = common.getsrclibvcs(app.Repo)
         else:
-            build_dir = os.path.join('build', app['id'])
-            repotype = app['Repo Type']
+            build_dir = os.path.join('build', app.id)
+            repotype = app.RepoType
 
         if repotype not in ('git', 'git-svn', 'hg', 'bzr'):
             return (None, 'Tags update mode only works for git, hg, bzr and git-svn repositories currently', None)
 
-        if repotype == 'git-svn' and ';' not in app['Repo']:
+        if repotype == 'git-svn' and ';' not in app.Repo:
             return (None, 'Tags update mode used in git-svn, but the repo was not set up with tags', None)
 
         # Set up vcs interface and make sure we have the latest code...
-        vcs = common.getvcs(app['Repo Type'], app['Repo'], build_dir)
+        vcs = common.getvcs(app.RepoType, app.Repo, build_dir)
 
         vcs.gotorevision(None)
 
-        flavours = []
-        if len(app['builds']) > 0:
-            if app['builds'][-1]['subdir']:
-                build_dir = os.path.join(build_dir, app['builds'][-1]['subdir'])
-            if app['builds'][-1]['gradle']:
-                flavours = app['builds'][-1]['gradle']
+        last_build = metadata.Build()
+        if len(app.builds) > 0:
+            last_build = app.builds[-1]
+
+        if last_build.submodules:
+            vcs.initsubmodules()
 
         hpak = None
         htag = None
@@ -130,13 +122,18 @@ def check_tags(app, pattern):
         hcode = "0"
 
         tags = vcs.gettags()
+        if not tags:
+            return (None, "No tags found", None)
+
         logging.debug("All tags: " + ','.join(tags))
         if pattern:
             pat = re.compile(pattern)
             tags = [tag for tag in tags if pat.match(tag)]
+            if not tags:
+                return (None, "No matching tags found", None)
             logging.debug("Matching tags: " + ','.join(tags))
 
-        if repotype in ('git',):
+        if len(tags) > 5 and repotype in ('git',):
             tags = vcs.latesttags(tags, 5)
             logging.debug("Latest tags: " + ','.join(tags))
 
@@ -144,20 +141,21 @@ def check_tags(app, pattern):
             logging.debug("Check tag: '{0}'".format(tag))
             vcs.gotorevision(tag)
 
-            # Only process tags where the manifest exists...
-            paths = common.manifest_paths(build_dir, flavours)
-            version, vercode, package = \
-                common.parse_androidmanifests(paths, app['Update Check Ignore'])
-            if not app_matches_packagename(app, package) or not version or not vercode:
-                continue
-
-            logging.debug("Manifest exists. Found version {0} ({1})"
-                          .format(version, vercode))
-            if int(vercode) > int(hcode):
-                hpak = package
-                htag = tag
-                hcode = str(int(vercode))
-                hver = version
+            for subdir in possible_subdirs(app):
+                if subdir == '.':
+                    root_dir = build_dir
+                else:
+                    root_dir = os.path.join(build_dir, subdir)
+                paths = common.manifest_paths(root_dir, last_build.gradle)
+                version, vercode, package = common.parse_androidmanifests(paths, app)
+                if vercode:
+                    logging.debug("Manifest exists in subdir '{0}'. Found version {1} ({2})"
+                                  .format(subdir, version, vercode))
+                    if int(vercode) > int(hcode):
+                        hpak = package
+                        htag = tag
+                        hcode = str(int(vercode))
+                        hver = version
 
         if not hpak:
             return (None, "Couldn't find package ID", None)
@@ -166,10 +164,10 @@ def check_tags(app, pattern):
         return (None, "Couldn't find any version information", None)
 
     except VCSException as vcse:
-        msg = "VCS error while scanning app {0}: {1}".format(app['id'], vcse)
+        msg = "VCS error while scanning app {0}: {1}".format(app.id, vcse)
         return (None, msg, None)
     except Exception:
-        msg = "Could not scan app {0} due to unknown error: {1}".format(app['id'], traceback.format_exc())
+        msg = "Could not scan app {0} due to unknown error: {1}".format(app.id, traceback.format_exc())
         return (None, msg, None)
 
 
@@ -183,15 +181,15 @@ def check_repomanifest(app, branch=None):
 
     try:
 
-        if app['Repo Type'] == 'srclib':
-            build_dir = os.path.join('build', 'srclib', app['Repo'])
-            repotype = common.getsrclibvcs(app['Repo'])
+        if app.RepoType == 'srclib':
+            build_dir = os.path.join('build', 'srclib', app.Repo)
+            repotype = common.getsrclibvcs(app.Repo)
         else:
-            build_dir = os.path.join('build', app['id'])
-            repotype = app['Repo Type']
+            build_dir = os.path.join('build', app.id)
+            repotype = app.RepoType
 
         # Set up vcs interface and make sure we have the latest code...
-        vcs = common.getvcs(app['Repo Type'], app['Repo'], build_dir)
+        vcs = common.getvcs(app.RepoType, app.Repo, build_dir)
 
         if repotype == 'git':
             if branch:
@@ -204,70 +202,70 @@ def check_repomanifest(app, branch=None):
         elif repotype == 'bzr':
             vcs.gotorevision(None)
 
-        flavours = []
-        if len(app['builds']) > 0:
-            if app['builds'][-1]['subdir']:
-                build_dir = os.path.join(build_dir, app['builds'][-1]['subdir'])
-            if app['builds'][-1]['gradle']:
-                flavours = app['builds'][-1]['gradle']
+        last_build = metadata.Build()
+        if len(app.builds) > 0:
+            last_build = app.builds[-1]
 
-        if not os.path.isdir(build_dir):
-            return (None, "Subdir '" + app['builds'][-1]['subdir'] + "'is not a valid directory")
+        if last_build.submodules:
+            vcs.initsubmodules()
 
-        paths = common.manifest_paths(build_dir, flavours)
+        hpak = None
+        hver = None
+        hcode = "0"
+        for subdir in possible_subdirs(app):
+            if subdir == '.':
+                root_dir = build_dir
+            else:
+                root_dir = os.path.join(build_dir, subdir)
+            paths = common.manifest_paths(root_dir, last_build.gradle)
+            version, vercode, package = common.parse_androidmanifests(paths, app)
+            if vercode:
+                logging.debug("Manifest exists in subdir '{0}'. Found version {1} ({2})"
+                              .format(subdir, version, vercode))
+                if int(vercode) > int(hcode):
+                    hpak = package
+                    hcode = str(int(vercode))
+                    hver = version
 
-        version, vercode, package = \
-            common.parse_androidmanifests(paths, app['Update Check Ignore'])
-        if not package:
+        if not hpak:
             return (None, "Couldn't find package ID")
-        if not app_matches_packagename(app, package):
-            return (None, "Package ID mismatch - got {0}".format(package))
-        if not version:
-            return (None, "Couldn't find latest version name")
-        if not vercode:
-            if "Ignore" == version:
-                return (None, "Latest version is ignored")
-            return (None, "Couldn't find latest version code")
-
-        vercode = str(int(vercode))
-
-        logging.debug("Manifest exists. Found version {0} ({1})".format(version, vercode))
-
-        return (version, vercode)
+        if hver:
+            return (hver, hcode)
+        return (None, "Couldn't find any version information")
 
     except VCSException as vcse:
-        msg = "VCS error while scanning app {0}: {1}".format(app['id'], vcse)
+        msg = "VCS error while scanning app {0}: {1}".format(app.id, vcse)
         return (None, msg)
     except Exception:
-        msg = "Could not scan app {0} due to unknown error: {1}".format(app['id'], traceback.format_exc())
+        msg = "Could not scan app {0} due to unknown error: {1}".format(app.id, traceback.format_exc())
         return (None, msg)
 
 
 def check_repotrunk(app, branch=None):
 
     try:
-        if app['Repo Type'] == 'srclib':
-            build_dir = os.path.join('build', 'srclib', app['Repo'])
-            repotype = common.getsrclibvcs(app['Repo'])
+        if app.RepoType == 'srclib':
+            build_dir = os.path.join('build', 'srclib', app.Repo)
+            repotype = common.getsrclibvcs(app.Repo)
         else:
-            build_dir = os.path.join('build', app['id'])
-            repotype = app['Repo Type']
+            build_dir = os.path.join('build', app.id)
+            repotype = app.RepoType
 
         if repotype not in ('git-svn', ):
             return (None, 'RepoTrunk update mode only makes sense in git-svn repositories')
 
         # Set up vcs interface and make sure we have the latest code...
-        vcs = common.getvcs(app['Repo Type'], app['Repo'], build_dir)
+        vcs = common.getvcs(app.RepoType, app.Repo, build_dir)
 
         vcs.gotorevision(None)
 
         ref = vcs.getref()
         return (ref, ref)
     except VCSException as vcse:
-        msg = "VCS error while scanning app {0}: {1}".format(app['id'], vcse)
+        msg = "VCS error while scanning app {0}: {1}".format(app.id, vcse)
         return (None, msg)
     except Exception:
-        msg = "Could not scan app {0} due to unknown error: {1}".format(app['id'], traceback.format_exc())
+        msg = "Could not scan app {0} due to unknown error: {1}".format(app.id, traceback.format_exc())
         return (None, msg)
 
 
@@ -276,7 +274,7 @@ def check_repotrunk(app, branch=None):
 # the details of the current version.
 def check_gplay(app):
     time.sleep(15)
-    url = 'https://play.google.com/store/apps/details?id=' + app['id']
+    url = 'https://play.google.com/store/apps/details?id=' + app.id
     headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:18.0) Gecko/20100101 Firefox/18.0'}
     req = urllib2.Request(url, None, headers)
     try:
@@ -313,61 +311,61 @@ def dirs_with_manifest(startdir):
 
 # Tries to find a new subdir starting from the root build_dir. Returns said
 # subdir relative to the build dir if found, None otherwise.
-def check_changed_subdir(app):
+def possible_subdirs(app):
 
-    if app['Repo Type'] == 'srclib':
-        build_dir = os.path.join('build', 'srclib', app['Repo'])
+    if app.RepoType == 'srclib':
+        build_dir = os.path.join('build', 'srclib', app.Repo)
     else:
-        build_dir = os.path.join('build', app['id'])
+        build_dir = os.path.join('build', app.id)
 
-    if not os.path.isdir(build_dir):
-        return None
-
-    flavours = []
-    if len(app['builds']) > 0 and app['builds'][-1]['gradle']:
-        flavours = app['builds'][-1]['gradle']
+    last_build = metadata.Build()
+    if len(app.builds) > 0:
+        last_build = app.builds[-1]
 
     for d in dirs_with_manifest(build_dir):
-        logging.debug("Trying possible dir %s." % d)
-        m_paths = common.manifest_paths(d, flavours)
-        package = common.parse_androidmanifests(m_paths, app['Update Check Ignore'])[2]
-        if app_matches_packagename(app, package):
-            logging.debug("Manifest exists in possible dir %s." % d)
-            return os.path.relpath(d, build_dir)
-
-    return None
+        m_paths = common.manifest_paths(d, last_build.gradle)
+        package = common.parse_androidmanifests(m_paths, app)[2]
+        if package is not None:
+            subdir = os.path.relpath(d, build_dir)
+            logging.debug("Adding possible subdir %s" % subdir)
+            yield subdir
 
 
 def fetch_autoname(app, tag):
 
-    if not app["Repo Type"] or app['Update Check Mode'] in ('None', 'Static'):
+    if not app.RepoType or app.UpdateCheckMode in ('None', 'Static'):
         return None
 
-    if app['Repo Type'] == 'srclib':
-        app_dir = os.path.join('build', 'srclib', app['Repo'])
+    if app.RepoType == 'srclib':
+        build_dir = os.path.join('build', 'srclib', app.Repo)
     else:
-        app_dir = os.path.join('build', app['id'])
+        build_dir = os.path.join('build', app.id)
 
     try:
-        vcs = common.getvcs(app["Repo Type"], app["Repo"], app_dir)
+        vcs = common.getvcs(app.RepoType, app.Repo, build_dir)
         vcs.gotorevision(tag)
     except VCSException:
         return None
 
-    flavours = []
-    if len(app['builds']) > 0:
-        if app['builds'][-1]['subdir']:
-            app_dir = os.path.join(app_dir, app['builds'][-1]['subdir'])
-        if app['builds'][-1]['gradle']:
-            flavours = app['builds'][-1]['gradle']
+    last_build = metadata.Build()
+    if len(app.builds) > 0:
+        last_build = app.builds[-1]
 
-    logging.debug("...fetch auto name from " + app_dir)
-    new_name = common.fetch_real_name(app_dir, flavours)
+    logging.debug("...fetch auto name from " + build_dir)
+    new_name = None
+    for subdir in possible_subdirs(app):
+        if subdir == '.':
+            root_dir = build_dir
+        else:
+            root_dir = os.path.join(build_dir, subdir)
+        new_name = common.fetch_real_name(root_dir, last_build.gradle)
+        if new_name is not None:
+            break
     commitmsg = None
     if new_name:
         logging.debug("...got autoname '" + new_name + "'")
-        if new_name != app['Auto Name']:
-            app['Auto Name'] = new_name
+        if new_name != app.AutoName:
+            app.AutoName = new_name
             if not commitmsg:
                 commitmsg = "Set autoname of {0}".format(common.getappname(app))
     else:
@@ -386,7 +384,7 @@ def checkupdates_app(app, first=True):
     msg = None
     vercode = None
     noverok = False
-    mode = app['Update Check Mode']
+    mode = app.UpdateCheckMode
     if mode.startswith('Tags'):
         pattern = mode[5:] if len(mode) > 4 else None
         (version, vercode, tag) = check_tags(app, pattern)
@@ -412,24 +410,9 @@ def checkupdates_app(app, first=True):
         version = None
         msg = 'Invalid update check method'
 
-    if first and version is None and vercode == "Couldn't find package ID":
-        logging.warn("Couldn't find any version information. Looking for a subdir change...")
-        new_subdir = check_changed_subdir(app)
-        if new_subdir is None:
-            logging.warn("Couldn't find any new subdir.")
-        else:
-            logging.warn("Trying a new subdir: %s" % new_subdir)
-            new_build = {}
-            metadata.fill_build_defaults(new_build)
-            new_build['version'] = "Ignore"
-            new_build['vercode'] = "-1"
-            new_build['subdir'] = new_subdir
-            app['builds'].append(new_build)
-            return checkupdates_app(app, first=False)
-
-    if version and vercode and app['Vercode Operation']:
+    if version and vercode and app.VercodeOperation:
         oldvercode = str(int(vercode))
-        op = app['Vercode Operation'].replace("%c", oldvercode)
+        op = app.VercodeOperation.replace("%c", oldvercode)
         vercode = str(eval(op))
         logging.debug("Applied vercode operation: %s -> %s" % (oldvercode, vercode))
 
@@ -441,16 +424,16 @@ def checkupdates_app(app, first=True):
 
     updating = False
     if version is None:
-        logmsg = "...{0} : {1}".format(app['id'], msg)
+        logmsg = "...{0} : {1}".format(app.id, msg)
         if noverok:
             logging.info(logmsg)
         else:
             logging.warn(logmsg)
-    elif vercode == app['Current Version Code']:
+    elif vercode == app.CurrentVersionCode:
         logging.info("...up to date")
     else:
-        app['Current Version'] = version
-        app['Current Version Code'] = str(int(vercode))
+        app.CurrentVersion = version
+        app.CurrentVersionCode = str(int(vercode))
         updating = True
 
     commitmsg = fetch_autoname(app, tag)
@@ -462,7 +445,7 @@ def checkupdates_app(app, first=True):
         commitmsg = 'Update CV of %s to %s' % (name, ver)
 
     if options.auto:
-        mode = app['Auto Update Mode']
+        mode = app.AutoUpdateMode
         if mode in ('None', 'Static'):
             pass
         elif mode.startswith('Version '):
@@ -476,37 +459,35 @@ def checkupdates_app(app, first=True):
                 suffix = ''
             gotcur = False
             latest = None
-            for build in app['builds']:
-                if build['vercode'] == app['Current Version Code']:
+            for build in app.builds:
+                if int(build.vercode) >= int(app.CurrentVersionCode):
                     gotcur = True
-                if not latest or int(build['vercode']) > int(latest['vercode']):
+                if not latest or int(build.vercode) > int(latest.vercode):
                     latest = build
 
-            if int(latest['vercode']) > int(app['Current Version Code']):
+            if int(latest.vercode) > int(app.CurrentVersionCode):
                 logging.info("Refusing to auto update, since the latest build is newer")
 
             if not gotcur:
-                newbuild = latest.copy()
-                if 'origlines' in newbuild:
-                    del newbuild['origlines']
-                newbuild['disable'] = False
-                newbuild['vercode'] = app['Current Version Code']
-                newbuild['version'] = app['Current Version'] + suffix
-                logging.info("...auto-generating build for " + newbuild['version'])
-                commit = pattern.replace('%v', newbuild['version'])
-                commit = commit.replace('%c', newbuild['vercode'])
-                newbuild['commit'] = commit
-                app['builds'].append(newbuild)
+                newbuild = copy.deepcopy(latest)
+                newbuild.disable = False
+                newbuild.vercode = app.CurrentVersionCode
+                newbuild.version = app.CurrentVersion + suffix
+                logging.info("...auto-generating build for " + newbuild.version)
+                commit = pattern.replace('%v', newbuild.version)
+                commit = commit.replace('%c', newbuild.vercode)
+                newbuild.commit = commit
+                app.builds.append(newbuild)
                 name = common.getappname(app)
                 ver = common.getcvname(app)
                 commitmsg = "Update %s to %s" % (name, ver)
         else:
-            logging.warn('Invalid auto update mode "' + mode + '" on ' + app['id'])
+            logging.warn('Invalid auto update mode "' + mode + '" on ' + app.id)
 
     if commitmsg:
-        metadatapath = os.path.join('metadata', app['id'] + '.txt')
+        metadatapath = os.path.join('metadata', app.id + '.txt')
         with open(metadatapath, 'w') as f:
-            metadata.write_metadata(f, app)
+            metadata.write_metadata('txt', f, app)
         if options.commit:
             logging.info("Commiting update for " + metadatapath)
             gitcmd = ["git", "commit", "-m", commitmsg]
@@ -556,7 +537,7 @@ def main():
                 else:
                     logging.info("{0} encountered a problem: {1}".format(common.getappname(app), reason))
             if version is not None:
-                stored = app['Current Version']
+                stored = app.CurrentVersion
                 if not stored:
                     logging.info("{0} has no Current Version but has version {1} on the Play Store"
                                  .format(common.getappname(app), version))
@@ -574,7 +555,7 @@ def main():
 
     for appid, app in apps.iteritems():
 
-        if options.autoonly and app['Auto Update Mode'] in ('None', 'Static'):
+        if options.autoonly and app.AutoUpdateMode in ('None', 'Static'):
             logging.debug("Nothing to do for {0}...".format(appid))
             continue
 
index 67885fd6791976db0aab496e2e5f9d3e25d90ccd..92e501775a531d3e85fbbd84d6a78046673df9b2 100644 (file)
@@ -56,7 +56,11 @@ default_config = {
         'r9b': None,
         'r10e': "$ANDROID_NDK",
     },
-    'build_tools': "23.0.1",
+    'build_tools': "23.0.2",
+    'java_paths': {
+        '1.7': "/usr/lib/jvm/java-7-openjdk",
+        '1.8': None,
+    },
     'ant': "ant",
     'mvn3': "mvn",
     'gradle': 'gradle',
@@ -122,7 +126,7 @@ def fill_config_defaults(thisconfig):
             thisconfig[k] = exp
             thisconfig[k + '_orig'] = v
 
-    for k in ['ndk_paths']:
+    for k in ['ndk_paths', 'java_paths']:
         d = thisconfig[k]
         for k2 in d.copy():
             v = d[k2]
@@ -185,6 +189,11 @@ def read_config(opts, config_file='config.py'):
     for n in ['ANDROID_HOME', 'ANDROID_SDK']:
         env[n] = config['sdk_path']
 
+    for v in ['7', '8']:
+        cpath = config['java_paths']['1.%s' % v]
+        if cpath:
+            env['JAVA%s_HOME' % v] = cpath
+
     for k in ["keystorepass", "keypass"]:
         if k in config:
             write_password_file(k)
@@ -212,15 +221,6 @@ def read_config(opts, config_file='config.py'):
     return config
 
 
-def get_ndk_path(version):
-    if version is None:
-        version = 'r10e'  # falls back to latest
-    paths = config['ndk_paths']
-    if version not in paths:
-        return ''
-    return paths[version] or ''
-
-
 def find_sdk_tools_cmd(cmd):
     '''find a working path to a tool from the Android SDK'''
 
@@ -354,10 +354,10 @@ def read_app_args(args, allapps, allow_vercodes=False):
         vc = vercodes[appid]
         if not vc:
             continue
-        app['builds'] = [b for b in app['builds'] if b['vercode'] in vc]
-        if len(app['builds']) != len(vercodes[appid]):
+        app.builds = [b for b in app.builds if b.vercode in vc]
+        if len(app.builds) != len(vercodes[appid]):
             error = True
-            allvcs = [b['vercode'] for b in app['builds']]
+            allvcs = [b.vercode for b in app.builds]
             for v in vercodes[appid]:
                 if v not in allvcs:
                     logging.critical("No such vercode %s for app %s" % (v, appid))
@@ -369,17 +369,18 @@ 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):
-    return ext == get_extension(filename)
+    _, f_ext = get_extension(filename)
+    return ext == f_ext
 
 
-apk_regex = None
+apk_regex = re.compile(r"^(.+)_([0-9]+)\.apk$")
 
 
 def clean_description(description):
@@ -396,10 +397,7 @@ def clean_description(description):
 
 
 def apknameinfo(filename):
-    global apk_regex
     filename = os.path.basename(filename)
-    if apk_regex is None:
-        apk_regex = re.compile(r"^(.+)_([0-9]+)\.apk$")
     m = apk_regex.match(filename)
     try:
         result = (m.group(1), m.group(2))
@@ -409,23 +407,23 @@ def apknameinfo(filename):
 
 
 def getapkname(app, build):
-    return "%s_%s.apk" % (app['id'], build['vercode'])
+    return "%s_%s.apk" % (app.id, build.vercode)
 
 
 def getsrcname(app, build):
-    return "%s_%s_src.tar.gz" % (app['id'], build['vercode'])
+    return "%s_%s_src.tar.gz" % (app.id, build.vercode)
 
 
 def getappname(app):
-    if app['Name']:
-        return app['Name']
-    if app['Auto Name']:
-        return app['Auto Name']
-    return app['id']
+    if app.Name:
+        return app.Name
+    if app.AutoName:
+        return app.AutoName
+    return app.id
 
 
 def getcvname(app):
-    return '%s (%s)' % (app['Current Version'], app['Current Version Code'])
+    return '%s (%s)' % (app.CurrentVersion, app.CurrentVersionCode)
 
 
 def getvcs(vcstype, remote, local):
@@ -648,6 +646,8 @@ class vcs_git(vcs):
             for line in lines:
                 if 'git@github.com' in line:
                     line = line.replace('git@github.com:', 'https://github.com/')
+                if 'git@gitlab.com' in line:
+                    line = line.replace('git@gitlab.com:', 'https://gitlab.com/')
                 f.write(line)
 
         p = FDroidPopen(['git', 'submodule', 'sync'], cwd=self.local, output=False)
@@ -883,6 +883,8 @@ class vcs_bzr(vcs):
 
 
 def unescape_string(string):
+    if len(string) < 2:
+        return string
     if string[0] == '"' and string[-1] == '"':
         return string[1:-1]
 
@@ -891,6 +893,9 @@ def unescape_string(string):
 
 def retrieve_string(app_dir, string, xmlfiles=None):
 
+    if not string.startswith('@string/'):
+        return unescape_string(string)
+
     if xmlfiles is None:
         xmlfiles = []
         for res_dir in [
@@ -901,18 +906,22 @@ def retrieve_string(app_dir, string, xmlfiles=None):
                 if os.path.basename(r) == 'values':
                     xmlfiles += [os.path.join(r, x) for x in f if x.endswith('.xml')]
 
-    if not string.startswith('@string/'):
-        return unescape_string(string)
-
     name = string[len('@string/'):]
 
+    def element_content(element):
+        if element.text is None:
+            return ""
+        s = XMLElementTree.tostring(element, encoding='utf-8', method='text')
+        return s.strip()
+
     for path in xmlfiles:
         if not os.path.isfile(path):
             continue
         xml = parse_xml(path)
         element = xml.find('string[@name="' + name + '"]')
-        if element is not None and element.text is not None:
-            return retrieve_string(app_dir, element.text.encode('utf-8'), xmlfiles)
+        if element is not None:
+            content = element_content(element)
+            return retrieve_string(app_dir, content, xmlfiles)
 
     return ''
 
@@ -947,6 +956,8 @@ def fetch_real_name(app_dir, flavours):
         logging.debug("fetch_real_name: Checking manifest at " + path)
         xml = parse_xml(path)
         app = xml.find('application')
+        if app is None:
+            continue
         if "{http://schemas.android.com/apk/res/android}label" not in app.attrib:
             continue
         label = app.attrib["{http://schemas.android.com/apk/res/android}label"].encode('utf-8')
@@ -995,20 +1006,31 @@ def remove_debuggable_flags(root_dir):
                         os.path.join(root, 'AndroidManifest.xml'))
 
 
+vcsearch_g = re.compile(r'.*versionCode *=* *["\']*([0-9]+)["\']*').search
+vnsearch_g = re.compile(r'.*versionName *=* *(["\'])((?:(?=(\\?))\3.)*?)\1.*').search
+psearch_g = re.compile(r'.*(packageName|applicationId) *=* *["\']([^"]+)["\'].*').search
+
+
+def app_matches_packagename(app, package):
+    if not package:
+        return False
+    appid = app.UpdateCheckName or app.id
+    if appid is None or appid == "Ignore":
+        return True
+    return appid == package
+
+
 # Extract some information from the AndroidManifest.xml at the given path.
 # Returns (version, vercode, package), any or all of which might be None.
 # All values returned are strings.
-def parse_androidmanifests(paths, ignoreversions=None):
+def parse_androidmanifests(paths, app):
+
+    ignoreversions = app.UpdateCheckIgnore
+    ignoresearch = re.compile(ignoreversions).search if ignoreversions else None
 
     if not paths:
         return (None, None, None)
 
-    vcsearch_g = re.compile(r'.*versionCode *=* *["\']*([0-9]+)["\']*').search
-    vnsearch_g = re.compile(r'.*versionName *=* *(["\'])((?:(?=(\\?))\3.)*?)\1.*').search
-    psearch_g = re.compile(r'.*(packageName|applicationId) *=* *["\']([^"]+)["\'].*').search
-
-    ignoresearch = re.compile(ignoreversions).search if ignoreversions else None
-
     max_version = None
     max_vercode = None
     max_package = None
@@ -1033,7 +1055,9 @@ def parse_androidmanifests(paths, ignoreversions=None):
                 if not package:
                     matches = psearch_g(line)
                     if matches:
-                        package = matches.group(2)
+                        s = matches.group(2)
+                        if app_matches_packagename(app, s):
+                            package = s
                 if not version:
                     matches = vnsearch_g(line)
                     if matches:
@@ -1045,7 +1069,9 @@ def parse_androidmanifests(paths, ignoreversions=None):
         else:
             xml = parse_xml(path)
             if "package" in xml.attrib:
-                package = xml.attrib["package"].encode('utf-8')
+                s = xml.attrib["package"].encode('utf-8')
+                if app_matches_packagename(app, s):
+                    package = s
             if "{http://schemas.android.com/apk/res/android}versionName" in xml.attrib:
                 version = xml.attrib["{http://schemas.android.com/apk/res/android}versionName"].encode('utf-8')
                 base_dir = os.path.dirname(path)
@@ -1099,14 +1125,16 @@ class FDroidException(Exception):
         self.value = value
         self.detail = detail
 
+    def shortened_detail(self):
+        if len(self.detail) < 16000:
+            return self.detail
+        return '[...]\n' + self.detail[-16000:]
+
     def get_wikitext(self):
         ret = repr(self.value) + "\n"
         if self.detail:
             ret += "=detail=\n"
-            ret += "<pre>\n"
-            txt = self.detail[-8192:] if len(self.detail) > 8192 else self.detail
-            ret += str(txt)
-            ret += "</pre>\n"
+            ret += "<pre>\n" + self.shortened_detail() + "</pre>\n"
         return ret
 
     def __str__(self):
@@ -1190,6 +1218,8 @@ def getsrclib(spec, srclib_dir, subdir=None, basepath=False,
 
     return (name, number, libdir)
 
+gradle_version_regex = re.compile(r"[^/]*'com\.android\.tools\.build:gradle:([^\.]+\.[^\.]+).*'.*")
+
 
 # Prepare the source code for a particular build
 #  'vcs'         - the appropriate vcs object for the application
@@ -1208,17 +1238,17 @@ def getsrclib(spec, srclib_dir, subdir=None, basepath=False,
 def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=False, refresh=True):
 
     # Optionally, the actual app source can be in a subdirectory
-    if build['subdir']:
-        root_dir = os.path.join(build_dir, build['subdir'])
+    if build.subdir:
+        root_dir = os.path.join(build_dir, build.subdir)
     else:
         root_dir = build_dir
 
     # Get a working copy of the right revision
-    logging.info("Getting source for revision " + build['commit'])
-    vcs.gotorevision(build['commit'], refresh)
+    logging.info("Getting source for revision " + build.commit)
+    vcs.gotorevision(build.commit, refresh)
 
     # Initialise submodules if required
-    if build['submodules']:
+    if build.submodules:
         logging.info("Initialising submodules")
         vcs.initsubmodules()
 
@@ -1228,31 +1258,31 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
         raise BuildException('Missing subdir ' + root_dir)
 
     # Run an init command if one is required
-    if build['init']:
-        cmd = replace_config_vars(build['init'], build)
+    if build.init:
+        cmd = replace_config_vars(build.init, build)
         logging.info("Running 'init' commands in %s" % root_dir)
 
         p = FDroidPopen(['bash', '-x', '-c', cmd], cwd=root_dir)
         if p.returncode != 0:
             raise BuildException("Error running init command for %s:%s" %
-                                 (app['id'], build['version']), p.output)
+                                 (app.id, build.version), p.output)
 
     # Apply patches if any
-    if build['patch']:
+    if build.patch:
         logging.info("Applying patches")
-        for patch in build['patch']:
+        for patch in build.patch:
             patch = patch.strip()
             logging.info("Applying " + patch)
-            patch_path = os.path.join('metadata', app['id'], patch)
+            patch_path = os.path.join('metadata', app.id, patch)
             p = FDroidPopen(['patch', '-p1', '-i', os.path.abspath(patch_path)], cwd=build_dir)
             if p.returncode != 0:
                 raise BuildException("Failed to apply patch %s" % patch_path)
 
     # Get required source libraries
     srclibpaths = []
-    if build['srclibs']:
+    if build.srclibs:
         logging.info("Collecting source libraries")
-        for lib in build['srclibs']:
+        for lib in build.srclibs:
             srclibpaths.append(getsrclib(lib, srclib_dir, build, preponly=onserver, refresh=refresh))
 
     for name, number, libpath in srclibpaths:
@@ -1265,8 +1295,12 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
 
     # Update the local.properties file
     localprops = [os.path.join(build_dir, 'local.properties')]
-    if build['subdir']:
-        localprops += [os.path.join(root_dir, 'local.properties')]
+    if build.subdir:
+        parts = build.subdir.split(os.sep)
+        cur = build_dir
+        for d in parts:
+            cur = os.path.join(cur, d)
+            localprops += [os.path.join(cur, 'local.properties')]
     for path in localprops:
         props = ""
         if os.path.isfile(path):
@@ -1278,28 +1312,28 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
             logging.info("Creating local.properties file at %s" % path)
         # Fix old-fashioned 'sdk-location' by copying
         # from sdk.dir, if necessary
-        if build['oldsdkloc']:
+        if build.oldsdkloc:
             sdkloc = re.match(r".*^sdk.dir=(\S+)$.*", props,
                               re.S | re.M).group(1)
             props += "sdk-location=%s\n" % sdkloc
         else:
             props += "sdk.dir=%s\n" % config['sdk_path']
             props += "sdk-location=%s\n" % config['sdk_path']
-        if build['ndk_path']:
+        ndk_path = build.ndk_path()
+        if ndk_path:
             # Add ndk location
-            props += "ndk.dir=%s\n" % build['ndk_path']
-            props += "ndk-location=%s\n" % build['ndk_path']
+            props += "ndk.dir=%s\n" % ndk_path
+            props += "ndk-location=%s\n" % ndk_path
         # Add java.encoding if necessary
-        if build['encoding']:
-            props += "java.encoding=%s\n" % build['encoding']
+        if build.encoding:
+            props += "java.encoding=%s\n" % build.encoding
         with open(path, 'w') as f:
             f.write(props)
 
     flavours = []
-    if build['type'] == 'gradle':
-        flavours = build['gradle']
+    if build.method() == 'gradle':
+        flavours = build.gradle
 
-        version_regex = re.compile(r"[^/]*'com\.android\.tools\.build:gradle:([^\.]+\.[^\.]+).*'.*")
         gradlepluginver = None
 
         gradle_dirs = [root_dir]
@@ -1321,19 +1355,19 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
                 if not os.path.isfile(path):
                     continue
                 for line in file(path):
-                    match = version_regex.match(line)
+                    match = gradle_version_regex.match(line)
                     if match:
                         gradlepluginver = match.group(1)
                         break
 
         if gradlepluginver:
-            build['gradlepluginver'] = LooseVersion(gradlepluginver)
+            build.gradlepluginver = LooseVersion(gradlepluginver)
         else:
             logging.warn("Could not fetch the gradle plugin version, defaulting to 0.11")
-            build['gradlepluginver'] = LooseVersion('0.11')
+            build.gradlepluginver = LooseVersion('0.11')
 
-        if build['target']:
-            n = build["target"].split('-')[1]
+        if build.target:
+            n = build.target.split('-')[1]
             regsub_file(r'compileSdkVersion[ =]+[0-9]+',
                         r'compileSdkVersion %s' % n,
                         os.path.join(root_dir, 'build.gradle'))
@@ -1342,38 +1376,38 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
     remove_debuggable_flags(root_dir)
 
     # Insert version code and number into the manifest if necessary
-    if build['forceversion']:
+    if build.forceversion:
         logging.info("Changing the version name")
         for path in manifest_paths(root_dir, flavours):
             if not os.path.isfile(path):
                 continue
             if has_extension(path, 'xml'):
                 regsub_file(r'android:versionName="[^"]*"',
-                            r'android:versionName="%s"' % build['version'],
+                            r'android:versionName="%s"' % build.version,
                             path)
             elif has_extension(path, 'gradle'):
                 regsub_file(r"""(\s*)versionName[\s'"=]+.*""",
-                            r"""\1versionName '%s'""" % build['version'],
+                            r"""\1versionName '%s'""" % build.version,
                             path)
 
-    if build['forcevercode']:
+    if build.forcevercode:
         logging.info("Changing the version code")
         for path in manifest_paths(root_dir, flavours):
             if not os.path.isfile(path):
                 continue
             if has_extension(path, 'xml'):
                 regsub_file(r'android:versionCode="[^"]*"',
-                            r'android:versionCode="%s"' % build['vercode'],
+                            r'android:versionCode="%s"' % build.vercode,
                             path)
             elif has_extension(path, 'gradle'):
                 regsub_file(r'versionCode[ =]+[0-9]+',
-                            r'versionCode %s' % build['vercode'],
+                            r'versionCode %s' % build.vercode,
                             path)
 
     # Delete unwanted files
-    if build['rm']:
+    if build.rm:
         logging.info("Removing specified files")
-        for part in getpaths(build_dir, build, 'rm'):
+        for part in getpaths(build_dir, build.rm):
             dest = os.path.join(build_dir, part)
             logging.info("Removing {0}".format(part))
             if os.path.lexists(dest):
@@ -1387,12 +1421,12 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
     remove_signing_keys(build_dir)
 
     # Add required external libraries
-    if build['extlibs']:
+    if build.extlibs:
         logging.info("Collecting prebuilt libraries")
         libsdir = os.path.join(root_dir, 'libs')
         if not os.path.exists(libsdir):
             os.mkdir(libsdir)
-        for lib in build['extlibs']:
+        for lib in build.extlibs:
             lib = lib.strip()
             logging.info("...installing extlib {0}".format(lib))
             libf = os.path.basename(lib)
@@ -1402,10 +1436,10 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
             shutil.copyfile(libsrc, os.path.join(libsdir, libf))
 
     # Run a pre-build command if one is required
-    if build['prebuild']:
+    if build.prebuild:
         logging.info("Running 'prebuild' commands in %s" % root_dir)
 
-        cmd = replace_config_vars(build['prebuild'], build)
+        cmd = replace_config_vars(build.prebuild, build)
 
         # Substitute source library paths into prebuild commands
         for name, number, libpath in srclibpaths:
@@ -1415,20 +1449,20 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
         p = FDroidPopen(['bash', '-x', '-c', cmd], cwd=root_dir)
         if p.returncode != 0:
             raise BuildException("Error running prebuild command for %s:%s" %
-                                 (app['id'], build['version']), p.output)
+                                 (app.id, build.version), p.output)
 
     # Generate (or update) the ant build file, build.xml...
-    if build['update'] and build['update'] != ['no'] and build['type'] == 'ant':
+    if build.method() == 'ant' and build.update != ['no']:
         parms = ['android', 'update', 'lib-project']
         lparms = ['android', 'update', 'project']
 
-        if build['target']:
-            parms += ['-t', build['target']]
-            lparms += ['-t', build['target']]
-        if build['update'] == ['auto']:
-            update_dirs = ant_subprojects(root_dir) + ['.']
+        if build.target:
+            parms += ['-t', build.target]
+            lparms += ['-t', build.target]
+        if build.update:
+            update_dirs = build.update
         else:
-            update_dirs = build['update']
+            update_dirs = ant_subprojects(root_dir) + ['.']
 
         for d in update_dirs:
             subdir = os.path.join(root_dir, d)
@@ -1452,14 +1486,27 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
     return (root_dir, srclibpaths)
 
 
-# Split and extend via globbing the paths from a field
-def getpaths(build_dir, build, field):
-    paths = []
-    for p in build[field]:
+# Extend via globbing the paths from a field and return them as a map from
+# original path to resulting paths
+def getpaths_map(build_dir, globpaths):
+    paths = dict()
+    for p in globpaths:
         p = p.strip()
         full_path = os.path.join(build_dir, p)
         full_path = os.path.normpath(full_path)
-        paths += [r[len(build_dir) + 1:] for r in glob.glob(full_path)]
+        paths[p] = [r[len(build_dir) + 1:] for r in glob.glob(full_path)]
+        if not paths[p]:
+            raise FDroidException("glob path '%s' did not match any files/dirs" % p)
+    return paths
+
+
+# Extend via globbing the paths from a field and return them as a set
+def getpaths(build_dir, globpaths):
+    paths_map = getpaths_map(build_dir, globpaths)
+    paths = set()
+    for k, v in paths_map.iteritems():
+        for p in v:
+            paths.add(p)
     return paths
 
 
@@ -1559,7 +1606,11 @@ def SdkToolsPopen(commands, cwd=None, output=True):
     cmd = commands[0]
     if cmd not in config:
         config[cmd] = find_sdk_tools_cmd(commands[0])
-    return FDroidPopen([config[cmd]] + commands[1:],
+    abscmd = config[cmd]
+    if abscmd is None:
+        logging.critical("Could not find '%s' on your system" % cmd)
+        sys.exit(1)
+    return FDroidPopen([abscmd] + commands[1:],
                        cwd=cwd, output=output)
 
 
@@ -1608,17 +1659,17 @@ def FDroidPopen(commands, cwd=None, output=True):
 
 
 gradle_comment = re.compile(r'[ ]*//')
+gradle_signing_configs = re.compile(r'^[\t ]*signingConfigs[ \t]*{[ \t]*$')
+gradle_line_matches = [
+    re.compile(r'^[\t ]*signingConfig [^ ]*$'),
+    re.compile(r'.*android\.signingConfigs\.[^{]*$'),
+    re.compile(r'.*variant\.outputFile = .*'),
+    re.compile(r'.*output\.outputFile = .*'),
+    re.compile(r'.*\.readLine\(.*'),
+]
 
 
 def remove_signing_keys(build_dir):
-    signing_configs = re.compile(r'^[\t ]*signingConfigs[ \t]*{[ \t]*$')
-    line_matches = [
-        re.compile(r'^[\t ]*signingConfig [^ ]*$'),
-        re.compile(r'.*android\.signingConfigs\.[^{]*$'),
-        re.compile(r'.*variant\.outputFile = .*'),
-        re.compile(r'.*output\.outputFile = .*'),
-        re.compile(r'.*\.readLine\(.*'),
-    ]
     for root, dirs, files in os.walk(build_dir):
         if 'build.gradle' in files:
             path = os.path.join(root, 'build.gradle')
@@ -1647,12 +1698,12 @@ def remove_signing_keys(build_dir):
                         opened -= line.count('}')
                         continue
 
-                    if signing_configs.match(line):
+                    if gradle_signing_configs.match(line):
                         changed = True
                         opened += 1
                         continue
 
-                    if any(s.match(line) for s in line_matches):
+                    if any(s.match(line) for s in gradle_line_matches):
                         changed = True
                         continue
 
@@ -1708,9 +1759,9 @@ def replace_config_vars(cmd, build):
     cmd = cmd.replace('$$NDK$$', env['ANDROID_NDK'])
     cmd = cmd.replace('$$MVN3$$', config['mvn3'])
     if build is not None:
-        cmd = cmd.replace('$$COMMIT$$', build['commit'])
-        cmd = cmd.replace('$$VERSION$$', build['version'])
-        cmd = cmd.replace('$$VERCODE$$', build['vercode'])
+        cmd = cmd.replace('$$COMMIT$$', build.commit)
+        cmd = cmd.replace('$$VERSION$$', build.version)
+        cmd = cmd.replace('$$VERCODE$$', build.vercode)
     return cmd
 
 
@@ -1736,6 +1787,8 @@ def place_srclib(root_dir, number, libpath):
         if not placed:
             o.write('android.library.reference.%d=%s\n' % (number, relpath))
 
+apk_sigfile = re.compile(r'META-INF/[0-9A-Za-z]+\.(SF|RSA)')
+
 
 def verify_apks(signed_apk, unsigned_apk, tmp_dir):
     """Verify that two apks are the same
@@ -1750,11 +1803,10 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir):
     :returns: None if the verification is successful, otherwise a string
               describing what went wrong.
     """
-    sigfile = re.compile(r'META-INF/[0-9A-Za-z]+\.(SF|RSA)')
     with ZipFile(signed_apk) as signed_apk_as_zip:
         meta_inf_files = ['META-INF/MANIFEST.MF']
         for f in signed_apk_as_zip.namelist():
-            if sigfile.match(f):
+            if apk_sigfile.match(f):
                 meta_inf_files.append(f)
         if len(meta_inf_files) < 3:
             return "Signature files missing from {0}".format(signed_apk)
@@ -1769,6 +1821,8 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir):
     logging.info("...successfully verified")
     return None
 
+apk_badchars = re.compile('''[/ :;'"]''')
+
 
 def compare_apks(apk1, apk2, tmp_dir):
     """Compare two apks
@@ -1778,9 +1832,8 @@ def compare_apks(apk1, apk2, tmp_dir):
     trying to do the comparison.
     """
 
-    badchars = re.compile('''[/ :;'"]''')
-    apk1dir = os.path.join(tmp_dir, badchars.sub('_', apk1[0:-4]))  # trim .apk
-    apk2dir = os.path.join(tmp_dir, badchars.sub('_', apk2[0:-4]))  # trim .apk
+    apk1dir = os.path.join(tmp_dir, apk_badchars.sub('_', apk1[0:-4]))  # trim .apk
+    apk2dir = os.path.join(tmp_dir, apk_badchars.sub('_', apk2[0:-4]))  # trim .apk
     for d in [apk1dir, apk2dir]:
         if os.path.exists(d):
             shutil.rmtree(d)
index 9841c7a138a094f0ba13335b27d4ba119475d2ce..e1d69c3c3eb91f63bcbf65469775d74ff8404735 100644 (file)
@@ -79,20 +79,20 @@ def get_metadata_from_url(app, url):
 
     # Figure out what kind of project it is...
     projecttype = None
-    app['Web Site'] = url  # by default, we might override it
+    app.WebSite = url  # by default, we might override it
     if url.startswith('git://'):
         projecttype = 'git'
         repo = url
         repotype = 'git'
-        app['Source Code'] = ""
-        app['Web Site'] = ""
+        app.SourceCode = ""
+        app.WebSite = ""
     elif url.startswith('https://github.com'):
         projecttype = 'github'
         repo = url
         repotype = 'git'
-        app['Source Code'] = url
-        app['issuetracker'] = url + '/issues'
-        app['Web Site'] = ""
+        app.SourceCode = url
+        app.IssueTracker = url + '/issues'
+        app.WebSite = ""
     elif url.startswith('https://gitlab.com/'):
         projecttype = 'gitlab'
         # git can be fussy with gitlab URLs unless they end in .git
@@ -101,16 +101,16 @@ def get_metadata_from_url(app, url):
         else:
             repo = url + '.git'
         repotype = 'git'
-        app['Source Code'] = url + '/tree/HEAD'
-        app['issuetracker'] = url + '/issues'
+        app.SourceCode = url + '/tree/HEAD'
+        app.IssueTracker = url + '/issues'
     elif url.startswith('https://bitbucket.org/'):
         if url.endswith('/'):
             url = url[:-1]
         projecttype = 'bitbucket'
-        app['Source Code'] = url + '/src'
-        app['issuetracker'] = url + '/issues'
+        app.SourceCode = url + '/src'
+        app.IssueTracker = url + '/issues'
         # Figure out the repo type and adddress...
-        repotype, repo = getrepofrompage(app['Source Code'])
+        repotype, repo = getrepofrompage(app.SourceCode)
         if not repotype:
             logging.error("Unable to determine vcs type. " + repo)
             sys.exit(1)
@@ -132,28 +132,28 @@ def get_metadata_from_url(app, url):
 
     # Get a copy of the source so we can extract some info...
     logging.info('Getting source from ' + repotype + ' repo at ' + repo)
-    src_dir = os.path.join(tmp_dir, 'importer')
-    if os.path.exists(src_dir):
-        shutil.rmtree(src_dir)
-    vcs = common.getvcs(repotype, repo, src_dir)
+    build_dir = os.path.join(tmp_dir, 'importer')
+    if os.path.exists(build_dir):
+        shutil.rmtree(build_dir)
+    vcs = common.getvcs(repotype, repo, build_dir)
     vcs.gotorevision(options.rev)
-    root_dir = get_subdir(src_dir)
+    root_dir = get_subdir(build_dir)
 
-    app['Repo Type'] = repotype
-    app['Repo'] = repo
+    app.RepoType = repotype
+    app.Repo = repo
 
-    return root_dir, src_dir
+    return root_dir, build_dir
 
 
 config = None
 options = None
 
 
-def get_subdir(src_dir):
+def get_subdir(build_dir):
     if options.subdir:
-        return os.path.join(src_dir, options.subdir)
+        return os.path.join(build_dir, options.subdir)
 
-    return src_dir
+    return build_dir
 
 
 def main():
@@ -174,17 +174,17 @@ def main():
     config = common.read_config(options)
 
     apps = metadata.read_metadata()
-    package, app = metadata.get_default_app_info_list(apps)
-    app['Update Check Mode'] = "Tags"
+    app = metadata.App()
+    app.UpdateCheckMode = "Tags"
 
     root_dir = None
-    src_dir = None
+    build_dir = None
 
     if options.url:
-        root_dir, src_dir = get_metadata_from_url(app, options.url)
+        root_dir, build_dir = get_metadata_from_url(app, options.url)
     elif os.path.isdir('.git'):
         if options.url:
-            app['Web Site'] = options.url
+            app.WebSite = options.url
         root_dir = get_subdir(os.getcwd())
     else:
         logging.error("Specify project url.")
@@ -194,7 +194,7 @@ def main():
     paths = common.manifest_paths(root_dir, [])
     if paths:
 
-        version, vercode, package = common.parse_androidmanifests(paths)
+        version, vercode, package = common.parse_androidmanifests(paths, app)
         if not package:
             logging.error("Couldn't find package ID")
             sys.exit(1)
@@ -222,34 +222,29 @@ def main():
         sys.exit(1)
 
     # Create a build line...
-    build = {}
-    build['version'] = version or '?'
-    build['vercode'] = vercode or '?'
-    build['commit'] = '?'
-    build['disable'] = 'Generated by import.py - check/set version fields and commit id'
+    build = metadata.Build()
+    build.version = version or '?'
+    build.vercode = vercode or '?'
+    build.commit = '?'
+    build.disable = 'Generated by import.py - check/set version fields and commit id'
     if options.subdir:
-        build['subdir'] = options.subdir
+        build.subdir = options.subdir
     if os.path.exists(os.path.join(root_dir, 'jni')):
-        build['buildjni'] = ['yes']
+        build.buildjni = ['yes']
 
-    for flag, value in metadata.flag_defaults.iteritems():
-        if flag in build:
-            continue
-        build[flag] = value
-
-    app['builds'].append(build)
+    app.builds.append(build)
 
     # Keep the repo directory to save bandwidth...
     if not os.path.exists('build'):
         os.mkdir('build')
-    if src_dir is not None:
-        shutil.move(src_dir, os.path.join('build', package))
+    if build_dir is not None:
+        shutil.move(build_dir, os.path.join('build', package))
     with open('build/.fdroidvcs-' + package, 'w') as f:
-        f.write(app['Repo Type'] + ' ' + app['Repo'])
+        f.write(app.RepoType + ' ' + app.Repo)
 
     metadatapath = os.path.join('metadata', package + '.txt')
     with open(metadatapath, 'w') as f:
-        metadata.write_metadata(f, app)
+        metadata.write_metadata('txt', f, app)
     logging.info("Wrote " + metadatapath)
 
 
index 766cd6a0e586664e6516454be7ca7aadaa5424bc..af4a71bee4ef279cf9722c2385cee5e48f7c5634 100644 (file)
@@ -35,9 +35,7 @@ def devices():
     p = SdkToolsPopen(['adb', "devices"])
     if p.returncode != 0:
         raise FDroidException("An error occured when finding devices: %s" % p.output)
-    lines = p.output.splitlines()
-    if lines[0].startswith('* daemon not running'):
-        lines = lines[2:]
+    lines = [l for l in p.output.splitlines() if not l.startswith('* ')]
     if len(lines) < 3:
         return []
     lines = lines[1:-1]
index fb2ce2c0087ad10c25c20beeece93cb27138f259..5932bd618bcf6b7eaa1a27247ff181a92b34d326 100644 (file)
 
 from argparse import ArgumentParser
 import re
-import common
-import metadata
 import sys
 from sets import Set
 
+import common
+import metadata
+import rewritemeta
+
 config = None
 options = None
 
@@ -55,8 +57,8 @@ http_url_shorteners = [
 http_checks = https_enforcings + http_url_shorteners + [
     (re.compile(r'.*github\.com/[^/]+/[^/]+\.git'),
      "Appending .git is not necessary"),
-    (re.compile(r'(.*/blob/master/|.*raw\.github.com/[^/]*/[^/]*/master/)'),
-     "Use /HEAD/ instead of /master/ to point at a file in the default branch"),
+    (re.compile(r'.*://[^/]*(github|gitlab|bitbucket|rawgit)[^/]*/([^/]+/){1,3}master'),
+     "Use /HEAD instead of /master to point at a file in the default branch"),
 ]
 
 regex_checks = {
@@ -97,7 +99,7 @@ regex_checks = {
          "Unnecessary trailing space"),
         (re.compile(r'.*([^[]|^)\[[^:[\]]+( |\]|$)'),
          "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]"),
-        (re.compile(r'.*[^[]https?://[^ ]+'),
+        (re.compile(r'(^|.* )https?://[^ ]+'),
          "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]"),
     ],
 }
@@ -106,56 +108,55 @@ regex_checks = {
 def check_regexes(app):
     for f, checks in regex_checks.iteritems():
         for m, r in checks:
-            v = app[f]
-            if type(v) == str:
+            v = app.get_field(f)
+            t = metadata.fieldtype(f)
+            if t == metadata.TYPE_MULTILINE:
+                for l in v.splitlines():
+                    if m.match(l):
+                        yield "%s at line '%s': %s" % (f, l, r)
+            else:
                 if v is None:
                     continue
                 if m.match(v):
                     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):
     lowest_vercode = -1
     lastbuild = None
     for build in builds:
-        if not build['disable']:
-            vercode = int(build['vercode'])
+        if not build.disable:
+            vercode = int(build.vercode)
             if lowest_vercode == -1 or vercode < lowest_vercode:
                 lowest_vercode = vercode
-        if not lastbuild or int(build['vercode']) > int(lastbuild['vercode']):
+        if not lastbuild or int(build.vercode) > int(lastbuild.vercode):
             lastbuild = build
     return lastbuild
 
 
 def check_ucm_tags(app):
-    lastbuild = get_lastbuild(app['builds'])
+    lastbuild = get_lastbuild(app.builds)
     if (lastbuild is not None
-            and lastbuild['commit']
-            and app['Update Check Mode'] == 'RepoManifest'
-            and not lastbuild['commit'].startswith('unknown')
-            and lastbuild['vercode'] == app['Current Version Code']
-            and not lastbuild['forcevercode']
-            and any(s in lastbuild['commit'] for s in '.,_-/')):
+            and lastbuild.commit
+            and app.UpdateCheckMode == 'RepoManifest'
+            and not lastbuild.commit.startswith('unknown')
+            and lastbuild.vercode == app.CurrentVersionCode
+            and not lastbuild.forcevercode
+            and any(s in lastbuild.commit for s in '.,_-/')):
         yield "Last used commit '%s' looks like a tag, but Update Check Mode is '%s'" % (
-            lastbuild['commit'], app['Update Check Mode'])
+            lastbuild.commit, app.UpdateCheckMode)
 
 
 def check_char_limits(app):
     limits = config['char_limits']
 
-    summ_chars = len(app['Summary'])
-    if summ_chars > limits['Summary']:
+    if len(app.Summary) > limits['Summary']:
         yield "Summary of length %s is over the %i char limit" % (
-            summ_chars, limits['Summary'])
+            len(app.Summary), limits['Summary'])
 
-    desc_charcount = sum(len(l) for l in app['Description'])
-    if desc_charcount > limits['Description']:
+    if len(app.Description) > limits['Description']:
         yield "Description of length %s is over the %i char limit" % (
-            desc_charcount, limits['Description'])
+            len(app.Description), limits['Description'])
 
 
 def check_old_links(app):
@@ -168,31 +169,28 @@ def check_old_links(app):
         'gitorious.org',
         'code.google.com',
     ]
-    if any(s in app['Repo'] for s in usual_sites):
+    if any(s in app.Repo for s in usual_sites):
         for f in ['Web Site', 'Source Code', 'Issue Tracker', 'Changelog']:
-            if any(s in app[f] for s in old_sites):
-                yield "App is in '%s' but has a link to '%s'" % (app['Repo'], app[f])
+            v = app.get_field(f)
+            if any(s in v for s in old_sites):
+                yield "App is in '%s' but has a link to '%s'" % (app.Repo, v)
 
 
 def check_useless_fields(app):
-    if app['Update Check Name'] == app['id']:
+    if app.UpdateCheckName == app.id:
         yield "Update Check Name is set to the known app id - it can be removed"
 
-filling_ucms = re.compile('^(Tags.*|RepoManifest.*)')
+filling_ucms = re.compile(r'^(Tags.*|RepoManifest.*)')
 
 
 def check_checkupdates_ran(app):
-    if filling_ucms.match(app['Update Check Mode']):
-        if all(app[f] == metadata.app_defaults[f] for f in [
-                'Auto Name',
-                'Current Version',
-                'Current Version Code',
-                ]):
+    if filling_ucms.match(app.UpdateCheckMode):
+        if not app.AutoName and not app.CurrentVersion and app.CurrentVersionCode == '0':
             yield "UCM is set but it looks like checkupdates hasn't been run yet"
 
 
 def check_empty_fields(app):
-    if not app['Categories']:
+    if not app.Categories:
         yield "Categories are not set"
 
 all_categories = Set([
@@ -217,37 +215,37 @@ all_categories = Set([
 
 
 def check_categories(app):
-    for categ in app['Categories']:
+    for categ in app.Categories:
         if categ not in all_categories:
             yield "Category '%s' is not valid" % categ
 
 
 def check_duplicates(app):
-    if app['Name'] and app['Name'] == app['Auto Name']:
-        yield "Name '%s' is just the auto name - remove it" % app['Name']
+    if app.Name and app.Name == app.AutoName:
+        yield "Name '%s' is just the auto name - remove it" % app.Name
 
     links_seen = set()
     for f in ['Source Code', 'Web Site', 'Issue Tracker', 'Changelog']:
-        if not app[f]:
+        v = app.get_field(f)
+        if not v:
             continue
-        v = app[f].lower()
+        v = v.lower()
         if v in links_seen:
             yield "Duplicate link in '%s': %s" % (f, v)
         else:
             links_seen.add(v)
 
-    name = app['Name'] or app['Auto Name']
-    if app['Summary'] and name:
-        if app['Summary'].lower() == name.lower():
-            yield "Summary '%s' is just the app's name" % app['Summary']
+    name = app.Name or app.AutoName
+    if app.Summary and name:
+        if app.Summary.lower() == name.lower():
+            yield "Summary '%s' is just the app's name" % app.Summary
 
-    desc = app['Description']
-    if app['Summary'] and desc and len(desc) == 1:
-        if app['Summary'].lower() == desc[0].lower():
-            yield "Description '%s' is just the app's summary" % app['Summary']
+    if app.Summary and app.Description and len(app.Description) == 1:
+        if app.Summary.lower() == app.Description[0].lower():
+            yield "Description '%s' is just the app's summary" % app.Summary
 
     seenlines = set()
-    for l in app['Description']:
+    for l in app.Description.splitlines():
         if len(l) < 1:
             continue
         if l in seenlines:
@@ -255,11 +253,11 @@ def check_duplicates(app):
         seenlines.add(l)
 
 
-desc_url = re.compile("[^[]\[([^ ]+)( |\]|$)")
+desc_url = re.compile(r'(^|[^[])\[([^ ]+)( |\]|$)')
 
 
 def check_mediawiki_links(app):
-    wholedesc = ' '.join(app['Description'])
+    wholedesc = ' '.join(app.Description)
     for um in desc_url.finditer(wholedesc):
         url = um.group(1)
         for m, r in http_checks:
@@ -271,7 +269,7 @@ def check_bulleted_lists(app):
     validchars = ['*', '#']
     lchar = ''
     lcount = 0
-    for l in app['Description']:
+    for l in app.Description.splitlines():
         if len(l) < 1:
             lcount = 0
             continue
@@ -287,16 +285,18 @@ def check_bulleted_lists(app):
 
 
 def check_builds(app):
-    for build in app['builds']:
-        if build['disable']:
+    for build in app.builds:
+        if build.disable:
             continue
         for s in ['master', 'origin', 'HEAD', 'default', 'trunk']:
-            if build['commit'] and build['commit'].startswith(s):
-                yield "Branch '%s' used as commit in build '%s'" % (s, build['version'])
-            for srclib in build['srclibs']:
+            if build.commit and build.commit.startswith(s):
+                yield "Branch '%s' used as commit in build '%s'" % (s, build.version)
+            for srclib in build.srclibs:
                 ref = srclib.split('@')[1].split('/')[0]
                 if ref.startswith(s):
                     yield "Branch '%s' used as commit in srclib '%s'" % (s, srclib)
+        if build.target and build.method() == 'gradle':
+            yield "target= has no gradle support"
 
 
 def main():
@@ -308,6 +308,8 @@ def main():
     # Parse command line...
     parser = ArgumentParser(usage="%(prog)s [options] [APPID [APPID ...]]")
     common.setup_global_opts(parser)
+    parser.add_argument("-f", "--format", action="store_true", default=False,
+                        help="Also warn about formatting issues, like rewritemeta -l")
     parser.add_argument("appid", nargs='*', help="app-id in the form APPID")
     options = parser.parse_args()
 
@@ -318,7 +320,7 @@ def main():
     apps = common.read_app_args(options.appid, allapps, False)
 
     for appid, app in apps.iteritems():
-        if app['Disabled']:
+        if app.Disabled:
             continue
 
         warns = []
@@ -339,6 +341,10 @@ def main():
                 ]:
             warns += check_func(app)
 
+        if options.format:
+            if not rewritemeta.proper_format(app):
+                warns.append("Run rewritemeta to fix formatting")
+
         if warns:
             anywarns = True
             for warn in warns:
index 530f135070bda67ae86031d0fc2eda8e1bbc3e3e..163ebf01b1653427b8be1c974f1353333de5a5e7 100644 (file)
 import json
 import os
 import re
-import sys
 import glob
 import cgi
-import logging
 import textwrap
 
+try:
+    from cStringIO import StringIO
+except:
+    from StringIO import StringIO
+
 import yaml
 # use libyaml if it is available
 try:
@@ -38,8 +41,6 @@ except ImportError:
 # use the C implementation when available
 import xml.etree.cElementTree as ElementTree
 
-from collections import OrderedDict
-
 import common
 
 srclibs = None
@@ -53,78 +54,328 @@ class MetaDataException(Exception):
     def __str__(self):
         return self.value
 
-# In the order in which they are laid out on files
-app_defaults = OrderedDict([
-    ('Disabled', None),
-    ('AntiFeatures', []),
-    ('Provides', None),
-    ('Categories', ['None']),
-    ('License', 'Unknown'),
-    ('Web Site', ''),
-    ('Source Code', ''),
-    ('Issue Tracker', ''),
-    ('Changelog', ''),
-    ('Donate', None),
-    ('FlattrID', None),
-    ('Bitcoin', None),
-    ('Litecoin', None),
-    ('Name', None),
-    ('Auto Name', ''),
-    ('Summary', ''),
-    ('Description', []),
-    ('Requires Root', False),
-    ('Repo Type', ''),
-    ('Repo', ''),
-    ('Binaries', None),
-    ('Maintainer Notes', []),
-    ('Archive Policy', None),
-    ('Auto Update Mode', 'None'),
-    ('Update Check Mode', 'None'),
-    ('Update Check Ignore', None),
-    ('Vercode Operation', None),
-    ('Update Check Name', None),
-    ('Update Check Data', None),
-    ('Current Version', ''),
-    ('Current Version Code', '0'),
-    ('No Source Since', ''),
+# To filter which ones should be written to the metadata files if
+# present
+app_fields = set([
+    'Disabled',
+    'AntiFeatures',
+    'Provides',
+    'Categories',
+    'License',
+    'Web Site',
+    'Source Code',
+    'Issue Tracker',
+    'Changelog',
+    'Donate',
+    'FlattrID',
+    'Bitcoin',
+    'Litecoin',
+    'Name',
+    'Auto Name',
+    'Summary',
+    'Description',
+    'Requires Root',
+    'Repo Type',
+    'Repo',
+    'Binaries',
+    'Maintainer Notes',
+    'Archive Policy',
+    'Auto Update Mode',
+    'Update Check Mode',
+    'Update Check Ignore',
+    'Vercode Operation',
+    'Update Check Name',
+    'Update Check Data',
+    'Current Version',
+    'Current Version Code',
+    'No Source Since',
+
+    'comments',  # For formats that don't do inline comments
+    'builds',    # For formats that do builds as a list
 ])
 
 
+class App():
+
+    def __init__(self):
+        self.Disabled = None
+        self.AntiFeatures = []
+        self.Provides = None
+        self.Categories = ['None']
+        self.License = 'Unknown'
+        self.WebSite = ''
+        self.SourceCode = ''
+        self.IssueTracker = ''
+        self.Changelog = ''
+        self.Donate = None
+        self.FlattrID = None
+        self.Bitcoin = None
+        self.Litecoin = None
+        self.Name = None
+        self.AutoName = ''
+        self.Summary = ''
+        self.Description = ''
+        self.RequiresRoot = False
+        self.RepoType = ''
+        self.Repo = ''
+        self.Binaries = None
+        self.MaintainerNotes = ''
+        self.ArchivePolicy = None
+        self.AutoUpdateMode = 'None'
+        self.UpdateCheckMode = 'None'
+        self.UpdateCheckIgnore = None
+        self.VercodeOperation = None
+        self.UpdateCheckName = None
+        self.UpdateCheckData = None
+        self.CurrentVersion = ''
+        self.CurrentVersionCode = '0'
+        self.NoSourceSince = ''
+
+        self.id = None
+        self.metadatapath = None
+        self.builds = []
+        self.comments = {}
+        self.added = None
+        self.lastupdated = None
+        self._modified = set()
+
+    # Translates human-readable field names to attribute names, e.g.
+    # 'Auto Name' to 'AutoName'
+    @classmethod
+    def field_to_attr(cls, f):
+        return f.replace(' ', '')
+
+    # Translates attribute names to human-readable field names, e.g.
+    # 'AutoName' to 'Auto Name'
+    @classmethod
+    def attr_to_field(cls, k):
+        if k in app_fields:
+            return k
+        f = re.sub(r'([a-z])([A-Z])', r'\1 \2', k)
+        return f
+
+    # Constructs an old-fashioned dict with the human-readable field
+    # names. Should only be used for tests.
+    def field_dict(self):
+        d = {}
+        for k, v in self.__dict__.iteritems():
+            if k == 'builds':
+                d['builds'] = []
+                for build in 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'
+    def get_field(self, f):
+        if f not in app_fields:
+            raise MetaDataException('Unrecognised app field: ' + f)
+        k = App.field_to_attr(f)
+        return getattr(self, k)
+
+    # Sets the value associated to a field name, e.g. 'Auto Name'
+    def set_field(self, f, v):
+        if f not in app_fields:
+            raise MetaDataException('Unrecognised app field: ' + f)
+        k = App.field_to_attr(f)
+        self.__dict__[k] = v
+        self._modified.add(k)
+
+    # Appends to the value associated to a field name, e.g. 'Auto Name'
+    def append_field(self, f, v):
+        if f not in app_fields:
+            raise MetaDataException('Unrecognised app field: ' + f)
+        k = App.field_to_attr(f)
+        if k not in self.__dict__:
+            self.__dict__[k] = [v]
+        else:
+            self.__dict__[k].append(v)
+
+    # Like dict.update(), but using human-readable field names
+    def update_fields(self, d):
+        for f, v in d.iteritems():
+            if f == 'builds':
+                for b in v:
+                    build = Build()
+                    build.update_flags(b)
+                    self.builds.append(build)
+            else:
+                self.set_field(f, v)
+
+TYPE_UNKNOWN = 0
+TYPE_OBSOLETE = 1
+TYPE_STRING = 2
+TYPE_BOOL = 3
+TYPE_LIST = 4
+TYPE_SCRIPT = 5
+TYPE_MULTILINE = 6
+TYPE_BUILD = 7
+TYPE_BUILD_V2 = 8
+
+fieldtypes = {
+    'Description': TYPE_MULTILINE,
+    'Maintainer Notes': TYPE_MULTILINE,
+    'Categories': TYPE_LIST,
+    'AntiFeatures': TYPE_LIST,
+    'Build Version': TYPE_BUILD,
+    'Build': TYPE_BUILD_V2,
+    'Use Built': TYPE_OBSOLETE,
+}
+
+
+def fieldtype(name):
+    if name in fieldtypes:
+        return fieldtypes[name]
+    return TYPE_STRING
+
+
 # In the order in which they are laid out on files
-# Sorted by their action and their place in the build timeline
-# These variables can have varying datatypes. For example, anything with
-# flagtype(v) == 'list' is inited as False, then set as a list of strings.
-flag_defaults = OrderedDict([
-    ('disable', False),
-    ('commit', None),
-    ('subdir', None),
-    ('submodules', False),
-    ('init', ''),
-    ('patch', []),
-    ('gradle', False),
-    ('maven', False),
-    ('kivy', False),
-    ('output', None),
-    ('srclibs', []),
-    ('oldsdkloc', False),
-    ('encoding', None),
-    ('forceversion', False),
-    ('forcevercode', False),
-    ('rm', []),
-    ('extlibs', []),
-    ('prebuild', ''),
-    ('update', ['auto']),
-    ('target', None),
-    ('scanignore', []),
-    ('scandelete', []),
-    ('build', ''),
-    ('buildjni', []),
-    ('ndk', 'r10e'),  # defaults to latest
-    ('preassemble', []),
-    ('gradleprops', []),
-    ('antcommands', None),
-    ('novcheck', False),
-])
+build_flags_order = [
+    'disable',
+    'commit',
+    'subdir',
+    'submodules',
+    'init',
+    'patch',
+    'gradle',
+    'maven',
+    'kivy',
+    'output',
+    'srclibs',
+    'oldsdkloc',
+    'encoding',
+    'forceversion',
+    'forcevercode',
+    'rm',
+    'extlibs',
+    'prebuild',
+    'update',
+    'target',
+    'scanignore',
+    'scandelete',
+    'build',
+    'buildjni',
+    'ndk',
+    'preassemble',
+    'gradleprops',
+    'antcommands',
+    'novcheck',
+]
+
+
+build_flags = set(build_flags_order + ['version', 'vercode'])
+
+
+class Build():
+
+    def __init__(self):
+        self.disable = False
+        self.commit = None
+        self.subdir = None
+        self.submodules = False
+        self.init = ''
+        self.patch = []
+        self.gradle = []
+        self.maven = False
+        self.kivy = False
+        self.output = None
+        self.srclibs = []
+        self.oldsdkloc = False
+        self.encoding = None
+        self.forceversion = False
+        self.forcevercode = False
+        self.rm = []
+        self.extlibs = []
+        self.prebuild = ''
+        self.update = []
+        self.target = None
+        self.scanignore = []
+        self.scandelete = []
+        self.build = ''
+        self.buildjni = []
+        self.ndk = None
+        self.preassemble = []
+        self.gradleprops = []
+        self.antcommands = []
+        self.novcheck = False
+
+        self._modified = set()
+
+    def get_flag(self, f):
+        if f not in build_flags:
+            raise MetaDataException('Unrecognised build flag: ' + f)
+        return getattr(self, f)
+
+    def set_flag(self, f, v):
+        if f == 'versionName':
+            f = 'version'
+        if f == 'versionCode':
+            f = 'vercode'
+        if f not in build_flags:
+            raise MetaDataException('Unrecognised build flag: ' + f)
+        self.__dict__[f] = v
+        self._modified.add(f)
+
+    def append_flag(self, f, v):
+        if f not in build_flags:
+            raise MetaDataException('Unrecognised build flag: ' + f)
+        if f not in self.__dict__:
+            self.__dict__[f] = [v]
+        else:
+            self.__dict__[f].append(v)
+
+    def method(self):
+        for f in ['maven', 'gradle', 'kivy']:
+            if self.get_flag(f):
+                return f
+        if self.output:
+            return 'raw'
+        return 'ant'
+
+    def ndk_path(self):
+        version = self.ndk
+        if not version:
+            version = 'r10e'  # falls back to latest
+        paths = common.config['ndk_paths']
+        if version not in paths:
+            return ''
+        return paths[version]
+
+    def update_flags(self, d):
+        for f, v in d.iteritems():
+            self.set_flag(f, v)
+
+flagtypes = {
+    'extlibs': TYPE_LIST,
+    'srclibs': TYPE_LIST,
+    'patch': TYPE_LIST,
+    'rm': TYPE_LIST,
+    'buildjni': TYPE_LIST,
+    'preassemble': TYPE_LIST,
+    'update': TYPE_LIST,
+    'scanignore': TYPE_LIST,
+    'scandelete': TYPE_LIST,
+    'gradle': TYPE_LIST,
+    'antcommands': TYPE_LIST,
+    'gradleprops': TYPE_LIST,
+    'init': TYPE_SCRIPT,
+    'prebuild': TYPE_SCRIPT,
+    'build': TYPE_SCRIPT,
+    'submodules': TYPE_BOOL,
+    'oldsdkloc': TYPE_BOOL,
+    'forceversion': TYPE_BOOL,
+    'forcevercode': TYPE_BOOL,
+    'novcheck': TYPE_BOOL,
+}
+
+
+def flagtype(name):
+    if name in flagtypes:
+        return flagtypes[name]
+    return TYPE_STRING
 
 
 # Designates a metadata field type and checks that it matches
@@ -133,41 +384,41 @@ flag_defaults = OrderedDict([
 # 'matching' - List of possible values or regex expression
 # 'sep'      - Separator to use if value may be a list
 # 'fields'   - Metadata fields (Field:Value) of this type
-# 'attrs'    - Build attributes (attr=value) of this type
+# 'flags'    - Build flags (flag=value) of this type
 #
 class FieldValidator():
 
-    def __init__(self, name, matching, sep, fields, attrs):
+    def __init__(self, name, matching, sep, fields, flags):
         self.name = name
         self.matching = matching
         if type(matching) is str:
             self.compiled = re.compile(matching)
+        else:
+            self.matching = set(self.matching)
         self.sep = sep
         self.fields = fields
-        self.attrs = attrs
+        self.flags = flags
 
     def _assert_regex(self, values, appid):
         for v in values:
             if not self.compiled.match(v):
-                raise MetaDataException("'%s' is not a valid %s in %s. "
-                                        % (v, self.name, appid) +
-                                        "Regex pattern: %s" % (self.matching))
+                raise MetaDataException("'%s' is not a valid %s in %s. Regex pattern: %s"
+                                        % (v, self.name, appid, self.matching))
 
     def _assert_list(self, values, appid):
         for v in values:
             if v not in self.matching:
-                raise MetaDataException("'%s' is not a valid %s in %s. "
-                                        % (v, self.name, appid) +
-                                        "Possible values: %s" % (", ".join(self.matching)))
+                raise MetaDataException("'%s' is not a valid %s in %s. Possible values: %s"
+                                        % (v, self.name, appid, ', '.join(self.matching)))
 
-    def check(self, value, appid):
-        if type(value) is not str or not value:
+    def check(self, v, appid):
+        if not v:
             return
-        if self.sep is not None:
-            values = value.split(self.sep)
+        if type(v) == list:
+            values = v
         else:
-            values = [value]
-        if type(self.matching) is list:
+            values = [v]
+        if type(self.matching) is set:
             self._assert_list(values, appid)
         else:
             self._assert_regex(values, appid)
@@ -187,7 +438,7 @@ valuetypes = {
 
     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,
@@ -199,15 +450,9 @@ valuetypes = {
                    ["Litecoin"],
                    []),
 
-    FieldValidator("bool",
-                   r'([Yy]es|[Nn]o|[Tt]rue|[Ff]alse)', None,
-                   ["Requires Root"],
-                   ['submodules', 'oldsdkloc', 'forceversion', 'forcevercode',
-                    'novcheck']),
-
     FieldValidator("Repo Type",
                    ['git', 'git-svn', 'svn', 'hg', 'bzr', 'srclib'], None,
-                   ["Repo Type"],
+                   ["RepoType"],
                    []),
 
     FieldValidator("Binaries",
@@ -217,7 +462,7 @@ valuetypes = {
 
     FieldValidator("Archive Policy",
                    r'^[0-9]+ versions$', None,
-                   ["Archive Policy"],
+                   ["ArchivePolicy"],
                    []),
 
     FieldValidator("Anti-Feature",
@@ -227,44 +472,51 @@ valuetypes = {
 
     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(info):
+def check_metadata(app):
     for v in valuetypes:
-        for field in v.fields:
-            v.check(info[field], info['id'])
-        for build in info['builds']:
-            for attr in v.attrs:
-                v.check(build[attr], info['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 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
 # each line of the description source from the metadata. At the end, call
-# end() and then text_wiki and text_html will contain the result.
+# end() and then text_txt and text_html will contain the result.
 class DescriptionFormatter:
+
     stNONE = 0
     stPARA = 1
     stUL = 2
     stOL = 3
-    bold = False
-    ital = False
-    state = stNONE
-    text_wiki = ''
-    text_html = ''
-    text_txt = ''
-    para_lines = []
-    linkResolver = None
 
     def __init__(self, linkres):
+        self.bold = False
+        self.ital = False
+        self.state = self.stNONE
+        self.laststate = self.stNONE
+        self.text_html = ''
+        self.text_txt = ''
+        self.html = StringIO()
+        self.text = StringIO()
+        self.para_lines = []
+        self.linkResolver = None
         self.linkResolver = linkres
 
     def endcur(self, notstates=None):
@@ -278,61 +530,62 @@ class DescriptionFormatter:
             self.endol()
 
     def endpara(self):
+        self.laststate = self.state
         self.state = self.stNONE
         whole_para = ' '.join(self.para_lines)
         self.addtext(whole_para)
-        self.text_txt += textwrap.fill(whole_para, 80,
-                                       break_long_words=False,
-                                       break_on_hyphens=False) + '\n\n'
-        self.text_html += '</p>'
+        self.text.write(textwrap.fill(whole_para, 80,
+                                      break_long_words=False,
+                                      break_on_hyphens=False))
+        self.html.write('</p>')
         del self.para_lines[:]
 
     def endul(self):
-        self.text_html += '</ul>'
-        self.text_txt += '\n'
+        self.html.write('</ul>')
+        self.laststate = self.state
         self.state = self.stNONE
 
     def endol(self):
-        self.text_html += '</ol>'
-        self.text_txt += '\n'
+        self.html.write('</ol>')
+        self.laststate = self.state
         self.state = self.stNONE
 
     def formatted(self, txt, html):
-        formatted = ''
+        res = ''
         if html:
             txt = cgi.escape(txt)
         while True:
             index = txt.find("''")
             if index == -1:
-                return formatted + txt
-            formatted += txt[:index]
+                return res + txt
+            res += txt[:index]
             txt = txt[index:]
             if txt.startswith("'''"):
                 if html:
                     if self.bold:
-                        formatted += '</b>'
+                        res += '</b>'
                     else:
-                        formatted += '<b>'
+                        res += '<b>'
                 self.bold = not self.bold
                 txt = txt[3:]
             else:
                 if html:
                     if self.ital:
-                        formatted += '</i>'
+                        res += '</i>'
                     else:
-                        formatted += '<i>'
+                        res += '<i>'
                 self.ital = not self.ital
                 txt = txt[2:]
 
     def linkify(self, txt):
-        linkified_plain = ''
-        linkified_html = ''
+        res_plain = ''
+        res_html = ''
         while True:
             index = txt.find("[")
             if index == -1:
-                return (linkified_plain + self.formatted(txt, False), linkified_html + self.formatted(txt, True))
-            linkified_plain += self.formatted(txt[:index], False)
-            linkified_html += self.formatted(txt[:index], True)
+                return (res_plain + self.formatted(txt, False), res_html + self.formatted(txt, True))
+            res_plain += self.formatted(txt[:index], False)
+            res_html += self.formatted(txt[:index], True)
             txt = txt[index:]
             if txt.startswith("[["):
                 index = txt.find("]]")
@@ -343,8 +596,8 @@ class DescriptionFormatter:
                     url, urltext = self.linkResolver(url)
                 else:
                     urltext = url
-                linkified_html += '<a href="' + url + '">' + cgi.escape(urltext) + '</a>'
-                linkified_plain += urltext
+                res_html += '<a href="' + url + '">' + cgi.escape(urltext) + '</a>'
+                res_plain += urltext
                 txt = txt[index + 2:]
             else:
                 index = txt.find("]")
@@ -359,55 +612,67 @@ class DescriptionFormatter:
                     url = url[:index2]
                     if url == urltxt:
                         raise MetaDataException("Url title is just the URL - use [url]")
-                linkified_html += '<a href="' + url + '">' + cgi.escape(urltxt) + '</a>'
-                linkified_plain += urltxt
+                res_html += '<a href="' + url + '">' + cgi.escape(urltxt) + '</a>'
+                res_plain += urltxt
                 if urltxt != url:
-                    linkified_plain += ' (' + url + ')'
+                    res_plain += ' (' + url + ')'
                 txt = txt[index + 1:]
 
     def addtext(self, txt):
         p, h = self.linkify(txt)
-        self.text_html += h
+        self.html.write(h)
 
     def parseline(self, line):
-        self.text_wiki += "%s\n" % line
         if not line:
             self.endcur()
         elif line.startswith('* '):
             self.endcur([self.stUL])
-            self.text_txt += "%s\n" % line
             if self.state != self.stUL:
-                self.text_html += '<ul>'
+                self.html.write('<ul>')
                 self.state = self.stUL
-            self.text_html += '<li>'
+                if self.laststate != self.stNONE:
+                    self.text.write('\n\n')
+            else:
+                self.text.write('\n')
+            self.text.write(line)
+            self.html.write('<li>')
             self.addtext(line[1:])
-            self.text_html += '</li>'
+            self.html.write('</li>')
         elif line.startswith('# '):
             self.endcur([self.stOL])
-            self.text_txt += "%s\n" % line
             if self.state != self.stOL:
-                self.text_html += '<ol>'
+                self.html.write('<ol>')
                 self.state = self.stOL
-            self.text_html += '<li>'
+                if self.laststate != self.stNONE:
+                    self.text.write('\n\n')
+            else:
+                self.text.write('\n')
+            self.text.write(line)
+            self.html.write('<li>')
             self.addtext(line[1:])
-            self.text_html += '</li>'
+            self.html.write('</li>')
         else:
             self.para_lines.append(line)
             self.endcur([self.stPARA])
             if self.state == self.stNONE:
-                self.text_html += '<p>'
                 self.state = self.stPARA
+                if self.laststate != self.stNONE:
+                    self.text.write('\n\n')
+                self.html.write('<p>')
 
     def end(self):
         self.endcur()
-        self.text_txt = self.text_txt.strip()
+        self.text_txt = self.text.getvalue()
+        self.text_html = self.html.getvalue()
+        self.text.close()
+        self.html.close()
 
 
 # Parse multiple lines of description as written in a metadata file, returning
 # a single string in text format and wrapped to 80 columns.
-def description_txt(lines):
+def description_txt(s):
     ps = DescriptionFormatter(None)
-    for line in lines:
+    for line in s.splitlines():
         ps.parseline(line)
     ps.end()
     return ps.text_txt
@@ -416,19 +681,15 @@ def description_txt(lines):
 # 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,
 # because it's the same format.
-def description_wiki(lines):
-    ps = DescriptionFormatter(None)
-    for line in lines:
-        ps.parseline(line)
-    ps.end()
-    return ps.text_wiki
+def description_wiki(s):
+    return s
 
 
 # Parse multiple lines of description as written in a metadata file, returning
 # a single string in HTML format.
-def description_html(lines, linkres):
+def description_html(s, linkres):
     ps = DescriptionFormatter(linkres)
-    for line in lines:
+    for line in s.splitlines():
         ps.parseline(line)
     ps.end()
     return ps.text_html
@@ -457,14 +718,16 @@ def parse_srclib(metadatapath):
             continue
 
         try:
-            field, value = line.split(':', 1)
+            f, v = line.split(':', 1)
         except ValueError:
             raise MetaDataException("Invalid metadata in %s:%d" % (line, n))
 
-        if field == "Subdir":
-            thisinfo[field] = value.split(',')
+        if f == "Subdir":
+            thisinfo[f] = v.split(',')
         else:
-            thisinfo[field] = value
+            thisinfo[f] = v
+
+    metafile.close()
 
     return thisinfo
 
@@ -519,9 +782,11 @@ def read_metadata(xref=True):
                                + glob.glob(os.path.join('metadata', '*.json'))
                                + glob.glob(os.path.join('metadata', '*.xml'))
                                + glob.glob(os.path.join('metadata', '*.yaml'))):
-        appid, appinfo = parse_metadata(apps, metadatapath)
-        check_metadata(appinfo)
-        apps[appid] = appinfo
+        app = parse_metadata(metadatapath)
+        if app.id in apps:
+            raise MetaDataException("Found multiple metadata files for " + app.id)
+        check_metadata(app)
+        apps[app.id] = app
 
     if xref:
         # Parse all descriptions at load time, just to ensure cross-referencing
@@ -533,157 +798,83 @@ def read_metadata(xref=True):
 
         for appid, app in apps.iteritems():
             try:
-                description_html(app['Description'], linkres)
+                description_html(app.Description, linkres)
             except MetaDataException, e:
                 raise MetaDataException("Problem with description of " + appid +
                                         " - " + str(e))
 
     return apps
 
-
-# Get the type expected for a given metadata field.
-def metafieldtype(name):
-    if name in ['Description', 'Maintainer Notes']:
-        return 'multiline'
-    if name in ['Categories', 'AntiFeatures']:
-        return 'list'
-    if name == 'Build Version':
-        return 'build'
-    if name == 'Build':
-        return 'buildv2'
-    if name == 'Use Built':
-        return 'obsolete'
-    if name not in app_defaults:
-        return 'unknown'
-    return 'string'
-
-
-def flagtype(name):
-    if name in ['extlibs', 'srclibs', 'patch', 'rm', 'buildjni', 'preassemble',
-                'update', 'scanignore', 'scandelete', 'gradle', 'antcommands',
-                'gradleprops']:
-        return 'list'
-    if name in ['init', 'prebuild', 'build']:
-        return 'script'
-    if name in ['submodules', 'oldsdkloc', 'forceversion', 'forcevercode',
-                'novcheck']:
-        return 'bool'
-    return 'string'
-
-
-def fill_build_defaults(build):
-
-    def get_build_type():
-        for t in ['maven', 'gradle', 'kivy']:
-            if build[t]:
-                return t
-        if build['output']:
-            return 'raw'
-        return 'ant'
-
-    for flag, value in flag_defaults.iteritems():
-        if flag in build:
-            continue
-        build[flag] = value
-    build['type'] = get_build_type()
-    build['ndk_path'] = common.get_ndk_path(build['ndk'])
+# Port legacy ';' separators
+list_sep = re.compile(r'[,;]')
 
 
 def split_list_values(s):
-    # Port legacy ';' separators
-    l = [v.strip() for v in s.replace(';', ',').split(',')]
-    return [v for v in l if v]
+    res = []
+    for v in re.split(list_sep, s):
+        if not v:
+            continue
+        v = v.strip()
+        if not v:
+            continue
+        res.append(v)
+    return res
 
 
-def get_default_app_info_list(apps, metadatapath=None):
+def get_default_app_info(metadatapath=None):
     if metadatapath is None:
         appid = None
     else:
-        appid = os.path.splitext(os.path.basename(metadatapath))[0]
-    if appid in apps:
-        logging.critical("'%s' is a duplicate! '%s' is already provided by '%s'"
-                         % (metadatapath, appid, apps[appid]['metadatapath']))
-        sys.exit(1)
+        appid, _ = common.get_extension(os.path.basename(metadatapath))
 
-    thisinfo = {}
-    thisinfo.update(app_defaults)
-    thisinfo['metadatapath'] = metadatapath
+    app = App()
+    app.metadatapath = metadatapath
     if appid is not None:
-        thisinfo['id'] = appid
-
-    # General defaults...
-    thisinfo['builds'] = []
-    thisinfo['comments'] = []
+        app.id = appid
 
-    return appid, thisinfo
+    return app
 
 
 def sorted_builds(builds):
-    return sorted(builds, key=lambda build: int(build['vercode']))
+    return sorted(builds, key=lambda build: int(build.vercode))
 
 
-def post_metadata_parse(thisinfo):
+esc_newlines = re.compile(r'\\( |\n)')
 
-    supported_metadata = app_defaults.keys() + ['comments', 'builds', 'id', 'metadatapath']
-    for k, v in thisinfo.iteritems():
-        if k not in supported_metadata:
-            raise MetaDataException("Unrecognised metadata: {0}: {1}"
-                                    .format(k, v))
+
+# This function uses __dict__ to be faster
+def post_metadata_parse(app):
+
+    for k, v in app.__dict__.iteritems():
+        if k not in app._modified:
+            continue
         if type(v) in (float, int):
-            thisinfo[k] = str(v)
-
-    # convert to the odd internal format
-    for k in ('Description', 'Maintainer Notes'):
-        if isinstance(thisinfo[k], basestring):
-            text = thisinfo[k].rstrip().lstrip()
-            thisinfo[k] = text.split('\n')
-
-    supported_flags = (flag_defaults.keys()
-                       + ['vercode', 'version', 'versionCode', 'versionName'])
-    esc_newlines = re.compile('\\\\( |\\n)')
-
-    for build in thisinfo['builds']:
-        for k, v in build.items():
-            if k not in supported_flags:
-                raise MetaDataException("Unrecognised build flag: {0}={1}"
-                                        .format(k, v))
-
-            if k == 'versionCode':
-                build['vercode'] = str(v)
-                del build['versionCode']
-            elif k == 'versionName':
-                build['version'] = str(v)
-                del build['versionName']
-            elif type(v) in (float, int):
-                build[k] = str(v)
-            else:
-                keyflagtype = flagtype(k)
-                if keyflagtype == 'list':
-                    # these can be bools, strings or lists, but ultimately are lists
-                    if isinstance(v, basestring):
-                        build[k] = [v]
-                    elif isinstance(v, bool):
-                        if v:
-                            build[k] = ['yes']
-                        else:
-                            build[k] = ['no']
-                elif keyflagtype == 'script':
-                    build[k] = re.sub(esc_newlines, '', v).lstrip().rstrip()
-                elif keyflagtype == 'bool':
-                    # TODO handle this using <xsd:element type="xsd:boolean> in a schema
-                    if isinstance(v, basestring):
-                        if v == 'true':
-                            build[k] = True
-                        else:
-                            build[k] = False
-
-    if not thisinfo['Description']:
-        thisinfo['Description'].append('No description available')
-
-    for build in thisinfo['builds']:
-        fill_build_defaults(build)
-
-    thisinfo['builds'] = sorted_builds(thisinfo['builds'])
+            app.__dict__[k] = str(v)
+
+    for build in app.builds:
+        for k, v in build.__dict__.iteritems():
+
+            if k not in build._modified:
+                continue
+            if type(v) in (float, int):
+                build.__dict__[k] = str(v)
+                continue
+            ftype = flagtype(k)
+
+            if ftype == TYPE_SCRIPT:
+                build.__dict__[k] = re.sub(esc_newlines, '', v).lstrip().rstrip()
+            elif ftype == TYPE_BOOL:
+                # TODO handle this using <xsd:element type="xsd:boolean> in a schema
+                if isinstance(v, basestring):
+                    build.__dict__[k] = _decode_bool(v)
+            elif ftype == TYPE_STRING:
+                if isinstance(v, bool) and v:
+                    build.__dict__[k] = 'yes'
+
+    if not app.Description:
+        app.Description = 'No description available'
+
+    app.builds = sorted_builds(app.builds)
 
 
 # Parse metadata for a single application.
@@ -729,125 +920,121 @@ def _decode_list(data):
 def _decode_dict(data):
     '''convert items in a dict from unicode to basestring'''
     rv = {}
-    for key, value in data.iteritems():
-        if isinstance(key, unicode):
-            key = key.encode('utf-8')
-        if isinstance(value, unicode):
-            value = value.encode('utf-8')
-        elif isinstance(value, list):
-            value = _decode_list(value)
-        elif isinstance(value, dict):
-            value = _decode_dict(value)
-        rv[key] = value
+    for k, v in data.iteritems():
+        if isinstance(k, unicode):
+            k = k.encode('utf-8')
+        if isinstance(v, unicode):
+            v = v.encode('utf-8')
+        elif isinstance(v, list):
+            v = _decode_list(v)
+        elif isinstance(v, dict):
+            v = _decode_dict(v)
+        rv[k] = v
     return rv
 
 
-def parse_metadata(apps, metadatapath):
-    root, ext = os.path.splitext(metadatapath)
-    metadataformat = ext[1:]
+bool_true = re.compile(r'([Yy]es|[Tt]rue)')
+bool_false = re.compile(r'([Nn]o|[Ff]alse)')
+
+
+def _decode_bool(s):
+    if bool_true.match(s):
+        return True
+    if bool_false.match(s):
+        return False
+    raise MetaDataException("Invalid bool '%s'" % s)
+
+
+def parse_metadata(metadatapath):
+    _, ext = common.get_extension(metadatapath)
     accepted = common.config['accepted_formats']
-    if metadataformat not in accepted:
-        logging.critical('"' + metadatapath
-                         + '" is not in an accepted format, '
-                         + 'convert to: ' + ', '.join(accepted))
-        sys.exit(1)
-
-    if metadataformat == 'txt':
-        return parse_txt_metadata(apps, metadatapath)
-    elif metadataformat == 'json':
-        return parse_json_metadata(apps, metadatapath)
-    elif metadataformat == 'xml':
-        return parse_xml_metadata(apps, metadatapath)
-    elif metadataformat == 'yaml':
-        return parse_yaml_metadata(apps, metadatapath)
-    else:
-        logging.critical('Unknown metadata format: ' + metadatapath)
-        sys.exit(1)
+    if ext not in accepted:
+        raise MetaDataException('"%s" is not an accepted format, convert to: %s' % (
+            metadatapath, ', '.join(accepted)))
+
+    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(apps, metadatapath):
 
-    appid, thisinfo = get_default_app_info_list(apps, 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 = json.load(open(metadatapath, 'r'),
-                         object_hook=_decode_dict,
+    jsoninfo = json.load(mf, object_hook=_decode_dict,
                          parse_int=lambda s: s,
                          parse_float=lambda s: s)
-    thisinfo.update(jsoninfo)
-    post_metadata_parse(thisinfo)
-
-    return (appid, thisinfo)
+    app.update_fields(jsoninfo)
+    for f in ['Description', 'Maintainer Notes']:
+        v = app.get_field(f)
+        app.set_field(f, '\n'.join(v))
+    return app
 
 
-def parse_xml_metadata(apps, metadatapath):
+def parse_xml_metadata(mf, app):
 
-    appid, thisinfo = get_default_app_info_list(apps, metadatapath)
-
-    tree = ElementTree.ElementTree(file=metadatapath)
+    tree = ElementTree.ElementTree(file=mf)
     root = tree.getroot()
 
     if root.tag != 'resources':
-        logging.critical(metadatapath + ' does not have root as <resources></resources>!')
-        sys.exit(1)
+        raise MetaDataException('%s does not have root as <resources></resources>!' % metadatapath)
 
-    supported_metadata = app_defaults.keys()
     for child in root:
         if child.tag != 'builds':
             # builds does not have name="" attrib
             name = child.attrib['name']
-            if name not in supported_metadata:
-                raise MetaDataException("Unrecognised metadata: <"
-                                        + child.tag + ' name="' + name + '">'
-                                        + child.text
-                                        + "</" + child.tag + '>')
 
         if child.tag == 'string':
-            thisinfo[name] = child.text
+            app.set_field(name, child.text)
         elif child.tag == 'string-array':
-            items = []
             for item in child:
-                items.append(item.text)
-            thisinfo[name] = items
+                app.append_field(name, item.text)
         elif child.tag == 'builds':
-            builds = []
-            for build in child:
-                builddict = dict()
-                for key in build:
-                    builddict[key.tag] = key.text
-                builds.append(builddict)
-            thisinfo['builds'] = builds
+            for b in child:
+                build = Build()
+                for key in b:
+                    build.set_flag(key.tag, key.text)
+                app.builds.append(build)
 
     # TODO handle this using <xsd:element type="xsd:boolean> in a schema
-    if not isinstance(thisinfo['Requires Root'], bool):
-        if thisinfo['Requires Root'] == 'true':
-            thisinfo['Requires Root'] = True
-        else:
-            thisinfo['Requires Root'] = False
+    if not isinstance(app.RequiresRoot, bool):
+        app.RequiresRoot = app.RequiresRoot == 'true'
 
-    post_metadata_parse(thisinfo)
+    return app
 
-    return (appid, thisinfo)
 
+def parse_yaml_metadata(mf, app):
 
-def parse_yaml_metadata(apps, metadatapath):
+    yamlinfo = yaml.load(mf, Loader=YamlLoader)
+    app.update_fields(yamlinfo)
+    return app
 
-    appid, thisinfo = get_default_app_info_list(apps, metadatapath)
 
-    yamlinfo = yaml.load(open(metadatapath, 'r'), Loader=YamlLoader)
-    thisinfo.update(yamlinfo)
-    post_metadata_parse(thisinfo)
+build_line_sep = re.compile(r'(?<!\\),')
+build_cont = re.compile(r'^[ \t]')
 
-    return (appid, thisinfo)
 
-
-def parse_txt_metadata(apps, metadatapath):
+def parse_txt_metadata(mf, app):
 
     linedesc = None
 
-    def add_buildflag(p, thisbuild):
+    def add_buildflag(p, build):
         if not p.strip():
             raise MetaDataException("Empty build flag at {1}"
                                     .format(buildlines[0], linedesc))
@@ -855,308 +1042,358 @@ def parse_txt_metadata(apps, metadatapath):
         if len(bv) != 2:
             raise MetaDataException("Invalid build flag at {0} in {1}"
                                     .format(buildlines[0], linedesc))
-        pk, pv = bv
-        if pk in thisbuild:
-            raise MetaDataException("Duplicate definition on {0} in version {1} of {2}"
-                                    .format(pk, thisbuild['version'], linedesc))
 
+        pk, pv = bv
         pk = pk.lstrip()
-        if pk not in flag_defaults:
-            raise MetaDataException("Unrecognised build flag at {0} in {1}"
-                                    .format(p, linedesc))
         t = flagtype(pk)
-        if t == 'list':
+        if t == TYPE_LIST:
             pv = split_list_values(pv)
-            if pk == 'gradle':
-                if len(pv) == 1 and pv[0] in ['main', 'yes']:
-                    pv = ['yes']
-            thisbuild[pk] = pv
-        elif t == 'string' or t == 'script':
-            thisbuild[pk] = pv
-        elif t == 'bool':
-            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"
-                                    % (t, p, linedesc))
+            build.set_flag(pk, pv)
+        elif t == TYPE_STRING or t == TYPE_SCRIPT:
+            build.set_flag(pk, pv)
+        elif t == TYPE_BOOL:
+            build.set_flag(pk, _decode_bool(pv))
 
     def parse_buildline(lines):
-        value = "".join(lines)
-        parts = [p.replace("\\,", ",")
-                 for p in re.split(r"(?<!\\),", value)]
+        v = "".join(lines)
+        parts = [p.replace("\\,", ",") for p in re.split(build_line_sep, v)]
         if len(parts) < 3:
-            raise MetaDataException("Invalid build format: " + value + " in " + metafile.name)
-        thisbuild = {}
-        thisbuild['origlines'] = lines
-        thisbuild['version'] = parts[0]
-        thisbuild['vercode'] = parts[1]
+            raise MetaDataException("Invalid build format: " + v + " in " + metafile.name)
+        build = Build()
+        build.version = parts[0]
+        build.vercode = parts[1]
         if parts[2].startswith('!'):
             # For backwards compatibility, handle old-style disabling,
             # including attempting to extract the commit from the message
-            thisbuild['disable'] = parts[2][1:]
+            build.disable = parts[2][1:]
             commit = 'unknown - see disabled'
             index = parts[2].rfind('at ')
             if index != -1:
                 commit = parts[2][index + 3:]
                 if commit.endswith(')'):
                     commit = commit[:-1]
-            thisbuild['commit'] = commit
+            build.commit = commit
         else:
-            thisbuild['commit'] = parts[2]
+            build.commit = parts[2]
         for p in parts[3:]:
-            add_buildflag(p, thisbuild)
+            add_buildflag(p, build)
 
-        return thisbuild
+        return build
 
     def add_comments(key):
         if not curcomments:
             return
-        for comment in curcomments:
-            thisinfo['comments'].append([key, comment])
+        app.comments[key] = list(curcomments)
         del curcomments[:]
 
-    appid, thisinfo = get_default_app_info_list(apps, metadatapath)
-    metafile = open(metadatapath, "r")
-
     mode = 0
     buildlines = []
+    multiline_lines = []
     curcomments = []
-    curbuild = None
-    vc_seen = {}
+    build = None
+    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 not any(line.startswith(s) for s in (' ', '\t')):
-                commit = curbuild['commit'] if 'commit' in curbuild else None
-                if not commit and 'disable' not in curbuild:
-                    raise MetaDataException("No commit specified for {0} in {1}"
-                                            .format(curbuild['version'], linedesc))
-
-                thisinfo['builds'].append(curbuild)
-                add_comments('build:' + curbuild['vercode'])
-                mode = 0
-            else:
+            if build_cont.match(line):
                 if line.endswith('\\'):
                     buildlines.append(line[:-1].lstrip())
                 else:
                     buildlines.append(line.lstrip())
                     bl = ''.join(buildlines)
-                    add_buildflag(bl, curbuild)
-                    buildlines = []
+                    add_buildflag(bl, build)
+                    del buildlines[:]
+            else:
+                if not build.commit and not build.disable:
+                    raise MetaDataException("No commit specified for {0} in {1}"
+                                            .format(build.version, linedesc))
+
+                app.builds.append(build)
+                add_comments('build:' + build.vercode)
+                mode = 0
 
         if mode == 0:
             if not line:
                 continue
             if line.startswith("#"):
-                curcomments.append(line)
+                curcomments.append(line[1:].strip())
                 continue
             try:
-                field, value = line.split(':', 1)
+                f, v = line.split(':', 1)
             except ValueError:
                 raise MetaDataException("Invalid metadata in " + linedesc)
-            if field != field.strip() or value != value.strip():
-                raise MetaDataException("Extra spacing found in " + linedesc)
 
             # Translate obsolete fields...
-            if field == 'Market Version':
-                field = 'Current Version'
-            if field == 'Market Version Code':
-                field = 'Current Version Code'
-
-            fieldtype = metafieldtype(field)
-            if fieldtype not in ['build', 'buildv2']:
-                add_comments(field)
-            if fieldtype == 'multiline':
+            if f == 'Market Version':
+                f = 'Current Version'
+            if f == 'Market Version Code':
+                f = 'Current Version Code'
+
+            ftype = fieldtype(f)
+            if ftype not in [TYPE_BUILD, TYPE_BUILD_V2]:
+                add_comments(f)
+            if ftype == TYPE_MULTILINE:
                 mode = 1
-                thisinfo[field] = []
-                if value:
-                    raise MetaDataException("Unexpected text on same line as " + field + " in " + linedesc)
-            elif fieldtype == 'string':
-                thisinfo[field] = value
-            elif fieldtype == 'list':
-                thisinfo[field] = split_list_values(value)
-            elif fieldtype == 'build':
-                if value.endswith("\\"):
+                if v:
+                    raise MetaDataException("Unexpected text on same line as " + f + " in " + linedesc)
+            elif ftype == TYPE_STRING:
+                app.set_field(f, v)
+            elif ftype == TYPE_LIST:
+                app.set_field(f, split_list_values(v))
+            elif ftype == TYPE_BUILD:
+                if v.endswith("\\"):
                     mode = 2
-                    buildlines = [value[:-1]]
+                    del buildlines[:]
+                    buildlines.append(v[:-1])
                 else:
-                    curbuild = parse_buildline([value])
-                    thisinfo['builds'].append(curbuild)
-                    add_comments('build:' + thisinfo['builds'][-1]['vercode'])
-            elif fieldtype == 'buildv2':
-                curbuild = {}
-                vv = value.split(',')
+                    build = parse_buildline([v])
+                    app.builds.append(build)
+                    add_comments('build:' + app.builds[-1].vercode)
+            elif ftype == TYPE_BUILD_V2:
+                vv = v.split(',')
                 if len(vv) != 2:
                     raise MetaDataException('Build should have comma-separated version and vercode, not "{0}", in {1}'
-                                            .format(value, linedesc))
-                curbuild['version'] = vv[0]
-                curbuild['vercode'] = vv[1]
-                if curbuild['vercode'] in vc_seen:
+                                            .format(v, linedesc))
+                build = Build()
+                build.version = vv[0]
+                build.vercode = vv[1]
+                if build.vercode in vc_seen:
                     raise MetaDataException('Duplicate build recipe found for vercode %s in %s' % (
-                                            curbuild['vercode'], linedesc))
-                vc_seen[curbuild['vercode']] = True
-                buildlines = []
+                                            build.vercode, linedesc))
+                vc_seen.add(build.vercode)
+                del buildlines[:]
                 mode = 3
-            elif fieldtype == 'obsolete':
+            elif ftype == TYPE_OBSOLETE:
                 pass        # Just throw it away!
             else:
-                raise MetaDataException("Unrecognised field type for " + field + " in " + linedesc)
+                raise MetaDataException("Unrecognised field '" + f + "' in " + linedesc)
         elif mode == 1:     # Multiline field
             if line == '.':
                 mode = 0
+                app.set_field(f, '\n'.join(multiline_lines))
+                del multiline_lines[:]
             else:
-                thisinfo[field].append(line)
+                multiline_lines.append(line)
         elif mode == 2:     # Line continuation mode in Build Version
             if line.endswith("\\"):
                 buildlines.append(line[:-1])
             else:
                 buildlines.append(line)
-                curbuild = parse_buildline(buildlines)
-                thisinfo['builds'].append(curbuild)
-                add_comments('build:' + thisinfo['builds'][-1]['vercode'])
+                build = parse_buildline(buildlines)
+                app.builds.append(build)
+                add_comments('build:' + app.builds[-1].vercode)
                 mode = 0
     add_comments(None)
 
-    # Mode at end of file should always be 0...
+    # Mode at end of file should always be 0
     if mode == 1:
-        raise MetaDataException(field + " not terminated in " + metafile.name)
-    elif mode == 2:
+        raise MetaDataException(f + " not terminated in " + mf.name)
+    if mode == 2:
         raise MetaDataException("Unterminated continuation in " + metafile.name)
-    elif mode == 3:
+    if mode == 3:
         raise MetaDataException("Unterminated build in " + metafile.name)
 
-    post_metadata_parse(thisinfo)
+    return app
 
-    return (appid, thisinfo)
 
+def write_plaintext_metadata(mf, app, w_comment, w_field, w_build):
 
-# Write a metadata file.
-#
-# 'mf'      - Writer interface (file, StringIO, ...)
-# 'app'     - The app data
-def write_metadata(mf, app):
-
-    def writecomments(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)
-        if value is None:
-            value = app[field]
-        t = metafieldtype(field)
-        if t == 'list':
-            value = ','.join(value)
-        elif t == 'multiline':
-            if type(value) == list:
-                value = '\n' + '\n'.join(value) + '\n.'
-            else:
-                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')
+    def w_comments(key):
+        if key not in app.comments:
+            return
+        for line in app.comments[key]:
+            w_comment(line)
+
+    def w_field_always(f, v=None):
+        if v is None:
+            v = app.get_field(f)
+        w_comments(f)
+        w_field(f, v)
+
+    def w_field_nonempty(f, v=None):
+        if v is None:
+            v = app.get_field(f)
+        w_comments(f)
+        if v:
+            w_field(f, v)
+
+    w_field_nonempty('Disabled')
+    if app.AntiFeatures:
+        w_field_always('AntiFeatures')
+    w_field_nonempty('Provides')
+    w_field_always('Categories')
+    w_field_always('License')
+    w_field_always('Web Site')
+    w_field_always('Source Code')
+    w_field_always('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')
-    writefield_nonempty('Name')
-    writefield_nonempty('Auto Name')
-    writefield('Summary')
-    writefield('Description', description_txt(app['Description']))
+    w_field_nonempty('Name')
+    w_field_nonempty('Auto Name')
+    w_field_always('Summary')
+    w_field_always('Description', description_txt(app.Description))
     mf.write('\n')
-    if app['Requires Root']:
-        writefield('Requires Root', 'yes')
+    if app.RequiresRoot:
+        w_field_always('Requires Root', 'yes')
         mf.write('\n')
-    if app['Repo Type']:
-        writefield('Repo Type')
-        writefield('Repo')
-        if app['Binaries']:
-            writefield('Binaries')
+    if app.RepoType:
+        w_field_always('Repo Type')
+        w_field_always('Repo')
+        if app.Binaries:
+            w_field_always('Binaries')
         mf.write('\n')
-    for build in sorted_builds(app['builds']):
 
-        if build['version'] == "Ignore":
+    for build in sorted_builds(app.builds):
+
+        if build.version == "Ignore":
             continue
 
-        writecomments('build:' + build['vercode'])
-        mf.write("Build:%s,%s\n" % (build['version'], build['vercode']))
+        w_comments('build:' + build.vercode)
+        w_build(build)
+        mf.write('\n')
+
+    if app.MaintainerNotes:
+        w_field_always('Maintainer Notes', app.MaintainerNotes)
+        mf.write('\n')
+
+    w_field_nonempty('Archive Policy')
+    w_field_always('Auto Update Mode')
+    w_field_always('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.CurrentVersion:
+        w_field_always('Current Version')
+        w_field_always('Current Version Code')
+    if app.NoSourceSince:
+        mf.write('\n')
+        w_field_always('No Source Since')
+    w_comments(None)
+
 
-        def write_builditem(key, value):
+# Write a metadata file in txt format.
+#
+# 'mf'      - Writer interface (file, StringIO, ...)
+# 'app'     - The app data
+def write_txt_metadata(mf, app):
 
-            if key in ['version', 'vercode']:
-                return
+    def w_comment(line):
+        mf.write("# %s\n" % line)
 
-            if value == flag_defaults[key]:
-                return
+    def w_field(f, v):
+        t = fieldtype(f)
+        if t == TYPE_LIST:
+            v = ','.join(v)
+        elif t == TYPE_MULTILINE:
+            v = '\n' + v + '\n.'
+        mf.write("%s:%s\n" % (f, v))
 
-            t = flagtype(key)
+    def w_build(build):
+        mf.write("Build:%s,%s\n" % (build.version, build.vercode))
 
-            logging.debug("...writing {0} : {1}".format(key, value))
-            outline = '    %s=' % key
+        for f in build_flags_order:
+            v = build.get_flag(f)
+            if not v:
+                continue
 
-            if t == 'string':
-                outline += value
-            elif t == 'bool':
-                outline += 'yes'
-            elif t == 'script':
-                outline += '&& \\\n        '.join([s.lstrip() for s in value.split('&& ')])
-            elif t == 'list':
-                outline += ','.join(value) if type(value) == list else value
+            t = flagtype(f)
+            mf.write('    %s=' % f)
+            if t == TYPE_STRING:
+                mf.write(v)
+            elif t == TYPE_BOOL:
+                mf.write('yes')
+            elif t == TYPE_SCRIPT:
+                first = True
+                for s in v.split(' && '):
+                    if first:
+                        first = False
+                    else:
+                        mf.write(' && \\\n        ')
+                    mf.write(s)
+            elif t == TYPE_LIST:
+                mf.write(','.join(v))
+
+            mf.write('\n')
+
+    write_plaintext_metadata(mf, app, w_comment, w_field, w_build)
+
+
+def write_yaml_metadata(mf, app):
+
+    def w_comment(line):
+        mf.write("# %s\n" % line)
+
+    def escape(v):
+        if not v:
+            return ''
+        if any(c in v for c in [': ', '%', '@', '*']):
+            return "'" + v.replace("'", "''") + "'"
+        return v
+
+    def w_field(f, v, prefix='', t=None):
+        if t is None:
+            t = fieldtype(f)
+        v = ''
+        if t == TYPE_LIST:
+            v = '\n'
+            for e in v:
+                v += prefix + ' - ' + escape(e) + '\n'
+        elif t == TYPE_MULTILINE:
+            v = ' |\n'
+            for l in v.splitlines():
+                if l:
+                    v += prefix + '  ' + l + '\n'
+                else:
+                    v += '\n'
+        elif t == TYPE_BOOL:
+            v = ' yes\n'
+        elif t == TYPE_SCRIPT:
+            cmds = [s + '&& \\' for s in v.split('&& ')]
+            if len(cmds) > 0:
+                cmds[-1] = cmds[-1][:-len('&& \\')]
+            w_field(f, cmds, prefix, 'multiline')
+            return
+        else:
+            v = ' ' + escape(v) + '\n'
+
+        mf.write(prefix)
+        mf.write(f)
+        mf.write(":")
+        mf.write(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, '  - ', TYPE_STRING)
+        w_field('versionCode', build.vercode, '    ', TYPE_STRING)
+        for f in build_flags_order:
+            v = build.get_flag(f)
+            if not v:
+                continue
 
-            outline += '\n'
-            mf.write(outline)
+            w_field(f, v, '    ', flagtype(f))
 
-        for flag in flag_defaults:
-            value = build[flag]
-            if value:
-                write_builditem(flag, value)
-        mf.write('\n')
+    write_plaintext_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_metadata(fmt, mf, app):
+    if fmt == 'txt':
+        return write_txt_metadata(mf, app)
+    if fmt == 'yaml':
+        return write_yaml_metadata(mf, app)
+    raise MetaDataException("Unknown metadata format given")
index 1e4fbeb8a92708c7e1ded0496e6cfdcd922c92c3..49aa69468e12864d60c992ec76815014aa0d8ef8 100644 (file)
@@ -117,7 +117,7 @@ def main():
             sys.exit(1)
         app = allapps[appid]
 
-        if app.get('Binaries', None):
+        if app.Binaries is not None:
 
             # It's an app where we build from source, and verify the apk
             # contents against a developer's binary, and then publish their
index 7ae9f9d5b2900f67323d780f00e6544fc6f2fad8..51d82c37e21b283f89baec9291b03ee4e4e53a5a 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from argparse import ArgumentParser
+import os
 import logging
-import StringIO
+try:
+    from cStringIO import StringIO
+except:
+    from StringIO import StringIO
 
 import common
 import metadata
@@ -29,6 +33,18 @@ config = None
 options = None
 
 
+def proper_format(app):
+    s = StringIO()
+    # TODO: currently reading entire file again, should reuse first
+    # read in metadata.py
+    with open(app.metadatapath, 'r') as f:
+        cur_content = f.read()
+    metadata.write_txt_metadata(s, app)
+    content = s.getvalue()
+    s.close()
+    return content == cur_content
+
+
 def main():
 
     global config, options
@@ -38,6 +54,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=None,
+                        help="Rewrite to a specific format")
     parser.add_argument("appid", nargs='*', help="app-id in the form APPID")
     options = parser.parse_args()
 
@@ -47,28 +65,34 @@ def main():
     allapps = metadata.read_metadata(xref=True)
     apps = common.read_app_args(options.appid, allapps, False)
 
+    if options.list and options.to is not None:
+        parser.error("Cannot use --list and --to at the same time")
+
+    supported = ['txt', 'yaml']
+
+    if options.to is not None and options.to not in supported:
+        parser.error("Must give a valid format to --to")
+
     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(app.metadatapath)
+        if not options.to and ext not in supported:
+            logging.info("Ignoring %s file at '%s'" % (ext, app.metadatapath))
             continue
-        logging.debug("Rewriting " + metadatapath)
+
+        to_ext = ext
+        if options.to is not None:
+            to_ext = options.to
+
         if options.list:
-            s = StringIO.StringIO()
-            # TODO: currently reading entire file again, should reuse first
-            # read in metadata.py
-            with open(metadatapath, 'r') as f:
-                cur_content = f.read()
-            metadata.write_metadata(s, app)
-            content = s.getvalue()
-            s.close()
-            if content != cur_content:
-                print(metadatapath)
-        else:
-            with open(metadatapath, 'w') as f:
-                metadata.write_metadata(f, app)
+            if not proper_format(app):
+                print app.metadatapath
+            continue
+
+        with open(base + '.' + to_ext, 'w') as f:
+            metadata.write_metadata(to_ext, f, app)
+
+        if ext != to_ext:
+            os.remove(app.metadatapath)
 
     logging.debug("Finished.")
 
index 7f6d7d91d36b1b123a1f6be4ed980e763b45f07e..f57c2f1be7e43a24d83e307ad0820abfa6815bbf 100644 (file)
@@ -31,18 +31,18 @@ config = None
 options = None
 
 
-def get_gradle_compile_commands(thisbuild):
+def get_gradle_compile_commands(build):
     compileCommands = ['compile', 'releaseCompile']
-    if thisbuild['gradle'] and thisbuild['gradle'] != ['yes']:
-        compileCommands += [flavor + 'Compile' for flavor in thisbuild['gradle']]
-        compileCommands += [flavor + 'ReleaseCompile' for flavor in thisbuild['gradle']]
+    if build.gradle and build.gradle != ['yes']:
+        compileCommands += [flavor + 'Compile' for flavor in build.gradle]
+        compileCommands += [flavor + 'ReleaseCompile' for flavor in build.gradle]
 
     return [re.compile(r'\s*' + c, re.IGNORECASE) for c in compileCommands]
 
 
 # Scan the source code in the given directory (and all subdirectories)
 # and return the number of fatal problems encountered
-def scan_source(build_dir, root_dir, thisbuild):
+def scan_source(build_dir, root_dir, build):
 
     count = 0
 
@@ -72,24 +72,39 @@ def scan_source(build_dir, root_dir, thisbuild):
             if r.match(s):
                 yield n
 
-    scanignore = common.getpaths(build_dir, thisbuild, 'scanignore')
-    scandelete = common.getpaths(build_dir, thisbuild, 'scandelete')
+    gradle_mavenrepo = re.compile(r'maven *{ *(url)? *[\'"]?([^ \'"]*)[\'"]?')
+
+    allowed_repos = [re.compile(r'^https?://' + re.escape(repo) + r'/*') for repo in [
+        'repo1.maven.org/maven2',  # mavenCentral()
+        'jcenter.bintray.com',     # jcenter()
+        'jitpack.io',
+        'repo.maven.apache.org/maven2',
+        'oss.sonatype.org/content/repositories/snapshots',
+        'oss.sonatype.org/content/repositories/releases',
+        'oss.sonatype.org/content/groups/public',
+        ]
+    ]
+
+    scanignore = common.getpaths_map(build_dir, build.scanignore)
+    scandelete = common.getpaths_map(build_dir, build.scandelete)
 
     scanignore_worked = set()
     scandelete_worked = set()
 
     def toignore(fd):
-        for p in scanignore:
-            if fd.startswith(p):
-                scanignore_worked.add(p)
-                return True
+        for k, paths in scanignore.iteritems():
+            for p in paths:
+                if fd.startswith(p):
+                    scanignore_worked.add(k)
+                    return True
         return False
 
     def todelete(fd):
-        for p in scandelete:
-            if fd.startswith(p):
-                scandelete_worked.add(p)
-                return True
+        for k, paths in scandelete.iteritems():
+            for p in paths:
+                if fd.startswith(p):
+                    scandelete_worked.add(k)
+                    return True
         return False
 
     def ignoreproblem(what, fd, fp):
@@ -102,6 +117,8 @@ def scan_source(build_dir, root_dir, thisbuild):
         return 0
 
     def warnproblem(what, fd):
+        if toignore(fd):
+            return
         logging.warn('Found %s at %s' % (what, fd))
 
     def handleproblem(what, fd, fp):
@@ -123,7 +140,20 @@ def scan_source(build_dir, root_dir, thisbuild):
             d = f.read(1024)
         return bool(d.translate(None, textchars))
 
-    gradle_compile_commands = get_gradle_compile_commands(thisbuild)
+    # False positives patterns for files that are binary and executable.
+    safe_paths = [re.compile(r) for r in [
+        r".*/drawable[^/]*/.*\.png$",  # png drawables
+        r".*/mipmap[^/]*/.*\.png$",    # png mipmaps
+        ]
+    ]
+
+    def safe_path(path):
+        for sp in safe_paths:
+            if sp.match(path):
+                return True
+        return False
+
+    gradle_compile_commands = get_gradle_compile_commands(build)
 
     def is_used_by_gradle(line):
         return any(command.match(line) for command in gradle_compile_commands)
@@ -138,6 +168,9 @@ def scan_source(build_dir, root_dir, thisbuild):
 
         for curfile in f:
 
+            if curfile in ['.DS_Store']:
+                continue
+
             # Path (relative) to the file
             fp = os.path.join(r, curfile)
 
@@ -145,7 +178,7 @@ def scan_source(build_dir, root_dir, thisbuild):
                 continue
 
             fd = fp[len(build_dir) + 1:]
-            ext = common.get_extension(fd)
+            _, ext = common.get_extension(fd)
 
             if ext == 'so':
                 count += handleproblem('shared library', fd, fp)
@@ -172,18 +205,25 @@ def scan_source(build_dir, root_dir, thisbuild):
             elif ext == 'gradle':
                 if not os.path.isfile(fp):
                     continue
-                for i, line in enumerate(file(fp)):
-                    i = i + 1
+                with open(fp, 'r') as f:
+                    lines = f.readlines()
+                for i, line in enumerate(lines):
                     if is_used_by_gradle(line):
                         for name in suspects_found(line):
-                            count += handleproblem('usual supect \'%s\' at line %d' % (name, i), fd, fp)
+                            count += handleproblem('usual supect \'%s\' at line %d' % (name, i+1), fd, fp)
+                noncomment_lines = [l for l in lines if not common.gradle_comment.match(l)]
+                joined = re.sub(r'[\n\r\s]+', ' ', ' '.join(noncomment_lines))
+                for m in gradle_mavenrepo.finditer(joined):
+                    url = m.group(2)
+                    if not any(r.match(url) for r in allowed_repos):
+                        count += handleproblem('unknown maven repo \'%s\'' % url, fd, fp)
 
             elif ext in ['', 'bin', 'out', 'exe']:
                 if is_binary(fp):
                     count += handleproblem('binary', fd, fp)
 
             elif is_executable(fp):
-                if is_binary(fp):
+                if is_binary(fp) and not safe_path(fd):
                     warnproblem('possible binary', fd)
 
     for p in scanignore:
@@ -196,14 +236,6 @@ def scan_source(build_dir, root_dir, thisbuild):
             logging.error('Unused scandelete path: %s' % p)
             count += 1
 
-    # Presence of a jni directory without buildjni=yes might
-    # indicate a problem (if it's not a problem, explicitly use
-    # buildjni=no to bypass this check)
-    if (os.path.exists(os.path.join(root_dir, 'jni')) and
-            not thisbuild['buildjni']):
-        logging.error('Found jni directory, but buildjni is not enabled. Set it to \'no\' to ignore.')
-        count += 1
-
     return count
 
 
@@ -234,10 +266,10 @@ def main():
 
     for appid, app in apps.iteritems():
 
-        if app['Disabled']:
+        if app.Disabled:
             logging.info("Skipping %s: disabled" % appid)
             continue
-        if not app['builds']:
+        if not app.builds:
             logging.info("Skipping %s: no builds specified" % appid)
             continue
 
@@ -245,32 +277,32 @@ def main():
 
         try:
 
-            if app['Repo Type'] == 'srclib':
-                build_dir = os.path.join('build', 'srclib', app['Repo'])
+            if app.RepoType == 'srclib':
+                build_dir = os.path.join('build', 'srclib', app.Repo)
             else:
                 build_dir = os.path.join('build', appid)
 
             # Set up vcs interface and make sure we have the latest code...
-            vcs = common.getvcs(app['Repo Type'], app['Repo'], build_dir)
+            vcs = common.getvcs(app.RepoType, app.Repo, build_dir)
 
-            for thisbuild in app['builds']:
+            for build in app.builds:
 
-                if thisbuild['disable']:
+                if build.disable:
                     logging.info("...skipping version %s - %s" % (
-                        thisbuild['version'], thisbuild.get('disable', thisbuild['commit'][1:])))
+                        build.version, build.get('disable', build.commit[1:])))
                 else:
-                    logging.info("...scanning version " + thisbuild['version'])
+                    logging.info("...scanning version " + build.version)
 
                     # Prepare the source code...
-                    root_dir, _ = common.prepare_source(vcs, app, thisbuild,
+                    root_dir, _ = common.prepare_source(vcs, app, build,
                                                         build_dir, srclib_dir,
                                                         extlib_dir, False)
 
                     # Do the scan...
-                    count = scan_source(build_dir, root_dir, thisbuild)
+                    count = scan_source(build_dir, root_dir, build)
                     if count > 0:
                         logging.warn('Scanner found %d problems in %s (%s)' % (
-                            count, appid, thisbuild['vercode']))
+                            count, appid, build.vercode))
                         probcount += count
 
         except BuildException as be:
index 1c07cad87b84f0929efbea2776f029aa83fe9c52..f80505c354ae4610dd60477f4f4653aa33f15ee7 100644 (file)
@@ -68,8 +68,8 @@ def main():
         sys.exit(1)
 
     # Get all metadata-defined apps...
-    allmetaapps = [a for a in metadata.read_metadata().itervalues()]
-    metaapps = [a for a in allmetaapps if not a['Disabled']]
+    allmetaapps = [app for app in metadata.read_metadata().itervalues()]
+    metaapps = [app for app in allmetaapps if not app.Disabled]
 
     statsdir = 'stats'
     logsdir = os.path.join(statsdir, 'logs')
@@ -217,9 +217,9 @@ def main():
     logging.info("Processing repo types...")
     repotypes = Counter()
     for app in metaapps:
-        rtype = app['Repo Type'] or 'none'
+        rtype = app.RepoType or 'none'
         if rtype == 'srclib':
-            rtype = common.getsrclibvcs(app['Repo'])
+            rtype = common.getsrclibvcs(app.Repo)
         repotypes[rtype] += 1
     with open(os.path.join(statsdir, 'repotypes.txt'), 'w') as f:
         for rtype, count in repotypes.most_common():
@@ -229,7 +229,7 @@ def main():
     logging.info("Processing update check modes...")
     ucms = Counter()
     for app in metaapps:
-        checkmode = app['Update Check Mode']
+        checkmode = app.UpdateCheckMode
         if checkmode.startswith('RepoManifest/'):
             checkmode = checkmode[:12]
         if checkmode.startswith('Tags '):
@@ -242,7 +242,7 @@ def main():
     logging.info("Processing categories...")
     ctgs = Counter()
     for app in metaapps:
-        for category in app['Categories']:
+        for category in app.Categories:
             ctgs[category] += 1
     with open(os.path.join(statsdir, 'categories.txt'), 'w') as f:
         for category, count in ctgs.most_common():
@@ -251,9 +251,9 @@ def main():
     logging.info("Processing antifeatures...")
     afs = Counter()
     for app in metaapps:
-        if app['AntiFeatures'] is None:
+        if app.AntiFeatures is None:
             continue
-        for antifeature in app['AntiFeatures']:
+        for antifeature in app.AntiFeatures:
             afs[antifeature] += 1
     with open(os.path.join(statsdir, 'antifeatures.txt'), 'w') as f:
         for antifeature, count in afs.most_common():
@@ -263,7 +263,7 @@ def main():
     logging.info("Processing licenses...")
     licenses = Counter()
     for app in metaapps:
-        license = app['License']
+        license = app.License
         licenses[license] += 1
     with open(os.path.join(statsdir, 'licenses.txt'), 'w') as f:
         for license, count in licenses.most_common():
@@ -271,7 +271,7 @@ def main():
 
     # Write list of disabled apps...
     logging.info("Processing disabled apps...")
-    disabled = [a['id'] for a in allmetaapps if a['Disabled']]
+    disabled = [app.id for app in allmetaapps if app.Disabled]
     with open(os.path.join(statsdir, 'disabled_apps.txt'), 'w') as f:
         for appid in sorted(disabled):
             f.write(appid + '\n')
index 4758e78901350a503bec4b9ecf792a245778f561..3a01a7c21cb2db097621d45eca9fd828053c4fbf 100644 (file)
@@ -45,9 +45,9 @@ import metadata
 from common import FDroidPopen, SdkToolsPopen
 from metadata import MetaDataException
 
+screen_densities = ['640', '480', '320', '240', '160', '120']
 
-def get_densities():
-    return ['640', '480', '320', '240', '160', '120']
+all_screen_densities = ['0'] + screen_densities
 
 
 def dpi_to_px(density):
@@ -59,15 +59,19 @@ def px_to_dpi(px):
 
 
 def get_icon_dir(repodir, density):
-    if density is None:
+    if density == '0':
         return os.path.join(repodir, "icons")
     return os.path.join(repodir, "icons-%s" % density)
 
 
 def get_icon_dirs(repodir):
-    for density in get_densities():
+    for density in screen_densities:
+        yield get_icon_dir(repodir, density)
+
+
+def get_all_icon_dirs(repodir):
+    for density in all_screen_densities:
         yield get_icon_dir(repodir, density)
-    yield os.path.join(repodir, "icons")
 
 
 def update_wiki(apps, sortedids, apks):
@@ -90,43 +94,43 @@ def update_wiki(apps, sortedids, apks):
         app = apps[appid]
 
         wikidata = ''
-        if app['Disabled']:
-            wikidata += '{{Disabled|' + app['Disabled'] + '}}\n'
-        if 'AntiFeatures' in app:
-            for af in app['AntiFeatures']:
+        if app.Disabled:
+            wikidata += '{{Disabled|' + app.Disabled + '}}\n'
+        if app.AntiFeatures:
+            for af in app.AntiFeatures:
                 wikidata += '{{AntiFeature|' + af + '}}\n'
-        if app['Requires Root']:
+        if app.RequiresRoot:
             requiresroot = 'Yes'
         else:
             requiresroot = 'No'
         wikidata += '{{App|id=%s|name=%s|added=%s|lastupdated=%s|source=%s|tracker=%s|web=%s|changelog=%s|donate=%s|flattr=%s|bitcoin=%s|litecoin=%s|license=%s|root=%s}}\n' % (
             appid,
-            app['Name'],
-            time.strftime('%Y-%m-%d', app['added']) if 'added' in app else '',
-            time.strftime('%Y-%m-%d', app['lastupdated']) if 'lastupdated' in app else '',
-            app['Source Code'],
-            app['Issue Tracker'],
-            app['Web Site'],
-            app['Changelog'],
-            app['Donate'],
-            app['FlattrID'],
-            app['Bitcoin'],
-            app['Litecoin'],
-            app['License'],
+            app.Name,
+            time.strftime('%Y-%m-%d', app.added) if app.added else '',
+            time.strftime('%Y-%m-%d', app.lastupdated) if app.lastupdated else '',
+            app.SourceCode,
+            app.IssueTracker,
+            app.WebSite,
+            app.Changelog,
+            app.Donate,
+            app.FlattrID,
+            app.Bitcoin,
+            app.Litecoin,
+            app.License,
             requiresroot)
 
-        if app['Provides']:
-            wikidata += "This app provides: %s" % ', '.join(app['Summary'].split(','))
+        if app.Provides:
+            wikidata += "This app provides: %s" % ', '.join(app.Summary.split(','))
 
-        wikidata += app['Summary']
+        wikidata += app.Summary
         wikidata += " - [https://f-droid.org/repository/browse/?fdid=" + appid + " view in repository]\n\n"
 
         wikidata += "=Description=\n"
-        wikidata += metadata.description_wiki(app['Description']) + "\n"
+        wikidata += metadata.description_wiki(app.Description) + "\n"
 
         wikidata += "=Maintainer Notes=\n"
-        if 'Maintainer Notes' in app:
-            wikidata += metadata.description_wiki(app['Maintainer Notes']) + "\n"
+        if app.MaintainerNotes:
+            wikidata += metadata.description_wiki(app.MaintainerNotes) + "\n"
         wikidata += "\nMetadata: [https://gitlab.com/fdroid/fdroiddata/blob/master/metadata/{0}.txt current] [https://gitlab.com/fdroid/fdroiddata/commits/master/metadata/{0}.txt history]\n".format(appid)
 
         # Get a list of all packages for this application...
@@ -136,32 +140,32 @@ def update_wiki(apps, sortedids, apks):
         buildfails = False
         for apk in apks:
             if apk['id'] == appid:
-                if str(apk['versioncode']) == app['Current Version Code']:
+                if str(apk['versioncode']) == app.CurrentVersionCode:
                     gotcurrentver = True
                 apklist.append(apk)
         # Include ones we can't build, as a special case...
-        for thisbuild in app['builds']:
-            if thisbuild['disable']:
-                if thisbuild['vercode'] == app['Current Version Code']:
+        for build in app.builds:
+            if build.disable:
+                if build.vercode == app.CurrentVersionCode:
                     cantupdate = True
                 # TODO: Nasty: vercode is a string in the build, and an int elsewhere
-                apklist.append({'versioncode': int(thisbuild['vercode']),
-                                'version': thisbuild['version'],
-                                'buildproblem': "The build for this version was manually disabled. Reason: {0}".format(thisbuild['disable']),
+                apklist.append({'versioncode': int(build.vercode),
+                                'version': build.version,
+                                'buildproblem': "The build for this version was manually disabled. Reason: {0}".format(build.disable),
                                 })
             else:
                 builtit = False
                 for apk in apklist:
-                    if apk['versioncode'] == int(thisbuild['vercode']):
+                    if apk['versioncode'] == int(build.vercode):
                         builtit = True
                         break
                 if not builtit:
                     buildfails = True
-                    apklist.append({'versioncode': int(thisbuild['vercode']),
-                                    'version': thisbuild['version'],
-                                    'buildproblem': "The build for this version appears to have failed. Check the [[{0}/lastbuild_{1}|build log]].".format(appid, thisbuild['vercode']),
+                    apklist.append({'versioncode': int(build.vercode),
+                                    'version': build.version,
+                                    'buildproblem': "The build for this version appears to have failed. Check the [[{0}/lastbuild_{1}|build log]].".format(appid, build.vercode),
                                     })
-        if app['Current Version Code'] == '0':
+        if app.CurrentVersionCode == '0':
             cantupdate = True
         # Sort with most recent first...
         apklist = sorted(apklist, key=lambda apk: apk['versioncode'], reverse=True)
@@ -173,13 +177,13 @@ def update_wiki(apps, sortedids, apks):
             wikidata += "We don't have the current version of this app."
         else:
             wikidata += "We have the current version of this app."
-        wikidata += " (Check mode: " + app['Update Check Mode'] + ") "
-        wikidata += " (Auto-update mode: " + app['Auto Update Mode'] + ")\n\n"
-        if len(app['No Source Since']) > 0:
-            wikidata += "This application has partially or entirely been missing source code since version " + app['No Source Since'] + ".\n\n"
-        if len(app['Current Version']) > 0:
-            wikidata += "The current (recommended) version is " + app['Current Version']
-            wikidata += " (version code " + app['Current Version Code'] + ").\n\n"
+        wikidata += " (Check mode: " + app.UpdateCheckMode + ") "
+        wikidata += " (Auto-update mode: " + app.AutoUpdateMode + ")\n\n"
+        if len(app.NoSourceSince) > 0:
+            wikidata += "This application has partially or entirely been missing source code since version " + app.NoSourceSince + ".\n\n"
+        if len(app.CurrentVersion) > 0:
+            wikidata += "The current (recommended) version is " + app.CurrentVersion
+            wikidata += " (version code " + app.CurrentVersionCode + ").\n\n"
         validapks = 0
         for apk in apklist:
             wikidata += "==" + apk['version'] + "==\n"
@@ -196,21 +200,21 @@ def update_wiki(apps, sortedids, apks):
             wikidata += "Version code: " + str(apk['versioncode']) + '\n'
 
         wikidata += '\n[[Category:' + wikicat + ']]\n'
-        if len(app['No Source Since']) > 0:
+        if len(app.NoSourceSince) > 0:
             wikidata += '\n[[Category:Apps missing source code]]\n'
-        if validapks == 0 and not app['Disabled']:
+        if validapks == 0 and not app.Disabled:
             wikidata += '\n[[Category:Apps with no packages]]\n'
-        if cantupdate and not app['Disabled']:
+        if cantupdate and not app.Disabled:
             wikidata += "\n[[Category:Apps we can't update]]\n"
-        if buildfails and not app['Disabled']:
+        if buildfails and not app.Disabled:
             wikidata += "\n[[Category:Apps with failing builds]]\n"
-        elif not gotcurrentver and not cantupdate and not app['Disabled'] and app['Update Check Mode'] != "Static":
+        elif not gotcurrentver and not cantupdate and not app.Disabled and app.UpdateCheckMode != "Static":
             wikidata += '\n[[Category:Apps to Update]]\n'
-        if app['Disabled']:
+        if app.Disabled:
             wikidata += '\n[[Category:Apps that are disabled]]\n'
-        if app['Update Check Mode'] == 'None' and not app['Disabled']:
+        if app.UpdateCheckMode == 'None' and not app.Disabled:
             wikidata += '\n[[Category:Apps with no update check]]\n'
-        for appcat in app['Categories']:
+        for appcat in app.Categories:
             wikidata += '\n[[Category:{0}]]\n'.format(appcat)
 
         # We can't have underscores in the page name, even if they're in
@@ -227,7 +231,7 @@ def update_wiki(apps, sortedids, apks):
         # Make a redirect from the name to the ID too, unless there's
         # already an existing page with the name and it isn't a redirect.
         noclobber = False
-        apppagename = app['Name'].replace('_', ' ')
+        apppagename = app.Name.replace('_', ' ')
         apppagename = apppagename.replace('{', '')
         apppagename = apppagename.replace('}', ' ')
         apppagename = apppagename.replace(':', ' ')
@@ -286,19 +290,29 @@ def delete_disabled_builds(apps, apkcache, repodirs):
     :param repodirs: the repo directories to process
     """
     for appid, app in apps.iteritems():
-        for build in app['builds']:
-            if build['disable']:
-                apkfilename = appid + '_' + str(build['vercode']) + '.apk'
-                for repodir in repodirs:
-                    apkpath = os.path.join(repodir, apkfilename)
-                    ascpath = apkpath + ".asc"
-                    srcpath = os.path.join(repodir, apkfilename[:-4] + "_src.tar.gz")
-                    for name in [apkpath, srcpath, ascpath]:
-                        if os.path.exists(name):
-                            logging.warn("Deleting disabled build output " + apkfilename)
-                            os.remove(name)
-                if apkfilename in apkcache:
-                    del apkcache[apkfilename]
+        for build in app.builds:
+            if not build.disable:
+                continue
+            apkfilename = appid + '_' + str(build.vercode) + '.apk'
+            iconfilename = "%s.%s.png" % (
+                appid,
+                build.vercode)
+            for repodir in repodirs:
+                files = [
+                    os.path.join(repodir, apkfilename),
+                    os.path.join(repodir, apkfilename + '.asc'),
+                    os.path.join(repodir, apkfilename[:-4] + "_src.tar.gz"),
+                ]
+                for density in all_screen_densities:
+                    repo_dir = get_icon_dir(repodir, density)
+                    files.append(os.path.join(repo_dir, iconfilename))
+
+                for f in files:
+                    if os.path.exists(f):
+                        logging.info("Deleting disabled build output " + f)
+                        os.remove(f)
+            if apkfilename in apkcache:
+                del apkcache[apkfilename]
 
 
 def resize_icon(iconpath, density):
@@ -327,7 +341,7 @@ def resize_all_icons(repodirs):
     :param repodirs: the repo directories to process
     """
     for repodir in repodirs:
-        for density in get_densities():
+        for density in screen_densities:
             icon_dir = get_icon_dir(repodir, density)
             icon_glob = os.path.join(icon_dir, '*.png')
             for iconpath in glob.glob(icon_glob):
@@ -403,8 +417,7 @@ def scan_apks(apps, apkcache, repodir, knownapks):
 
     cachechanged = False
 
-    icon_dirs = get_icon_dirs(repodir)
-    for icon_dir in icon_dirs:
+    for icon_dir in get_all_icon_dirs(repodir):
         if os.path.exists(icon_dir):
             if options.clean:
                 shutil.rmtree(icon_dir)
@@ -440,8 +453,8 @@ def scan_apks(apps, apkcache, repodir, knownapks):
 
         usecache = False
         if apkfilename in apkcache:
-            thisinfo = apkcache[apkfilename]
-            if thisinfo['sha256'] == shasum:
+            apk = apkcache[apkfilename]
+            if apk['sha256'] == shasum:
                 logging.debug("Reading " + apkfilename + " from cache")
                 usecache = True
             else:
@@ -449,17 +462,17 @@ def scan_apks(apps, apkcache, repodir, knownapks):
 
         if not usecache:
             logging.debug("Processing " + apkfilename)
-            thisinfo = {}
-            thisinfo['apkname'] = apkfilename
-            thisinfo['sha256'] = shasum
+            apk = {}
+            apk['apkname'] = apkfilename
+            apk['sha256'] = shasum
             srcfilename = apkfilename[:-4] + "_src.tar.gz"
             if os.path.exists(os.path.join(repodir, srcfilename)):
-                thisinfo['srcname'] = srcfilename
-            thisinfo['size'] = os.path.getsize(apkfile)
-            thisinfo['permissions'] = set()
-            thisinfo['features'] = set()
-            thisinfo['icons_src'] = {}
-            thisinfo['icons'] = {}
+                apk['srcname'] = srcfilename
+            apk['size'] = os.path.getsize(apkfile)
+            apk['permissions'] = set()
+            apk['features'] = set()
+            apk['icons_src'] = {}
+            apk['icons'] = {}
             p = SdkToolsPopen(['aapt', 'dump', 'badging', apkfile], output=False)
             if p.returncode != 0:
                 if options.delete_unknown:
@@ -474,51 +487,51 @@ def scan_apks(apps, apkcache, repodir, knownapks):
             for line in p.output.splitlines():
                 if line.startswith("package:"):
                     try:
-                        thisinfo['id'] = re.match(name_pat, line).group(1)
-                        thisinfo['versioncode'] = int(re.match(vercode_pat, line).group(1))
-                        thisinfo['version'] = re.match(vername_pat, line).group(1)
+                        apk['id'] = re.match(name_pat, line).group(1)
+                        apk['versioncode'] = int(re.match(vercode_pat, line).group(1))
+                        apk['version'] = re.match(vername_pat, line).group(1)
                     except Exception, e:
                         logging.error("Package matching failed: " + str(e))
                         logging.info("Line was: " + line)
                         sys.exit(1)
                 elif line.startswith("application:"):
-                    thisinfo['name'] = re.match(label_pat, line).group(1)
+                    apk['name'] = re.match(label_pat, line).group(1)
                     # Keep path to non-dpi icon in case we need it
                     match = re.match(icon_pat_nodpi, line)
                     if match:
-                        thisinfo['icons_src']['-1'] = match.group(1)
+                        apk['icons_src']['-1'] = match.group(1)
                 elif line.startswith("launchable-activity:"):
                     # Only use launchable-activity as fallback to application
-                    if not thisinfo['name']:
-                        thisinfo['name'] = re.match(label_pat, line).group(1)
-                    if '-1' not in thisinfo['icons_src']:
+                    if not apk['name']:
+                        apk['name'] = re.match(label_pat, line).group(1)
+                    if '-1' not in apk['icons_src']:
                         match = re.match(icon_pat_nodpi, line)
                         if match:
-                            thisinfo['icons_src']['-1'] = match.group(1)
+                            apk['icons_src']['-1'] = match.group(1)
                 elif line.startswith("application-icon-"):
                     match = re.match(icon_pat, line)
                     if match:
                         density = match.group(1)
                         path = match.group(2)
-                        thisinfo['icons_src'][density] = path
+                        apk['icons_src'][density] = path
                 elif line.startswith("sdkVersion:"):
                     m = re.match(sdkversion_pat, line)
                     if m is None:
                         logging.error(line.replace('sdkVersion:', '')
                                       + ' is not a valid minSdkVersion!')
                     else:
-                        thisinfo['sdkversion'] = m.group(1)
+                        apk['sdkversion'] = m.group(1)
                 elif line.startswith("maxSdkVersion:"):
-                    thisinfo['maxsdkversion'] = re.match(sdkversion_pat, line).group(1)
+                    apk['maxsdkversion'] = re.match(sdkversion_pat, line).group(1)
                 elif line.startswith("native-code:"):
-                    thisinfo['nativecode'] = []
+                    apk['nativecode'] = []
                     for arch in line[13:].split(' '):
-                        thisinfo['nativecode'].append(arch[1:-1])
+                        apk['nativecode'].append(arch[1:-1])
                 elif line.startswith("uses-permission:"):
                     perm = re.match(string_pat, line).group(1)
                     if perm.startswith("android.permission."):
                         perm = perm[19:]
-                    thisinfo['permissions'].add(perm)
+                    apk['permissions'].add(perm)
                 elif line.startswith("uses-feature:"):
                     perm = re.match(string_pat, line).group(1)
                     # Filter out this, it's only added with the latest SDK tools and
@@ -527,11 +540,11 @@ def scan_apks(apps, apkcache, repodir, knownapks):
                             and perm != "android.hardware.screen.landscape":
                         if perm.startswith("android.feature."):
                             perm = perm[16:]
-                        thisinfo['features'].add(perm)
+                        apk['features'].add(perm)
 
-            if 'sdkversion' not in thisinfo:
+            if 'sdkversion' not in apk:
                 logging.warn("No SDK version information found in {0}".format(apkfile))
-                thisinfo['sdkversion'] = 0
+                apk['sdkversion'] = 0
 
             # Check for debuggable apks...
             if common.isApkDebuggable(apkfile, config):
@@ -539,20 +552,20 @@ def scan_apks(apps, apkcache, repodir, knownapks):
 
             # Get the signature (or md5 of, to be precise)...
             logging.debug('Getting signature of {0}'.format(apkfile))
-            thisinfo['sig'] = getsig(os.path.join(os.getcwd(), apkfile))
-            if not thisinfo['sig']:
+            apk['sig'] = getsig(os.path.join(os.getcwd(), apkfile))
+            if not apk['sig']:
                 logging.critical("Failed to get apk signature")
                 sys.exit(1)
 
-            apk = zipfile.ZipFile(apkfile, 'r')
+            apkzip = zipfile.ZipFile(apkfile, 'r')
 
             # if an APK has files newer than the system time, suggest updating
             # the system clock.  This is useful for offline systems, used for
             # signing, which do not have another source of clock sync info. It
             # has to be more than 24 hours newer because ZIP/APK files do not
             # store timezone info
-            info = apk.getinfo('AndroidManifest.xml')
-            dt_obj = datetime(*info.date_time)
+            manifest = apkzip.getinfo('AndroidManifest.xml')
+            dt_obj = datetime(*manifest.date_time)
             checkdt = dt_obj - timedelta(1)
             if datetime.today() < checkdt:
                 logging.warn('System clock is older than manifest in: '
@@ -560,45 +573,44 @@ def scan_apks(apps, apkcache, repodir, knownapks):
                              + 'sudo date -s "' + str(dt_obj) + '"')
 
             iconfilename = "%s.%s.png" % (
-                thisinfo['id'],
-                thisinfo['versioncode'])
+                apk['id'],
+                apk['versioncode'])
 
             # Extract the icon file...
-            densities = get_densities()
             empty_densities = []
-            for density in densities:
-                if density not in thisinfo['icons_src']:
+            for density in screen_densities:
+                if density not in apk['icons_src']:
                     empty_densities.append(density)
                     continue
-                iconsrc = thisinfo['icons_src'][density]
+                iconsrc = apk['icons_src'][density]
                 icon_dir = get_icon_dir(repodir, density)
                 icondest = os.path.join(icon_dir, iconfilename)
 
                 try:
                     with open(icondest, 'wb') as f:
-                        f.write(apk.read(iconsrc))
-                    thisinfo['icons'][density] = iconfilename
+                        f.write(apkzip.read(iconsrc))
+                    apk['icons'][density] = iconfilename
 
                 except:
                     logging.warn("Error retrieving icon file")
-                    del thisinfo['icons'][density]
-                    del thisinfo['icons_src'][density]
+                    del apk['icons'][density]
+                    del apk['icons_src'][density]
                     empty_densities.append(density)
 
-            if '-1' in thisinfo['icons_src']:
-                iconsrc = thisinfo['icons_src']['-1']
+            if '-1' in apk['icons_src']:
+                iconsrc = apk['icons_src']['-1']
                 iconpath = os.path.join(
-                    get_icon_dir(repodir, None), iconfilename)
+                    get_icon_dir(repodir, '0'), iconfilename)
                 with open(iconpath, 'wb') as f:
-                    f.write(apk.read(iconsrc))
+                    f.write(apkzip.read(iconsrc))
                 try:
                     im = Image.open(iconpath)
                     dpi = px_to_dpi(im.size[0])
-                    for density in densities:
-                        if density in thisinfo['icons']:
+                    for density in screen_densities:
+                        if density in apk['icons']:
                             break
-                        if density == densities[-1] or dpi >= int(density):
-                            thisinfo['icons'][density] = iconfilename
+                        if density == screen_densities[-1] or dpi >= int(density):
+                            apk['icons'][density] = iconfilename
                             shutil.move(iconpath,
                                         os.path.join(get_icon_dir(repodir, density), iconfilename))
                             empty_densities.remove(density)
@@ -606,14 +618,14 @@ def scan_apks(apps, apkcache, repodir, knownapks):
                 except Exception, e:
                     logging.warn("Failed reading {0} - {1}".format(iconpath, e))
 
-            if thisinfo['icons']:
-                thisinfo['icon'] = iconfilename
+            if apk['icons']:
+                apk['icon'] = iconfilename
 
-            apk.close()
+            apkzip.close()
 
             # First try resizing down to not lose quality
             last_density = None
-            for density in densities:
+            for density in screen_densities:
                 if density not in empty_densities:
                     last_density = density
                     continue
@@ -640,7 +652,7 @@ def scan_apks(apps, apkcache, repodir, knownapks):
 
             # Then just copy from the highest resolution available
             last_density = None
-            for density in reversed(densities):
+            for density in reversed(screen_densities):
                 if density not in empty_densities:
                     last_density = density
                     continue
@@ -655,7 +667,7 @@ def scan_apks(apps, apkcache, repodir, knownapks):
 
                 empty_densities.remove(density)
 
-            for density in densities:
+            for density in screen_densities:
                 icon_dir = get_icon_dir(repodir, density)
                 icondest = os.path.join(icon_dir, iconfilename)
                 resize_icon(icondest, density)
@@ -663,18 +675,19 @@ def scan_apks(apps, apkcache, repodir, knownapks):
             # Copy from icons-mdpi to icons since mdpi is the baseline density
             baseline = os.path.join(get_icon_dir(repodir, '160'), iconfilename)
             if os.path.isfile(baseline):
+                apk['icons']['0'] = iconfilename
                 shutil.copyfile(baseline,
-                                os.path.join(get_icon_dir(repodir, None), iconfilename))
+                                os.path.join(get_icon_dir(repodir, '0'), iconfilename))
 
             # Record in known apks, getting the added date at the same time..
-            added = knownapks.recordapk(thisinfo['apkname'], thisinfo['id'])
+            added = knownapks.recordapk(apk['apkname'], apk['id'])
             if added:
-                thisinfo['added'] = added
+                apk['added'] = added
 
-            apkcache[apkfilename] = thisinfo
+            apkcache[apkfilename] = apk
             cachechanged = True
 
-        apks.append(thisinfo)
+        apks.append(apk)
 
     return apks, cachechanged
 
@@ -792,7 +805,7 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
     for appid in sortedids:
         app = apps[appid]
 
-        if app['Disabled'] is not None:
+        if app.Disabled is not None:
             continue
 
         # Get a list of the apks for this app...
@@ -805,57 +818,57 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
             continue
 
         apel = doc.createElement("application")
-        apel.setAttribute("id", app['id'])
+        apel.setAttribute("id", app.id)
         root.appendChild(apel)
 
-        addElement('id', app['id'], doc, apel)
-        if 'added' in app:
-            addElement('added', time.strftime('%Y-%m-%d', app['added']), doc, apel)
-        if 'lastupdated' in app:
-            addElement('lastupdated', time.strftime('%Y-%m-%d', app['lastupdated']), doc, apel)
-        addElement('name', app['Name'], doc, apel)
-        addElement('summary', app['Summary'], doc, apel)
-        if app['icon']:
-            addElement('icon', app['icon'], doc, apel)
+        addElement('id', app.id, doc, apel)
+        if app.added:
+            addElement('added', time.strftime('%Y-%m-%d', app.added), doc, apel)
+        if app.lastupdated:
+            addElement('lastupdated', time.strftime('%Y-%m-%d', app.lastupdated), doc, apel)
+        addElement('name', app.Name, doc, apel)
+        addElement('summary', app.Summary, doc, apel)
+        if app.icon:
+            addElement('icon', app.icon, doc, apel)
 
         def linkres(appid):
             if appid in apps:
-                return ("fdroid.app:" + appid, apps[appid]['Name'])
+                return ("fdroid.app:" + appid, apps[appid].Name)
             raise MetaDataException("Cannot resolve app id " + appid)
 
         addElement('desc',
-                   metadata.description_html(app['Description'], linkres),
+                   metadata.description_html(app.Description, linkres),
                    doc, apel)
-        addElement('license', app['License'], doc, apel)
-        if 'Categories' in app and app['Categories']:
-            addElement('categories', ','.join(app["Categories"]), doc, apel)
+        addElement('license', app.License, doc, apel)
+        if app.Categories:
+            addElement('categories', ','.join(app.Categories), doc, apel)
             # We put the first (primary) category in LAST, which will have
             # the desired effect of making clients that only understand one
             # category see that one.
-            addElement('category', app["Categories"][0], doc, apel)
-        addElement('web', app['Web Site'], doc, apel)
-        addElement('source', app['Source Code'], doc, apel)
-        addElement('tracker', app['Issue Tracker'], doc, apel)
-        addElementNonEmpty('changelog', app['Changelog'], doc, apel)
-        addElementNonEmpty('donate', app['Donate'], doc, apel)
-        addElementNonEmpty('bitcoin', app['Bitcoin'], doc, apel)
-        addElementNonEmpty('litecoin', app['Litecoin'], doc, apel)
-        addElementNonEmpty('flattr', app['FlattrID'], doc, apel)
+            addElement('category', app.Categories[0], doc, apel)
+        addElement('web', app.WebSite, doc, apel)
+        addElement('source', app.SourceCode, doc, apel)
+        addElement('tracker', app.IssueTracker, doc, apel)
+        addElementNonEmpty('changelog', app.Changelog, doc, apel)
+        addElementNonEmpty('donate', app.Donate, doc, apel)
+        addElementNonEmpty('bitcoin', app.Bitcoin, doc, apel)
+        addElementNonEmpty('litecoin', app.Litecoin, doc, apel)
+        addElementNonEmpty('flattr', app.FlattrID, doc, apel)
 
         # These elements actually refer to the current version (i.e. which
         # one is recommended. They are historically mis-named, and need
         # changing, but stay like this for now to support existing clients.
-        addElement('marketversion', app['Current Version'], doc, apel)
-        addElement('marketvercode', app['Current Version Code'], doc, apel)
+        addElement('marketversion', app.CurrentVersion, doc, apel)
+        addElement('marketvercode', app.CurrentVersionCode, doc, apel)
 
-        if app['AntiFeatures']:
-            af = app['AntiFeatures']
+        if app.AntiFeatures:
+            af = app.AntiFeatures
             if af:
                 addElementNonEmpty('antifeatures', ','.join(af), doc, apel)
-        if app['Provides']:
-            pv = app['Provides'].split(',')
+        if app.Provides:
+            pv = app.Provides.split(',')
             addElementNonEmpty('provides', ','.join(pv), doc, apel)
-        if app['Requires Root']:
+        if app.RequiresRoot:
             addElement('requirements', 'root', doc, apel)
 
         # Sort the apk list into version order, just so the web site
@@ -875,7 +888,7 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
             # find the APK for the "Current Version"
             if current_version_code < apk['versioncode']:
                 current_version_code = apk['versioncode']
-            if current_version_code < int(app['Current Version Code']):
+            if current_version_code < int(app.CurrentVersionCode):
                 current_version_file = apk['apkname']
 
             apkel = doc.createElement("package")
@@ -907,11 +920,11 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
         if current_version_file is not None \
                 and config['make_current_version_link'] \
                 and repodir == 'repo':  # only create these
-            sanitized_name = re.sub('''[ '"&%?+=/]''', '',
-                                    app[config['current_version_name_source']])
+            namefield = config['current_version_name_source']
+            sanitized_name = re.sub('''[ '"&%?+=/]''', '', app.get_field(namefield))
             apklinkname = sanitized_name + '.apk'
             current_version_path = os.path.join(repodir, current_version_file)
-            if os.path.exists(apklinkname):
+            if os.path.islink(apklinkname):
                 os.remove(apklinkname)
             os.symlink(current_version_path, apklinkname)
             # also symlink gpg signature, if it exists
@@ -919,7 +932,7 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
                 sigfile_path = current_version_path + extension
                 if os.path.exists(sigfile_path):
                     siglinkname = apklinkname + extension
-                    if os.path.exists(siglinkname):
+                    if os.path.islink(siglinkname):
                         os.remove(siglinkname)
                     os.symlink(sigfile_path, siglinkname)
 
@@ -983,36 +996,62 @@ def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversi
 
     for appid, app in apps.iteritems():
 
-        # Get a list of the apks for this app...
-        apklist = []
-        for apk in apks:
-            if apk['id'] == appid:
-                apklist.append(apk)
-
-        # Sort the apk list into version order...
-        apklist = sorted(apklist, key=lambda apk: apk['versioncode'], reverse=True)
-
-        if app['Archive Policy']:
-            keepversions = int(app['Archive Policy'][:-9])
+        if app.ArchivePolicy:
+            keepversions = int(app.ArchivePolicy[:-9])
         else:
             keepversions = defaultkeepversions
 
-        if len(apklist) > keepversions:
+        def filter_apk_list_sorted(apk_list):
+            res = []
+            for apk in apk_list:
+                if apk['id'] == appid:
+                    res.append(apk)
+
+            # Sort the apk list by version code. First is highest/newest.
+            return sorted(res, key=lambda apk: apk['versioncode'], reverse=True)
+
+        def move_file(from_dir, to_dir, filename, ignore_missing):
+            from_path = os.path.join(from_dir, filename)
+            if ignore_missing and not os.path.exists(from_path):
+                return
+            to_path = os.path.join(to_dir, filename)
+            shutil.move(from_path, to_path)
+
+        if len(apks) > keepversions:
+            apklist = filter_apk_list_sorted(apks)
+            # Move back the ones we don't want.
             for apk in apklist[keepversions:]:
                 logging.info("Moving " + apk['apkname'] + " to archive")
-                shutil.move(os.path.join(repodir, apk['apkname']),
-                            os.path.join(archivedir, apk['apkname']))
+                move_file(repodir, archivedir, apk['apkname'], False)
+                move_file(repodir, archivedir, apk['apkname'] + '.asc', True)
+                for density in all_screen_densities:
+                    repo_icon_dir = get_icon_dir(repodir, density)
+                    archive_icon_dir = get_icon_dir(archivedir, density)
+                    if density not in apk['icons']:
+                        continue
+                    move_file(repo_icon_dir, archive_icon_dir, apk['icons'][density], True)
                 if 'srcname' in apk:
-                    shutil.move(os.path.join(repodir, apk['srcname']),
-                                os.path.join(archivedir, apk['srcname']))
-                    # Move GPG signature too...
-                    sigfile = apk['srcname'] + '.asc'
-                    sigsrc = os.path.join(repodir, sigfile)
-                    if os.path.exists(sigsrc):
-                        shutil.move(sigsrc, os.path.join(archivedir, sigfile))
-
+                    move_file(repodir, archivedir, apk['srcname'], False)
                 archapks.append(apk)
                 apks.remove(apk)
+        elif len(apks) < keepversions and len(archapks) > 0:
+            required = keepversions - len(apks)
+            archapklist = filter_apk_list_sorted(archapks)
+            # Move forward the ones we want again.
+            for apk in archapklist[:required]:
+                logging.info("Moving " + apk['apkname'] + " from archive")
+                move_file(archivedir, repodir, apk['apkname'], False)
+                move_file(archivedir, repodir, apk['apkname'] + '.asc', True)
+                for density in all_screen_densities:
+                    repo_icon_dir = get_icon_dir(repodir, density)
+                    archive_icon_dir = get_icon_dir(archivedir, density)
+                    if density not in apk['icons']:
+                        continue
+                    move_file(archive_icon_dir, repo_icon_dir, apk['icons'][density], True)
+                if 'srcname' in apk:
+                    move_file(archivedir, repodir, apk['srcname'], False)
+                archapks.remove(apk)
+                apks.append(apk)
 
 
 def add_apks_to_per_app_repos(repodir, apks):
@@ -1124,7 +1163,7 @@ def main():
     # Generate a list of categories...
     categories = set()
     for app in apps.itervalues():
-        categories.update(app['Categories'])
+        categories.update(app.Categories)
 
     # Read known apks data (will be updated and written back when we've finished)
     knownapks = common.KnownApks()
@@ -1195,8 +1234,6 @@ def main():
     # same time.
     for appid, app in apps.iteritems():
         bestver = 0
-        added = None
-        lastupdated = None
         for apk in apks + archapks:
             if apk['id'] == appid:
                 if apk['versioncode'] > bestver:
@@ -1204,34 +1241,30 @@ def main():
                     bestapk = apk
 
                 if 'added' in apk:
-                    if not added or apk['added'] < added:
-                        added = apk['added']
-                    if not lastupdated or apk['added'] > lastupdated:
-                        lastupdated = apk['added']
+                    if not app.added or apk['added'] < app.added:
+                        app.added = apk['added']
+                    if not app.lastupdated or apk['added'] > app.lastupdated:
+                        app.lastupdated = apk['added']
 
-        if added:
-            app['added'] = added
-        else:
-            logging.warn("Don't know when " + appid + " was added")
-        if lastupdated:
-            app['lastupdated'] = lastupdated
-        else:
-            logging.warn("Don't know when " + appid + " was last updated")
+        if not app.added:
+            logging.debug("Don't know when " + appid + " was added")
+        if not app.lastupdated:
+            logging.debug("Don't know when " + appid + " was last updated")
 
         if bestver == 0:
-            if app['Name'] is None:
-                app['Name'] = app['Auto Name'] or appid
-            app['icon'] = None
-            logging.warn("Application " + appid + " has no packages")
+            if app.Name is None:
+                app.Name = app.AutoName or appid
+            app.icon = None
+            logging.debug("Application " + appid + " has no packages")
         else:
-            if app['Name'] is None:
-                app['Name'] = bestapk['name']
-            app['icon'] = bestapk['icon'] if 'icon' in bestapk else None
+            if app.Name is None:
+                app.Name = bestapk['name']
+            app.icon = bestapk['icon'] if 'icon' in bestapk else None
 
     # Sort the app list by name, then the web site doesn't have to by default.
     # (we had to wait until we'd scanned the apks to do this, because mostly the
     # name comes from there!)
-    sortedids = sorted(apps.iterkeys(), key=lambda appid: apps[appid]['Name'].upper())
+    sortedids = sorted(apps.iterkeys(), key=lambda appid: apps[appid].Name.upper())
 
     # APKs are placed into multiple repos based on the app package, providing
     # per-app subscription feeds for nightly builds and things like it
@@ -1270,10 +1303,10 @@ def main():
                 appid = line.rstrip()
                 data += appid + "\t"
                 app = apps[appid]
-                data += app['Name'] + "\t"
-                if app['icon'] is not None:
-                    data += app['icon'] + "\t"
-                data += app['License'] + "\n"
+                data += app.Name + "\t"
+                if app.icon is not None:
+                    data += app.icon + "\t"
+                data += app.License + "\n"
             with open(os.path.join(repodirs[0], 'latestapps.dat'), 'w') as f:
                 f.write(data)
 
index 839fc3cba21b7b74ebc8ea3dd80e459c3d867362..0a59f9cc4a3b5448cfb73550dfc2cd8449c682f9 100755 (executable)
@@ -64,9 +64,135 @@ if not os.path.exists(cachedir):
     os.mkdir(cachedir)
 
 cachefiles = [
-    ('android-sdk_r24.3.4-linux.tgz',
-     'https://dl.google.com/android/android-sdk_r24.3.4-linux.tgz',
-     '886412375d8fe6e49a1583e57a8a36a47943666da681701ba9ad1ab7236e83ea'),
+    ('android-sdk_r24.4.1-linux.tgz',
+     'https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz',
+     'e16917ad685c1563ccbc5dd782930ee1a700a1b6a6fd3e44b83ac694650435e9'),
+    ('android-platform-3.zip',
+     'https://dl.google.com/android/repository/android-1.5_r04-linux.zip',
+     '85b6c8f9797e56aa415d3a282428bb640c96b0acb17c11d41621bb2a5302fe64'),
+    ('android-platform-4.zip',
+     'https://dl.google.com/android/repository/android-1.6_r03-linux.zip',
+     'a8c4e3b32269c6b04c2adeabd112fce42f292dab1a40ef3b08ea7d4212be0df4'),
+    ('android-platform-5.zip',
+     'https://dl.google.com/android/repository/android-2.0_r01-linux.zip',
+     'e70e2151b49613f23f40828c771ab85e241eed361cab037c6312df77f2612f0a'),
+    ('android-platform-6.zip',
+     'https://dl.google.com/android/repository/android-2.0.1_r01-linux.zip',
+     'f47b46177b17f6368461f85bc2a27d0d2c437929f588ea27105712bc3185f664'),
+    ('android-platform-7.zip',
+     'https://dl.google.com/android/repository/android-2.1_r03-linux.zip',
+     'b9cc140a9b879586181b22cfc7d4aa18b979251e16e9b17771c5d0acb71ba940'),
+    ('android-platform-8.zip',
+     'https://dl.google.com/android/repository/android-2.2_r03-linux.zip',
+     '7c9ea1bd7cb225504bd085d7c93ae27d52bd88d29b621d28108f82fef68177c0'),
+    ('android-platform-9.zip',
+     'https://dl.google.com/android/repository/android-2.3.1_r02-linux.zip',
+     'b2ab4896d0a4857e4f688f69eb08b0e1a8074709d4445a92a83ece7ec7cd198c'),
+    ('android-platform-10.zip',
+     'https://dl.google.com/android/repository/android-2.3.3_r02-linux.zip',
+     '54bdb0f1ca06ba5747061ddeea20f431af72c448334fd4d3d7f84ea2ccd29fea'),
+    ('android-platform-11.zip',
+     'https://dl.google.com/android/repository/android-3.0_r02-linux.zip',
+     '1cacae7b6e1b5a5d73c06f5d29d2ea92d16674df8fd5507681290e77d1647a1c'),
+    ('android-platform-12.zip',
+     'https://dl.google.com/android/repository/android-3.1_r03-linux.zip',
+     '7570c86a86488a146aa2141a65a24d81800959c1907ff4f1d2c13bbafab230c5'),
+    ('android-platform-13.zip',
+     'https://dl.google.com/android/repository/android-3.2_r01-linux.zip',
+     'ff6b26ad34d7060a72ba504b0314cef8ba3138005561705adec5ad470a073d9b'),
+    ('android-platform-14.zip',
+     'https://dl.google.com/android/repository/android-14_r04.zip',
+     'da1af15c77ba41d062eb6d0ef5921cc424ab6167587033b830609d65f04802b6'),
+    ('android-platform-15.zip',
+     'https://dl.google.com/android/repository/android-15_r05.zip',
+     '5bc1f93aae86b4336ffc4cae9eb8ec41a9a8fd677582dd86a9629798f019bed9'),
+    ('android-platform-16.zip',
+     'https://dl.google.com/android/repository/android-16_r05.zip',
+     'fd7f269a423d1f1d079eabf9f918ceab49108702a1c6bb2589d57c23393503d3'),
+    ('android-platform-17.zip',
+     'https://dl.google.com/android/repository/android-17_r03.zip',
+     'b66e73fb2639f8c916fde4369aa29012a5c531e156dbb205fe3788fe998fbbe8'),
+    ('android-platform-18.zip',
+     'https://dl.google.com/android/repository/android-18_r03.zip',
+     '166ae9cf299747a5faa8f04168f0ee47cd7466a975d8b44acaaa62a43e767568'),
+    ('android-platform-19.zip',
+     'https://dl.google.com/android/repository/android-19_r04.zip',
+     '5efc3a3a682c1d49128daddb6716c433edf16e63349f32959b6207524ac04039'),
+    ('android-platform-20.zip',
+     'https://dl.google.com/android/repository/android-20_r02.zip',
+     'ef08c453e16ab6e656cf5d9413ef61cb8c650607d33b24ee4ce08dafdfe965a7'),
+    ('android-platform-21.zip',
+     'https://dl.google.com/android/repository/android-21_r02.zip',
+     'a76cd7ad3080ac6ce9f037cb935b399a1bad396c0605d4ff42f693695f1dcefe'),
+    ('android-platform-22.zip',
+     'https://dl.google.com/android/repository/android-22_r02.zip',
+     '45eb581bbe53c9256f34c26b2cea919543c0079140897ac721cf88c0b9f6789e'),
+    ('android-platform-23.zip',
+     'https://dl.google.com/android/repository/android-23_r01.zip',
+     '16e828bec35521f5529c998a6d312aaa6155cd4aabb5507d9eb2d4b3c9a1aff0'),
+    ('build-tools-17.0.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r17-linux.zip',
+     '4c8444972343a19045236f6924bd7f12046287c70dace96ab88b2159c8ec0e74'),
+    ('build-tools-18.0.1.zip',
+     'https://dl.google.com/android/repository/build-tools_r18.0.1-linux.zip',
+     'a9b7b1bdfd864780fdd03fa1683f3fe712a4276cf200646833808cb9159bafc0'),
+    ('build-tools-18.1.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r18.1-linux.zip',
+     '0753606738f31cc346426db1d46b7d021bc1bdaff63085f9ee9d278ee054d3c9'),
+    ('build-tools-18.1.1.zip',
+     'https://dl.google.com/android/repository/build-tools_r18.1.1-linux.zip',
+     '7e4ed326b53078f4f23276ddab52c400011f7593dfbb6508c0a6671954dba8b0'),
+    ('build-tools-19.0.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r19-linux.zip',
+     '9442e1c5212ed594e344a231fa93e7a017a5ef8cc661117011f1d3142eca7acc'),
+    ('build-tools-19.0.1.zip',
+     'https://dl.google.com/android/repository/build-tools_r19.0.1-linux.zip',
+     'b068edaff05c3253a63e9c8f0e1786429799b7e4b01514a847a8b291beb9232e'),
+    ('build-tools-19.0.2.zip',
+     'https://dl.google.com/android/repository/build-tools_r19.0.2-linux.zip',
+     '06124fad0d4bde21191240d61df2059a8546c085064a9a57d024c36fa2c9bebb'),
+    ('build-tools-19.0.3.zip',
+     'https://dl.google.com/android/repository/build-tools_r19.0.3-linux.zip',
+     'bc9b3db0de4a3e233a170274293359051a758f1e3f0d0d852ff4ad6d90d0a794'),
+    ('build-tools-19.1.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r19.1-linux.zip',
+     '3833b409f78c002a83244e220be380ea6fa44d604e0d47de4b7e5daefe7cd3f4'),
+    ('build-tools-20.0.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r20-linux.zip',
+     '296e09d62095d80e6eaa06a64cfa4c6f9f317c2d67ad8da6514523ec66f5c871'),
+    ('build-tools-21.0.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r21-linux.zip',
+     '12b818f38fe1b68091b94545988317438efbf41eb61fd36b72cd79f536044065'),
+    ('build-tools-21.0.1.zip',
+     'https://dl.google.com/android/repository/build-tools_r21.0.1-linux.zip',
+     'a8922e80d3dd0cf6df14b29a7862448fa111b48086c639168d4b18c92431f559'),
+    ('build-tools-21.0.2.zip',
+     'https://dl.google.com/android/repository/build-tools_r21.0.2-linux.zip',
+     '859b17a6b65d063dfd86c163489b736b12bdeecd9173fdddb3e9f32e0fe584b7'),
+    ('build-tools-21.1.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r21.1-linux.zip',
+     '022a85b92360272379b2f04b8a4d727e754dbe7eb8ab5a9568190e33e480d8f1'),
+    ('build-tools-21.1.1.zip',
+     'https://dl.google.com/android/repository/build-tools_r21.1.1-linux.zip',
+     '29b612484de6b5cde0df6de655e413f7611b0557b440538397afa69b557e2f08'),
+    ('build-tools-21.1.2.zip',
+     'https://dl.google.com/android/repository/build-tools_r21.1.2-linux.zip',
+     '3f88efc2d5316fb73f547f35b472610eed5e6f3f56762750ddad1c7d1d81660d'),
+    ('build-tools-22.0.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r22-linux.zip',
+     '061c021243f04c80c19568a6e3a027c00d8e269c9311d7bf07fced60fbde7bd5'),
+    ('build-tools-22.0.1.zip',
+     'https://dl.google.com/android/repository/build-tools_r22.0.1-linux.zip',
+     '91e5524bf227aad1135ddd10905518ac49f74797d33d48920dcf8364b9fde214'),
+    ('build-tools-23.0.0.zip',
+     'https://dl.google.com/android/repository/build-tools_r23-linux.zip',
+     '56bf4fc6c43638c55fef4a0937bad38281945725459841879b436c6922df786c'),
+    ('build-tools-23.0.1.zip',
+     'https://dl.google.com/android/repository/build-tools_r23.0.1-linux.zip',
+     'e56b3ef7b760ad06a7cee9b2d52ba7f43133dcecedfa5357f8845b3a80aeeecf'),
+    ('build-tools-23.0.2.zip',
+     'https://dl.google.com/android/repository/build-tools_r23.0.2-linux.zip',
+     '82754f551a6e36eaf516fbdd00c95ff0ccd19f81d1e134125b6ac4916f7ed9b6'),
     ('gradle-1.4-bin.zip',
      'https://services.gradle.org/distributions/gradle-1.4-bin.zip',
      'cd99e85fbcd0ae8b99e81c9992a2f10cceb7b5f009c3720ef3a0078f4f92e94e'),
@@ -109,6 +235,15 @@ cachefiles = [
     ('gradle-2.6-bin.zip',
      'https://services.gradle.org/distributions/gradle-2.6-bin.zip',
      '18a98c560af231dfa0d3f8e0802c20103ae986f12428bb0a6f5396e8f14e9c83'),
+    ('gradle-2.7-bin.zip',
+     'https://services.gradle.org/distributions/gradle-2.7-bin.zip',
+     'cde43b90945b5304c43ee36e58aab4cc6fb3a3d5f9bd9449bb1709a68371cb06'),
+    ('gradle-2.8-bin.zip',
+     'https://services.gradle.org/distributions/gradle-2.8-bin.zip',
+     'a88db9c2f104defdaa8011c58cf6cda6c114298ae3695ecfb8beb30da3a903cb'),
+    ('gradle-2.9-bin.zip',
+     'https://services.gradle.org/distributions/gradle-2.9-bin.zip',
+     'c9159ec4362284c0a38d73237e224deae6139cbde0db4f0f44e1c7691dd3de2f'),
     ('Kivy-1.7.2.tar.gz',
      'https://pypi.python.org/packages/source/K/Kivy/Kivy-1.7.2.tar.gz',
      '0485e2ef97b5086df886eb01f8303cb542183d2d71a159466f99ad6c8a1d03f1'),
@@ -153,7 +288,7 @@ for f, src, shasum in cachefiles:
     relpath = os.path.join(cachedir, f)
     if not os.path.exists(relpath):
         print "Downloading " + f + " to cache"
-        if subprocess.call(['wget', src], cwd=cachedir) != 0:
+        if subprocess.call(['wget', src, '-O', f], cwd=cachedir) != 0:
             print "...download of " + f + " failed."
             sys.exit(1)
     if shasum:
index 6f68f58818f47bc632f821eaa70abf2bea0c34ed..7834799b036ff8ec3f77c0b6bedd6439010ae570 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ else:
     data_prefix = sys.prefix
 
 setup(name='fdroidserver',
-      version='0.4.0',
+      version='0.5.0',
       description='F-Droid Server Tools',
       long_description=open('README.md').read(),
       author='The F-Droid Project',
index 5bb0bd3674ab869aaba7415b5053bfaf774e7148..0665bfffa7f41b3c2de249a7957b5fb74b046586 100755 (executable)
@@ -59,16 +59,14 @@ class BuildTest(unittest.TestCase):
         fdroidserver.build.config['build_tools'] = teststring
         fdroidserver.build.adapt_gradle(testsdir)
         pattern = re.compile("buildToolsVersion[\s=]+'%s'\s+" % teststring)
-        for f in ('source-files/fdroid/fdroidclient/build.gradle',
+        for p in ('source-files/fdroid/fdroidclient/build.gradle',
                   'source-files/Zillode/syncthing-silk/build.gradle',
                   'source-files/open-keychain/open-keychain/build.gradle',
-                  'source-files/osmandapp/osmand/build.gradle'):
-            filedata = open(os.path.join(testsdir, f)).read()
+                  'source-files/osmandapp/osmand/build.gradle',
+                  'source-files/open-keychain/open-keychain/OpenKeychain/build.gradle'):
+            with open(os.path.join(testsdir, p), 'r') as f:
+                filedata = f.read()
             self.assertIsNotNone(pattern.search(filedata))
-        tp = os.path.join(testsdir,
-                          'source-files/open-keychain/open-keychain/OpenKeychain/build.gradle')
-        filedata = open(tp).read()
-        self.assertIsNone(pattern.search(filedata))
 
 if __name__ == "__main__":
     parser = optparse.OptionParser()
index 9f80c1df93af75130dc9e2483db9d455cceecd0f..d34569995509c1024dbfd269a9e3178dbc3dd50b 100755 (executable)
@@ -114,20 +114,19 @@ class CommonTest(unittest.TestCase):
 
         config = dict()
         config['sdk_path'] = os.getenv('ANDROID_HOME')
+        config['ndk_paths'] = {'r10d': os.getenv('ANDROID_NDK_HOME')}
         config['build_tools'] = 'FAKE_BUILD_TOOLS_VERSION'
         fdroidserver.common.config = config
-        app = dict()
-        app['id'] = 'org.fdroid.froid'
-        build = dict(fdroidserver.metadata.flag_defaults)
-        build['commit'] = 'master'
-        build['forceversion'] = True
-        build['forcevercode'] = True
-        build['gradle'] = ['yes']
-        build['ndk_path'] = os.getenv('ANDROID_NDK_HOME')
-        build['target'] = 'android-' + str(testint)
-        build['type'] = 'gradle'
-        build['version'] = teststr
-        build['vercode'] = testint
+        app = fdroidserver.metadata.App()
+        app.id = 'org.fdroid.froid'
+        build = fdroidserver.metadata.Build()
+        build.commit = 'master'
+        build.forceversion = True
+        build.forcevercode = True
+        build.gradle = ['yes']
+        build.target = 'android-' + str(testint)
+        build.version = teststr
+        build.vercode = testint
 
         class FakeVcs():
             # no need to change to the correct commit here
@@ -140,13 +139,15 @@ class CommonTest(unittest.TestCase):
 
         fdroidserver.common.prepare_source(FakeVcs(), app, build, testdir, testdir, testdir)
 
-        filedata = open(os.path.join(testdir, 'build.gradle')).read()
+        with open(os.path.join(testdir, 'build.gradle'), 'r') as f:
+            filedata = f.read()
         self.assertIsNotNone(re.search("\s+compileSdkVersion %s\s+" % testint, filedata))
 
-        filedata = open(os.path.join(testdir, 'AndroidManifest.xml')).read()
+        with open(os.path.join(testdir, 'AndroidManifest.xml')) as f:
+            filedata = f.read()
         self.assertIsNone(re.search('android:debuggable', filedata))
-        self.assertIsNotNone(re.search('android:versionName="%s"' % build['version'], filedata))
-        self.assertIsNotNone(re.search('android:versionCode="%s"' % build['vercode'], filedata))
+        self.assertIsNotNone(re.search('android:versionName="%s"' % build.version, filedata))
+        self.assertIsNotNone(re.search('android:versionCode="%s"' % build.vercode, filedata))
 
 
 if __name__ == "__main__":
index adcbe1a25af3843fc7049aca0b3c2145942383f2..1d00a6885e4c99464f0a1780650eb87179fc5b9e 100755 (executable)
@@ -30,13 +30,12 @@ class ImportTest(unittest.TestCase):
         fdroidserver.common.config['sdk_path'] = '/fake/path/to/android-sdk'
 
         url = 'https://gitlab.com/fdroid/fdroidclient'
-        apps = dict()
-        appid, app = fdroidserver.metadata.get_default_app_info_list(apps)
-        app['Update Check Mode'] = "Tags"
+        app = fdroidserver.metadata.get_default_app_info()
+        app.UpdateCheckMode = "Tags"
         root_dir, src_dir = import_proxy.get_metadata_from_url(app, url)
-        self.assertEquals(app['Repo Type'], 'git')
-        self.assertEquals(app['Web Site'], 'https://gitlab.com/fdroid/fdroidclient')
-        self.assertEquals(app['Repo'], 'https://gitlab.com/fdroid/fdroidclient.git')
+        self.assertEquals(app.RepoType, 'git')
+        self.assertEquals(app.WebSite, 'https://gitlab.com/fdroid/fdroidclient')
+        self.assertEquals(app.Repo, 'https://gitlab.com/fdroid/fdroidclient.git')
 
 
 if __name__ == "__main__":
index 69f4c6ede4bc08b69162183d0c282929f98139d6..c1ffbf363af4c6c264697ec43e82a79e112c1601 100755 (executable)
@@ -39,9 +39,16 @@ class MetadataTest(unittest.TestCase):
 
         apps = fdroidserver.metadata.read_metadata(xref=True)
         for appid in ('org.smssecure.smssecure', 'org.adaway', 'net.osmand.plus', 'org.videolan.vlc'):
-            frompickle = pickle.load(open(os.path.join('metadata', appid + '.pickle')))
-            self.assertTrue(appid in apps.keys())
-            self.assertEquals(apps[appid], frompickle)
+            app = apps[appid]
+            savepath = os.path.join('metadata', appid + '.pickle')
+            frommeta = app.field_dict()
+            self.assertTrue(appid in apps)
+            with open(savepath, 'r') as f:
+                frompickle = pickle.load(f)
+            self.assertEquals(frommeta, frompickle)
+            # Uncomment to overwrite
+            # with open(savepath, 'wb') as f:
+            #     pickle.dump(frommeta, f)
 
 
 if __name__ == "__main__":
index d11ffc8b4fdcfe9ff2b3131a5f29f5c679dda36c..8b82d387fef5a7d07d1eba62a2d323879b03cde7 100644 (file)
@@ -10,493 +10,424 @@ S'Tracking'
 p5
 aS'NonFreeNet'
 p6
-asS'Web Site'
+asS'Litecoin'
 p7
-S'http://osmand.net'
+NsS'comments'
 p8
-sS'Auto Update Mode'
-p9
-S'None'
-p10
+(dp9
 sS'Provides'
-p11
+p10
 NsS'Issue Tracker'
-p12
+p11
 S'https://github.com/osmandapp/Osmand/issues'
-p13
+p12
 sS'Donate'
-p14
+p13
 S'https://code.google.com/p/osmand/#Please_support_the_project'
+p14
+sS'Archive Policy'
 p15
-sS'id'
+NsS'Description'
 p16
-S'net.osmand.plus'
+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"
 p17
-sS'Description'
+sS'Requires Root'
 p18
-(lp19
-S"Osmand~'s features can be extended by enabling the plugins via the settings,"
+I00
+sS'lastupdated'
+p19
+NsS'id'
 p20
-aS'which include online maps from many sources, tracking, OpenStreetMap (OSM) editing and'
+S'net.osmand.plus'
 p21
-aS'accessibility enhancements.'
+sS'Repo'
 p22
-aS''
+S'https://github.com/mvdan/OsmAnd-submodules'
 p23
-aS'Map data of both vector and raster types can be stored on the phone memory'
+sS'No Source Since'
 p24
-aS'card for offline usage, and navigation by default uses offline methods. Map'
+S''
 p25
-aS'data packages for many territories can be downloaded from within the app and'
+sS'Repo Type'
 p26
-aS'there is a desktop program available on the website as well for creating your'
+S'git'
 p27
-aS'own.'
+sS'Auto Name'
 p28
-ag23
-aS'Anti-Features: Tracking - It will send your device and application specs to an'
+g25
+sS'Categories'
 p29
-aS'Analytics server upon downloading the list of maps you can download.'
-p30
-ag23
-aS'[https://osmandapp.github.io/changes.html Changelog]'
+(lp30
+S'None'
 p31
-asS'Requires Root'
+aS'Navigation'
 p32
-I00
-sS'comments'
+asS'Source Code'
 p33
-(lp34
-sS'Repo Type'
+S'https://github.com/osmandapp/Osmand'
+p34
+sS'added'
 p35
-S'git'
+NsS'Update Check Ignore'
 p36
-sS'Repo'
+NsS'Name'
 p37
-S'https://github.com/mvdan/OsmAnd-submodules'
+S'OsmAnd~'
 p38
-sS'No Source Since'
+sS'License'
 p39
-g23
-sS'Auto Name'
+S'GPLv3'
 p40
-g23
-sS'Categories'
+sS'Changelog'
 p41
-(lp42
-S'Navigation'
+g25
+sS'Update Check Mode'
+p42
+S'None'
 p43
-asS'Source Code'
+sS'Summary'
 p44
-S'https://github.com/osmandapp/Osmand'
+S'Offline/online maps and navigation'
 p45
-sS'Litecoin'
+sS'Current Version'
 p46
-NsS'Update Check Ignore'
+S'1.9.5'
 p47
-NsS'Name'
+sS'Maintainer Notes'
 p48
-S'OsmAnd~'
+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  "
 p49
-sS'License'
+sS'Current Version Code'
 p50
-S'GPLv3'
-p51
-sS'Changelog'
-p52
-g23
-sS'Update Check Mode'
-p53
-S'None'
-p54
-sS'Summary'
-p55
-S'Offline/online maps and navigation'
-p56
-sS'Maintainer Notes'
-p57
-(lp58
-S'No UCMs apply because git never contains actual releases, only pre-releses.'
-p59
-ag23
-aS'The build instructions have been moved to a script in the root of the repo,'
-p60
-aS"'build'. This way it can be updated along with the submodules."
-p61
-asS'Current Version Code'
-p62
 S'197'
-p63
+p51
 sS'Binaries'
-p64
-NsS'Archive Policy'
-p65
+p52
 NsS'builds'
-p66
-(lp67
-(dp68
+p53
+(lp54
+(dp55
 S'submodules'
-p69
+p56
 I01
 sS'vercode'
-p70
+p57
 S'182'
-p71
+p58
 sS'forceversion'
-p72
+p59
 I00
 sS'oldsdkloc'
-p73
+p60
 I00
 sS'gradleprops'
-p74
-(lp75
-sS'scanignore'
-p76
-(lp77
+p61
+(lp62
+sS'kivy'
+p63
+I00
 sS'patch'
-p78
-(lp79
+p64
+(lp65
+sS'scanignore'
+p66
+(lp67
 sS'srclibs'
-p80
-(lp81
-sS'output'
-p82
-S'bin/OsmAnd-release-unsigned.apk'
-p83
+p68
+(lp69
 sS'encoding'
-p84
+p70
 NsS'extlibs'
-p85
-(lp86
+p71
+(lp72
 sS'init'
-p87
-g23
+p73
+g25
 sS'version'
-p88
+p74
 S'1.8.2'
-p89
+p75
 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'
-p91
+p77
 sS'rm'
-p92
-(lp93
-sS'kivy'
-p94
-I00
+p78
+(lp79
 sS'subdir'
-p95
+p80
 S'android/OsmAnd'
-p96
+p81
 sS'forcevercode'
-p97
+p82
 I00
 sS'preassemble'
-p98
-(lp99
+p83
+(lp84
 sS'update'
-p100
-(lp101
-S'auto'
-p102
-asS'maven'
-p103
+p85
+(lp86
+sS'maven'
+p87
 I00
 sS'disable'
-p104
+p88
 I00
-sS'ndk_path'
-p105
-g23
+sS'output'
+p89
+S'bin/OsmAnd-release-unsigned.apk'
+p90
 sS'scandelete'
-p106
-(lp107
+p91
+(lp92
 sS'buildjni'
-p108
-(lp109
+p93
 S'no'
-p110
-asS'ndk'
-p111
-S'r10e'
-p112
-sS'target'
-p113
-NsS'type'
-p114
-S'raw'
-p115
-sS'antcommands'
-p116
-NsS'gradle'
-p117
-I00
+p94
+sS'ndk'
+p95
+NsS'target'
+p96
+NsS'antcommands'
+p97
+(lp98
+sS'gradle'
+p99
+(lp100
 sS'prebuild'
-p118
+p101
 S'sed -i \'s/"OsmAnd+"/"OsmAnd~"/g\' build.xml'
-p119
+p102
 sS'novcheck'
-p120
+p103
 I00
 sS'commit'
-p121
+p104
 S'76ada6c8a08afe69acb755503373ac36328ef665'
-p122
-sa(dp123
-S'submodules'
-p124
+p105
+sa(dp106
+g56
 I01
-sg70
+sg57
 S'183'
-p125
-sg72
+p107
+sg59
 I00
-sg73
+sg60
 I00
+sg61
+(lp108
+sg63
+I00
+sg64
+(lp109
+sg66
+(lp110
+sg68
+(lp111
+sg70
+Nsg71
+(lp112
+sg73
+g25
 sg74
-(lp126
+S'1.8.3'
+p113
 sg76
-g77
+S'../../build'
+p114
 sg78
-g79
+(lp115
 sg80
-g81
-sS'output'
-p127
-S'bin/OsmAnd-release-unsigned.apk'
-p128
-sg84
-Nsg85
-g86
-sg87
-g23
-sg88
-S'1.8.3'
-p129
-sS'subdir'
-p130
 S'android/OsmAnd'
-p131
-sg92
-g93
-sg94
-I00
-sS'build'
-p132
-S'../../build'
-p133
-sg97
+p116
+sg82
 I00
-sg98
-g99
-sg100
-g101
-sg103
+sg83
+(lp117
+sg85
+(lp118
+sg87
 I00
-sg104
+sg88
 I00
-sg105
-g23
-sg106
-g107
-sS'buildjni'
-p134
-(lp135
+sg89
+S'bin/OsmAnd-release-unsigned.apk'
+p119
+sg91
+(lp120
+sg93
 S'no'
-p136
-asg111
-g112
-sg113
-Nsg114
-g115
-sg116
-Nsg117
-I00
-sS'prebuild'
-p137
-g23
-sg120
+p121
+sg95
+Nsg96
+Nsg97
+(lp122
+sg99
+(lp123
+sg101
+g25
+sg103
 I00
-sS'commit'
-p138
+sg104
 S'1.8.3'
-p139
-sa(dp140
-S'submodules'
-p141
+p124
+sa(dp125
+g56
 I01
-sg70
+sg57
 S'196'
-p142
-sg72
+p126
+sg59
 I00
-sg73
+sg60
+I00
+sg61
+(lp127
+sg63
 I00
+sg64
+(lp128
+sg66
+(lp129
+sg68
+(lp130
+sg70
+Nsg71
+(lp131
+sg73
+g25
 sg74
-(lp143
+S'1.9.4'
+p132
 sg76
-g77
+S'../../build'
+p133
 sg78
-g79
+(lp134
 sg80
-g81
-sS'output'
-p144
-S'bin/OsmAnd-release-unsigned.apk'
-p145
-sg84
-Nsg85
-g86
-sg87
-g23
-sg88
-S'1.9.4'
-p146
-sS'subdir'
-p147
 S'android/OsmAnd'
-p148
-sg92
-g93
-sg94
+p135
+sg82
 I00
-sS'build'
-p149
-S'../../build'
-p150
-sg97
-I00
-sg98
-g99
-sg100
-g101
-sg103
+sg83
+(lp136
+sg85
+(lp137
+sg87
 I00
-sg104
+sg88
 I00
-sg105
-g23
-sg106
-g107
-sS'buildjni'
-p151
-(lp152
+sg89
+S'bin/OsmAnd-release-unsigned.apk'
+p138
+sg91
+(lp139
+sg93
 S'no'
-p153
-asS'ndk'
-p154
+p140
+sg95
 S'r10d'
-p155
-sg113
-Nsg114
-g115
-sg116
-Nsg117
-I00
-sg137
-g23
-sg120
+p141
+sg96
+Nsg97
+(lp142
+sg99
+(lp143
+sg101
+g25
+sg103
 I00
-sS'commit'
-p156
+sg104
 S'1.9.4'
-p157
-sa(dp158
-S'submodules'
-p159
+p144
+sa(dp145
+g56
 I01
-sg70
+sg57
 S'197'
-p160
-sg72
+p146
+sg59
 I00
-sg73
+sg60
+I00
+sg61
+(lp147
+sg63
 I00
+sg64
+(lp148
+sg66
+(lp149
+sg68
+(lp150
+sg70
+Nsg71
+(lp151
+sg73
+g25
 sg74
-(lp161
+S'1.9.5'
+p152
 sg76
-g77
+S'../../build'
+p153
 sg78
-g79
+(lp154
 sg80
-g81
-sS'output'
-p162
-S'bin/OsmAnd-release-unsigned.apk'
-p163
-sg84
-Nsg85
-g86
-sg87
-g23
-sg88
-S'1.9.5'
-p164
-sS'subdir'
-p165
 S'android/OsmAnd'
-p166
-sg92
-g93
-sg94
-I00
-sS'build'
-p167
-S'../../build'
-p168
-sg97
+p155
+sg82
 I00
-sg98
-g99
-sg100
-g101
-sg103
+sg83
+(lp156
+sg85
+(lp157
+sg87
 I00
-sg104
+sg88
 I00
-sg105
-g23
-sg106
-g107
-sS'buildjni'
-p169
-(lp170
+sg89
+S'bin/OsmAnd-release-unsigned.apk'
+p158
+sg91
+(lp159
+sg93
 S'no'
-p171
-asS'ndk'
-p172
+p160
+sg95
 S'r10d'
-p173
-sg113
-Nsg114
-g115
-sg116
-Nsg117
-I00
-sg137
-g23
-sg120
+p161
+sg96
+Nsg97
+(lp162
+sg99
+(lp163
+sg101
+g25
+sg103
 I00
-sS'commit'
-p174
+sg104
 S'1.9.5'
-p175
+p164
 sasS'FlattrID'
-p176
+p165
 NsS'metadatapath'
-p177
+p166
 S'metadata/net.osmand.plus.xml'
-p178
+p167
 sS'Disabled'
-p179
-NsS'Update Check Name'
-p180
+p168
+NsS'Web Site'
+p169
+S'http://osmand.net'
+p170
+sS'Update Check Name'
+p171
 NsS'Vercode Operation'
-p181
-NsS'Current Version'
-p182
-S'1.9.5'
-p183
+p172
+NsS'Auto Update Mode'
+p173
+S'None'
+p174
 s.
\ No newline at end of file
index 954b21cf3942927602a68d2bf88cd85a25ab2e80..241488a98908fe3a00cffbc1b6b9d915685f2271 100644 (file)
             "versionName": "3.0"
         }
     ],
-    "comments": [
-        ["build:40", "#RootCommands srclib needs changing on fdroidserver"],
-        ["build:42", "#RootCommands srclib needs changing on fdroidserver"]
-    ]
+    "comments": {
+        "build:40": ["#RootCommands srclib needs changing on fdroidserver"],
+        "build:42": ["#RootCommands srclib needs changing on fdroidserver"]
+    }
 }
index d24b410a13bb5943492687266b77fbf570f67308..64403e3a4cfa4ef35c157016d7a04bdee6b5ec02 100644 (file)
@@ -6,2288 +6,1990 @@ p2
 NsS'AntiFeatures'
 p3
 (lp4
-sS'Web Site'
+sS'Litecoin'
 p5
-S'http://sufficientlysecure.org/index.php/adaway'
+NsS'comments'
 p6
-sS'Auto Update Mode'
-p7
-S'Version v%v'
+(dp7
+S'build:42'
 p8
-sS'Provides'
-p9
-S'org.sufficientlysecure.adaway'
+(lp9
+S'#RootCommands srclib needs changing on fdroidserver'
 p10
-sS'Issue Tracker'
+asS'build:40'
 p11
-S'https://github.com/dschuermann/ad-away/issues'
-p12
-sS'Donate'
+(lp12
+S'#RootCommands srclib needs changing on fdroidserver'
 p13
-S'http://sufficientlysecure.org/index.php/adaway'
+assS'Provides'
 p14
-sS'Repo Type'
+S'org.sufficientlysecure.adaway'
 p15
-S'git'
+sS'Issue Tracker'
 p16
-sS'Description'
+S'https://github.com/dschuermann/ad-away/issues'
 p17
-(lp18
-S'An ad blocker that uses the hosts file. The hosts file'
+sS'Donate'
+p18
+S'http://sufficientlysecure.org/index.php/adaway'
 p19
-aS'contains a list of mappings between hostnames and IP addresses. When'
+sS'Archive Policy'
 p20
-aS'an app requests an ad, that request is directed to 127.0.0.1 which does'
+NsS'Description'
 p21
-aS'nothing. There are options to run a web server'
+S'An ad blocker that uses the hosts file. The hosts file\ncontains a list of mappings between hostnames and IP addresses. When\nan app requests an ad, that request is directed to 127.0.0.1 which does\nnothing. There are options to run a web server\nto respond to blocked hostnames and to direct requests to the IP\naddress of your choosing. You can download hosts files from the\napp but it is possible to use your own and to add certain sites\nto the white- and black-lists.\n\n[https://github.com/dschuermann/ad-away/raw/HEAD/CHANGELOG Changelog]\n\nRequires root: Yes. The hosts files is located in /system which is normally\nread-only.'
 p22
-aS'to respond to blocked hostnames and to direct requests to the IP'
+sS'Requires Root'
 p23
-aS'address of your choosing. You can download hosts files from the'
+I01
+sS'lastupdated'
 p24
-aS'app but it is possible to use your own and to add certain sites'
+NsS'id'
 p25
-aS'to the white- and black-lists.'
+S'org.adaway'
 p26
-aS''
+sS'Repo'
 p27
-aS'[https://github.com/dschuermann/ad-away/raw/HEAD/CHANGELOG Changelog]'
+S'https://github.com/dschuermann/ad-away.git'
 p28
-ag27
-aS'Requires root: Yes. The hosts files is located in /system which is normally'
+sS'No Source Since'
 p29
-aS'read-only.'
+S''
 p30
-asS'Requires Root'
+sS'Repo Type'
 p31
-I01
-sS'comments'
+S'git'
 p32
-(lp33
-(lp34
-S'build:40'
-p35
-aS'#RootCommands srclib needs changing on fdroidserver'
-p36
-aa(lp37
-S'build:42'
-p38
-aS'#RootCommands srclib needs changing on fdroidserver'
-p39
-aasS'id'
-p40
-S'org.adaway'
-p41
-sS'Repo'
-p42
-S'https://github.com/dschuermann/ad-away.git'
-p43
-sS'No Source Since'
-p44
-g27
 sS'Auto Name'
-p45
+p33
 S'AdAway'
-p46
+p34
 sS'Categories'
-p47
-(lp48
+p35
+(lp36
 S'System'
-p49
+p37
 aS'Security'
-p50
+p38
 asS'Source Code'
-p51
+p39
 S'https://github.com/dschuermann/ad-away'
-p52
-sS'Litecoin'
-p53
+p40
+sS'added'
+p41
 NsS'Update Check Ignore'
-p54
+p42
 NsS'Name'
-p55
+p43
 NsS'License'
-p56
+p44
 S'GPLv3'
-p57
+p45
 sS'Changelog'
-p58
-g27
+p46
+g30
 sS'Update Check Mode'
-p59
+p47
 S'Tags'
-p60
+p48
 sS'Summary'
-p61
+p49
 S'Block advertisements'
-p62
+p50
+sS'Current Version'
+p51
+S'3.0'
+p52
 sS'Maintainer Notes'
-p63
-(lp64
+p53
+g30
 sS'Current Version Code'
-p65
+p54
 S'52'
-p66
+p55
 sS'Binaries'
-p67
-NsS'Archive Policy'
-p68
+p56
 NsS'builds'
-p69
-(lp70
-(dp71
+p57
+(lp58
+(dp59
 S'submodules'
-p72
+p60
 I00
 sS'vercode'
-p73
+p61
 S'13'
-p74
+p62
 sS'forceversion'
-p75
+p63
 I00
 sS'oldsdkloc'
-p76
+p64
 I00
 sS'gradleprops'
-p77
-(lp78
-sS'scanignore'
-p79
-(lp80
-sS'gradle'
-p81
+p65
+(lp66
+sS'kivy'
+p67
 I00
+sS'patch'
+p68
+(lp69
+sS'scanignore'
+p70
+(lp71
 sS'srclibs'
-p82
-(lp83
+p72
+(lp73
 sS'encoding'
-p84
+p74
 NsS'extlibs'
-p85
-(lp86
+p75
+(lp76
 sS'init'
-p87
-g27
+p77
+g30
 sS'version'
-p88
+p78
 S'1.12'
-p89
+p79
+sS'build'
+p80
+g30
+sS'rm'
+p81
+(lp82
 sS'subdir'
-p90
+p83
 S'org_adaway/'
+p84
+sS'forcevercode'
+p85
+I00
+sS'preassemble'
+p86
+(lp87
+sS'update'
+p88
+(lp89
+sS'maven'
+p90
+I00
+sS'disable'
 p91
-sS'ndk_path'
+I00
+sS'output'
 p92
-g27
-sS'kivy'
+NsS'scandelete'
 p93
-I00
-sS'build'
-p94
-g27
-sS'forcevercode'
+(lp94
+sS'buildjni'
 p95
-I00
-sS'preassemble'
+I01
+sS'ndk'
 p96
-(lp97
-sS'update'
+NsS'target'
+p97
+NsS'antcommands'
 p98
 (lp99
-S'auto'
+sS'gradle'
 p100
-asS'maven'
-p101
-I00
-sS'disable'
+(lp101
+sS'prebuild'
 p102
-I00
-sS'rm'
+g30
+sS'novcheck'
 p103
-(lp104
-sS'scandelete'
-p105
-(lp106
-sS'buildjni'
-p107
-(lp108
-S'yes'
-p109
-asS'ndk'
-p110
-S'r10e'
-p111
-sS'target'
-p112
-NsS'type'
-p113
-S'ant'
-p114
+I00
 sS'commit'
-p115
+p104
 S'ea5378a94ee0dc1d99d2cec95fae7e6d81afb2b9'
-p116
-sS'antcommands'
-p117
-NsS'patch'
-p118
-(lp119
-sS'prebuild'
-p120
-g27
-sS'novcheck'
-p121
-I00
-sS'output'
-p122
-Nsa(dp123
-g72
+p105
+sa(dp106
+g60
 I00
-sg73
+sg61
 S'16'
-p124
-sg75
+p107
+sg63
 I00
-sg76
+sg64
 I00
+sg65
+(lp108
+sg67
+I00
+sg68
+(lp109
+S'defprop.patch'
+p110
+asg70
+(lp111
+sg72
+(lp112
+sg74
+Nsg75
+(lp113
 sg77
-(lp125
-sg79
-g80
+g30
+sg78
+S'1.15'
+p114
+sg80
+g30
 sg81
+(lp115
+sg83
+S'org_adaway/'
+p116
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp117
 sg88
-S'1.15'
-p126
-sS'subdir'
-p127
-S'org_adaway/'
-p128
-sg92
-g27
-sg93
+(lp118
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp119
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp120
+sg100
+(lp121
 sg102
-I00
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p129
-(lp130
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p131
-S'4128e59da2eac5c2904c7c7568d298ca51e79540'
-p132
-sg117
-NsS'patch'
-p133
-(lp134
-S'defprop.patch'
-p135
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp136
-g72
+sg104
+S'4128e59da2eac5c2904c7c7568d298ca51e79540'
+p122
+sa(dp123
+g60
 I00
-sg73
+sg61
 S'19'
-p137
-sg75
+p124
+sg63
+I00
+sg64
 I00
-sg76
+sg65
+(lp125
+sg67
 I00
+sg68
+(lp126
+S'defprop.patch'
+p127
+asg70
+(lp128
+sg72
+(lp129
+sg74
+Nsg75
+(lp130
 sg77
-(lp138
-sg79
-g80
+g30
+sg78
+S'1.18'
+p131
+sg80
+g30
 sg81
+(lp132
+sg83
+S'org_adaway/'
+p133
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp134
 sg88
-S'1.18'
-p139
-sS'subdir'
-p140
-S'org_adaway/'
-p141
-sg92
-g27
-sg93
+(lp135
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp136
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp137
+sg100
+(lp138
 sg102
-I00
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p142
-(lp143
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p144
-S'0b9985398b9eef7baf6aadd0dbb12002bc199d2e'
-p145
-sg117
-NsS'patch'
-p146
-(lp147
-S'defprop.patch'
-p148
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp149
-g72
+sg104
+S'0b9985398b9eef7baf6aadd0dbb12002bc199d2e'
+p139
+sa(dp140
+g60
 I00
-sg73
+sg61
 S'20'
-p150
-sg75
+p141
+sg63
 I00
-sg76
+sg64
 I00
+sg65
+(lp142
+sg67
+I00
+sg68
+(lp143
+S'defprop.patch'
+p144
+asg70
+(lp145
+sg72
+(lp146
+sg74
+Nsg75
+(lp147
 sg77
-(lp151
-sg79
-g80
+g30
+sg78
+S'1.19'
+p148
+sg80
+g30
 sg81
+(lp149
+sg83
+S'org_adaway/'
+p150
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp151
 sg88
-S'1.19'
-p152
-sS'subdir'
-p153
-S'org_adaway/'
-p154
-sg92
-g27
-sg93
+(lp152
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp153
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp154
+sg100
+(lp155
 sg102
-I00
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p155
-(lp156
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p157
-S'ab27f4dab5f3ea5e228cfb4a6b0e1fbf53695f22'
-p158
-sg117
-NsS'patch'
-p159
-(lp160
-S'defprop.patch'
-p161
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp162
-g72
+sg104
+S'ab27f4dab5f3ea5e228cfb4a6b0e1fbf53695f22'
+p156
+sa(dp157
+g60
 I00
-sg73
+sg61
 S'21'
-p163
-sg75
+p158
+sg63
 I00
-sg76
+sg64
 I00
-sg77
-(lp164
-sg79
-g80
-sg81
+sg65
+(lp159
+sg67
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+sg68
+(lp160
+S'defprop.patch'
+p161
+asg70
+(lp162
+sg72
+(lp163
+sg74
+Nsg75
+(lp164
+sg77
+g30
+sg78
 S'1.20'
 p165
-sS'subdir'
-p166
+sg80
+g30
+sg81
+(lp166
+sg83
 S'org_adaway/'
 p167
-sg92
-g27
-sg93
+sg85
 I00
-sg94
-g27
-sg95
+sg86
+(lp168
+sg88
+(lp169
+sg90
 I00
-sg96
-g97
-sg98
-g99
-sg101
+sg91
 I00
+sg92
+Nsg93
+(lp170
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp171
+sg100
+(lp172
 sg102
-I00
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p168
-(lp169
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p170
-S'695e3801e4081026c8f7213a2345fc451d5eb89c'
-p171
-sg117
-NsS'patch'
-p172
-(lp173
-S'defprop.patch'
-p174
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp175
-g72
+sg104
+S'695e3801e4081026c8f7213a2345fc451d5eb89c'
+p173
+sa(dp174
+g60
 I00
-sg73
+sg61
 S'22'
-p176
-sg75
+p175
+sg63
 I00
-sg76
+sg64
 I00
-sg77
+sg65
+(lp176
+sg67
+I00
+sg68
 (lp177
-sg79
-g80
+S'defprop.patch'
+p178
+asg70
+(lp179
+sg72
+(lp180
+sg74
+Nsg75
+(lp181
+sg77
+g30
+sg78
+S'1.21'
+p182
+sg80
+g30
 sg81
+(lp183
+sg83
+S'org_adaway/'
+p184
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp185
 sg88
-S'1.21'
-p178
-sS'subdir'
-p179
-S'org_adaway/'
-p180
-sg92
-g27
-sg93
+(lp186
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp187
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp188
+sg100
+(lp189
 sg102
-I00
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p181
-(lp182
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p183
-S'65138c11cc8b6affd28b68e125fbc1dff0886a4e'
-p184
-sg117
-NsS'patch'
-p185
-(lp186
-S'defprop.patch'
-p187
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp188
-g72
+sg104
+S'65138c11cc8b6affd28b68e125fbc1dff0886a4e'
+p190
+sa(dp191
+g60
 I00
-sg73
+sg61
 S'24'
-p189
-sg75
+p192
+sg63
 I00
-sg76
+sg64
 I00
+sg65
+(lp193
+sg67
+I00
+sg68
+(lp194
+sg70
+(lp195
+sg72
+(lp196
+sg74
+Nsg75
+(lp197
 sg77
-(lp190
-sg79
-g80
+g30
+sg78
+S'1.23'
+p198
+sg80
+g30
 sg81
-I00
-sg82
-g83
-sg84
+(lp199
+sg83
 Nsg85
-g86
-sg87
-g27
+I00
+sg86
+(lp200
 sg88
-S'1.23'
-p191
-sS'subdir'
-p192
-Nsg92
-g27
-sg93
+(lp201
+sg90
 I00
-sg94
-g27
+sg91
+S'no source in repo'
+p202
+sg92
+Nsg93
+(lp203
 sg95
-I00
+(lp204
 sg96
-g97
-sg98
-g99
-sg101
-I00
-sS'disable'
-p193
-S'no source in repo'
-p194
+Nsg97
+Nsg98
+(lp205
+sg100
+(lp206
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p195
-(lp196
-sg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p197
+I00
+sg104
 S'unknown - see disabled'
-p198
-sg117
-Nsg118
-g119
-sg120
-g27
-sg121
-I00
-sg122
-Nsa(dp199
-g72
-I00
-sg73
+p207
+sa(dp208
+g60
+I00
+sg61
 S'25'
-p200
-sg75
+p209
+sg63
+I00
+sg64
 I00
-sg76
+sg65
+(lp210
+sg67
 I00
+sg68
+(lp211
+sg70
+(lp212
+sg72
+(lp213
+sg74
+Nsg75
+(lp214
 sg77
-(lp201
-sg79
-g80
+g30
+sg78
+S'1.24'
+p215
+sg80
+g30
 sg81
+(lp216
+sg83
+S'org_adaway/'
+p217
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp218
 sg88
-S'1.24'
-p202
-sS'subdir'
-p203
-S'org_adaway/'
-p204
-sg92
-g27
-sg93
+(lp219
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp220
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp221
+sg100
+(lp222
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p205
-(lp206
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p207
-S'f811e53e1e1d2ee047b18715fd7d2072b90ae76b'
-p208
-sg117
-Nsg118
-g119
-sS'prebuild'
-p209
 S'android update project -p ../com_actionbarsherlock'
-p210
-sg121
+p223
+sg103
 I00
-sg122
-Nsa(dp211
-g72
+sg104
+S'f811e53e1e1d2ee047b18715fd7d2072b90ae76b'
+p224
+sa(dp225
+g60
 I00
-sg73
+sg61
 S'26'
-p212
-sg75
+p226
+sg63
+I00
+sg64
 I00
-sg76
+sg65
+(lp227
+sg67
 I00
+sg68
+(lp228
+sg70
+(lp229
+sg72
+(lp230
+sg74
+Nsg75
+(lp231
 sg77
-(lp213
-sg79
-g80
+g30
+sg78
+S'1.25'
+p232
+sg80
+g30
 sg81
+(lp233
+sg83
+S'org_adaway/'
+p234
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp235
 sg88
-S'1.25'
-p214
-sS'subdir'
-p215
-S'org_adaway/'
-p216
-sg92
-g27
-sg93
+(lp236
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp237
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp238
+sg100
+(lp239
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p217
-(lp218
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p219
-S'ff97932761cdee68638dc2550751a64b2cbe18e7'
-p220
-sg117
-Nsg118
-g119
-sS'prebuild'
-p221
 S'android update project -p ../com_actionbarsherlock'
-p222
-sg121
+p240
+sg103
 I00
-sg122
-Nsa(dp223
-g72
+sg104
+S'ff97932761cdee68638dc2550751a64b2cbe18e7'
+p241
+sa(dp242
+g60
 I00
-sg73
+sg61
 S'27'
-p224
-sg75
-I00
-sg76
-I00
+p243
+sg63
+I00
+sg64
+I00
+sg65
+(lp244
+sg67
+I00
+sg68
+(lp245
+sg70
+(lp246
+sg72
+(lp247
+sg74
+Nsg75
+(lp248
 sg77
-(lp225
-sg79
-g80
+g30
+sg78
+S'1.26'
+p249
+sg80
+g30
 sg81
+(lp250
+sg83
+S'org_adaway/'
+p251
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp252
 sg88
-S'1.26'
-p226
-sS'subdir'
-p227
-S'org_adaway/'
-p228
-sg92
-g27
-sg93
+(lp253
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp254
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp255
+sg100
+(lp256
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p229
-(lp230
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p231
-S'33d4d80998f30bafc88c04c80cbae00b03916f99'
-p232
-sg117
-Nsg118
-g119
-sS'prebuild'
-p233
 S'android update project -p ../com_actionbarsherlock'
-p234
-sg121
+p257
+sg103
 I00
-sg122
-Nsa(dp235
-g72
+sg104
+S'33d4d80998f30bafc88c04c80cbae00b03916f99'
+p258
+sa(dp259
+g60
 I00
-sg73
+sg61
 S'28'
-p236
-sg75
+p260
+sg63
 I00
-sg76
+sg64
 I00
+sg65
+(lp261
+sg67
+I00
+sg68
+(lp262
+sg70
+(lp263
+sg72
+(lp264
+sg74
+Nsg75
+(lp265
 sg77
-(lp237
-sg79
-g80
+g30
+sg78
+S'1.27'
+p266
+sg80
+g30
 sg81
+(lp267
+sg83
+S'org_adaway/'
+p268
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp269
 sg88
-S'1.27'
-p238
-sS'subdir'
-p239
-S'org_adaway/'
-p240
-sg92
-g27
-sg93
+(lp270
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp271
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp272
+sg100
+(lp273
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p241
-(lp242
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p243
-S'743d25a7e287505461f33f4b8e57e4cf988fffea'
-p244
-sg117
-Nsg118
-g119
-sS'prebuild'
-p245
 S'android update project -p ../com_actionbarsherlock'
-p246
-sg121
+p274
+sg103
 I00
-sg122
-Nsa(dp247
-g72
+sg104
+S'743d25a7e287505461f33f4b8e57e4cf988fffea'
+p275
+sa(dp276
+g60
 I00
-sg73
+sg61
 S'30'
-p248
-sg75
+p277
+sg63
+I00
+sg64
 I00
-sg76
+sg65
+(lp278
+sg67
 I00
+sg68
+(lp279
+sg70
+(lp280
+sg72
+(lp281
+sg74
+Nsg75
+(lp282
 sg77
-(lp249
-sg79
-g80
+g30
+sg78
+S'1.29'
+p283
+sg80
+g30
 sg81
+(lp284
+sg83
+S'org_adaway/'
+p285
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp286
 sg88
-S'1.29'
-p250
-sS'subdir'
-p251
-S'org_adaway/'
-p252
-sg92
-g27
-sg93
+(lp287
+sg90
 I00
-sg94
-g27
-sg95
+sg91
 I00
+sg92
+Nsg93
+(lp288
+sg95
+I01
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp289
+sg100
+(lp290
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p253
-(lp254
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p255
-S'eaa07f4'
-p256
-sg117
-Nsg118
-g119
-sS'prebuild'
-p257
 S'android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/*'
-p258
-sg121
+p291
+sg103
 I00
-sg122
-Nsa(dp259
-g72
+sg104
+S'eaa07f4'
+p292
+sa(dp293
+g60
 I00
-sg73
+sg61
 S'33'
-p260
-sg75
+p294
+sg63
+I00
+sg64
 I00
-sg76
+sg65
+(lp295
+sg67
 I00
+sg68
+(lp296
+sg70
+(lp297
+sg72
+(lp298
+sg74
+Nsg75
+(lp299
 sg77
-(lp261
-sg79
-g80
+g30
+sg78
+S'1.32'
+p300
+sg80
+g30
 sg81
+(lp301
+sg83
+S'org_adaway/'
+p302
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp303
 sg88
-S'1.32'
-p262
-sS'subdir'
-p263
-S'org_adaway/'
-p264
-sg92
-g27
-sg93
+(lp304
+sg90
 I00
-sg94
-g27
+sg91
+I00
+sg92
+Nsg93
+(lp305
 sg95
 I00
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp306
+sg100
+(lp307
 sg102
-I00
+S'android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && rm libs/android-support-v4.jar'
+p308
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p265
-(lp266
-S'no'
-p267
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p268
-S'71ced3f'
-p269
-sg117
-Nsg118
-g119
-sS'prebuild'
-p270
-S'android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && rm libs/android-support-v4.jar'
-p271
-sg121
 I00
-sg122
-Nsa(dp272
-g72
+sg104
+S'71ced3f'
+p309
+sa(dp310
+g60
 I00
-sg73
+sg61
 S'34'
-p273
-sg75
+p311
+sg63
 I00
-sg76
+sg64
 I00
+sg65
+(lp312
+sg67
+I00
+sg68
+(lp313
+sg70
+(lp314
+sg72
+(lp315
+sg74
+Nsg75
+(lp316
 sg77
-(lp274
-sg79
-g80
+g30
+sg78
+S'1.33'
+p317
+sg80
+g30
 sg81
+(lp318
+sg83
+S'org_adaway/'
+p319
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp320
 sg88
-S'1.33'
-p275
-sS'subdir'
-p276
-S'org_adaway/'
-p277
-sg92
-g27
-sg93
+(lp321
+sg90
 I00
-sg94
-g27
+sg91
+I00
+sg92
+Nsg93
+(lp322
 sg95
 I00
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp323
+sg100
+(lp324
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p278
-(lp279
-g267
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p280
-S'9d63c18'
-p281
-sg117
-Nsg118
-g119
-sS'prebuild'
-p282
 S'android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/*'
-p283
-sg121
+p325
+sg103
 I00
-sg122
-Nsa(dp284
-g72
+sg104
+S'9d63c18'
+p326
+sa(dp327
+g60
 I00
-sg73
+sg61
 S'35'
-p285
-sg75
-I00
-sg76
-I00
+p328
+sg63
+I00
+sg64
+I00
+sg65
+(lp329
+sg67
+I00
+sg68
+(lp330
+sg70
+(lp331
+sg72
+(lp332
+sg74
+Nsg75
+(lp333
 sg77
-(lp286
-sg79
-g80
+g30
+sg78
+S'1.34'
+p334
+sg80
+g30
 sg81
+(lp335
+sg83
+S'org_adaway/'
+p336
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp337
 sg88
-S'1.34'
-p287
-sS'subdir'
-p288
-S'org_adaway/'
-p289
-sg92
-g27
-sg93
+(lp338
+sg90
 I00
-sg94
-g27
+sg91
+I00
+sg92
+Nsg93
+(lp339
 sg95
 I00
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp340
+sg100
+(lp341
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p290
-(lp291
-g267
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p292
-S'f2568b1'
-p293
-sg117
-Nsg118
-g119
-sS'prebuild'
-p294
 S'android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && android update project -p ../org_donations'
-p295
-sg121
+p342
+sg103
 I00
-sg122
-Nsa(dp296
-g72
+sg104
+S'f2568b1'
+p343
+sa(dp344
+g60
 I00
-sg73
+sg61
 S'36'
-p297
-sg75
+p345
+sg63
 I00
-sg76
+sg64
 I00
+sg65
+(lp346
+sg67
+I00
+sg68
+(lp347
+sg70
+(lp348
+sg72
+(lp349
+sg74
+Nsg75
+(lp350
 sg77
-(lp298
-sg79
-g80
+g30
+sg78
+S'1.35'
+p351
+sg80
+g30
 sg81
+(lp352
+sg83
+S'org_adaway/'
+p353
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp354
 sg88
-S'1.35'
-p299
-sS'subdir'
-p300
-S'org_adaway/'
-p301
-sg92
-g27
-sg93
+(lp355
+sg90
+I00
+sg91
 I00
-sg94
-g27
+sg92
+Nsg93
+(lp356
 sg95
 I00
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp357
+sg100
+(lp358
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p302
-(lp303
-g267
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p304
-S'7442d5d'
-p305
-sg117
-Nsg118
-g119
-sS'prebuild'
-p306
 S'android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && android update project -p ../org_donations'
-p307
-sg121
+p359
+sg103
 I00
-sg122
-Nsa(dp308
-g72
+sg104
+S'7442d5d'
+p360
+sa(dp361
+g60
 I00
-sg73
+sg61
 S'37'
-p309
-sg75
+p362
+sg63
+I00
+sg64
 I00
-sg76
+sg65
+(lp363
+sg67
 I00
+sg68
+(lp364
+sg70
+(lp365
+sg72
+(lp366
+sg74
+Nsg75
+(lp367
 sg77
-(lp310
-sg79
-g80
+g30
+sg78
+S'1.36'
+p368
+sg80
+g30
 sg81
+(lp369
+sg83
+S'org_adaway/'
+p370
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp371
 sg88
-S'1.36'
-p311
-sS'subdir'
-p312
-S'org_adaway/'
-p313
-sg92
-g27
-sg93
+(lp372
+sg90
 I00
-sg94
-g27
+sg91
+I00
+sg92
+Nsg93
+(lp373
 sg95
 I00
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp374
+sg100
+(lp375
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p314
-(lp315
-g267
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p316
-S'83fc713'
-p317
-sg117
-Nsg118
-g119
-sS'prebuild'
-p318
 S'android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && android update project -p ../org_donations'
-p319
-sg121
+p376
+sg103
 I00
-sg122
-Nsa(dp320
-g72
+sg104
+S'83fc713'
+p377
+sa(dp378
+g60
 I00
-sg73
+sg61
 S'38'
-p321
-sg75
-I00
-sg76
-I00
+p379
+sg63
+I00
+sg64
+I00
+sg65
+(lp380
+sg67
+I00
+sg68
+(lp381
+sg70
+(lp382
+sg72
+(lp383
+sg74
+Nsg75
+(lp384
 sg77
-(lp322
-sg79
-g80
+g30
+sg78
+S'1.37'
+p385
+sg80
+g30
 sg81
+(lp386
+sg83
+S'org_adaway/'
+p387
+sg85
 I00
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
+sg86
+(lp388
 sg88
-S'1.37'
-p323
-sS'subdir'
-p324
-S'org_adaway/'
-p325
-sg92
-g27
-sg93
+(lp389
+sg90
 I00
-sg94
-g27
+sg91
+I00
+sg92
+Nsg93
+(lp390
 sg95
 I00
 sg96
-g97
-sg98
-g99
-sg101
-I00
+Nsg97
+Nsg98
+(lp391
+sg100
+(lp392
 sg102
-I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p326
-(lp327
-g267
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p328
-S'70da32b567122b701cdcb1609b780eb85732028f'
-p329
-sg117
-Nsg118
-g119
-sS'prebuild'
-p330
 S'android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && android update project -p ../org_donations'
-p331
-sg121
+p393
+sg103
 I00
-sg122
-Nsa(dp332
-g72
+sg104
+S'70da32b567122b701cdcb1609b780eb85732028f'
+p394
+sa(dp395
+g60
 I00
-sg73
+sg61
 S'40'
-p333
-sg75
+p396
+sg63
 I00
-sg76
+sg64
 I00
-sg77
-(lp334
-sg79
-g80
-sg81
+sg65
+(lp397
+sg67
 I00
-sS'srclibs'
-p335
-(lp336
+sg68
+(lp398
+sg70
+(lp399
+sg72
+(lp400
 S'RootCommands@c940b0e503'
-p337
-asg84
-NsS'extlibs'
-p338
-(lp339
+p401
+asg74
+Nsg75
+(lp402
 S'htmlcleaner/htmlcleaner-2.2.jar'
-p340
-asS'init'
-p341
+p403
+asg77
 S'rm android-libs/Donations/custom_rules.xml && git clone https://github.com/dschuermann/HtmlSpanner android-libs/HtmlSpanner'
-p342
-sg88
+p404
+sg78
 S'2.1'
-p343
-sS'subdir'
-p344
+p405
+sg80
+g30
+sg81
+(lp406
+sg83
 S'AdAway'
-p345
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p407
+sg85
 I00
-sg96
-g97
-sS'update'
-p346
-(lp347
+sg86
+(lp408
+sg88
+(lp409
 S'.'
-p348
+p410
 aS'android-libs/Donations'
-p349
+p411
 aS'android-libs/ActionBarSherlock'
-p350
+p412
 aS'android-libs/HtmlSpanner/htmlspanner'
-p351
-asg101
+p413
+asg90
 I00
-sg102
+sg91
 I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p352
-(lp353
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p354
-S'v2.1'
-p355
-sg117
-Nsg118
-g119
-sS'prebuild'
-p356
+sg92
+Nsg93
+(lp414
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp415
+sg100
+(lp416
+sg102
 S'rm -rf ../update_zip libs/root-commands-1.2.jar libs/htmlspanner-0.2-fork.jar && cp -f libs/htmlcleaner-2.2.jar android-libs/HtmlSpanner/htmlspanner/libs/ && echo "android.library.reference.3=$$RootCommands$$" >> project.properties && echo "android.library.reference.4=android-libs/HtmlSpanner/htmlspanner" >> project.properties && find . -type f -print0 | xargs -0 sed -i \'s/org.rootcommands/org.sufficientlysecure.rootcommands/g\' && cp android-libs/Donations/ant-templates/other/DonationsConfig.java android-libs/Donations/src/org/donations/'
-p357
-sg121
+p417
+sg103
 I00
-sg122
-Nsa(dp358
-g72
+sg104
+S'v2.1'
+p418
+sa(dp419
+g60
 I00
-sg73
+sg61
 S'42'
-p359
-sg75
+p420
+sg63
 I00
-sg76
+sg64
 I00
-sg77
-(lp360
-sg79
-g80
-sg81
+sg65
+(lp421
+sg67
 I00
-sS'srclibs'
-p361
-(lp362
+sg68
+(lp422
+sg70
+(lp423
+sg72
+(lp424
 S'RootCommands@c940b0e503'
-p363
-asg84
-NsS'extlibs'
-p364
-(lp365
+p425
+asg74
+Nsg75
+(lp426
 S'htmlcleaner/htmlcleaner-2.2.jar'
-p366
-asS'init'
-p367
+p427
+asg77
 S'rm android-libs/Donations/custom_rules.xml && git clone https://github.com/dschuermann/HtmlSpanner android-libs/HtmlSpanner'
-p368
-sg88
+p428
+sg78
 S'2.3'
-p369
-sS'subdir'
-p370
+p429
+sg80
+g30
+sg81
+(lp430
+sg83
 S'AdAway'
-p371
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p431
+sg85
 I00
-sg96
-g97
-sS'update'
-p372
-(lp373
-g348
+sg86
+(lp432
+sg88
+(lp433
+g410
 aS'android-libs/Donations'
-p374
+p434
 aS'android-libs/ActionBarSherlock'
-p375
+p435
 aS'android-libs/HtmlSpanner/htmlspanner'
-p376
-asg101
+p436
+asg90
 I00
-sg102
+sg91
 I00
-sg103
-g104
-sg105
-g106
-sS'buildjni'
-p377
-(lp378
-g109
-asg110
-g111
-sg112
-Nsg113
-g114
-sS'commit'
-p379
-S'v2.3'
-p380
-sg117
-Nsg118
-g119
-sS'prebuild'
-p381
+sg92
+Nsg93
+(lp437
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp438
+sg100
+(lp439
+sg102
 S'rm -rf ../update_zip libs/root-commands-1.2.jar libs/htmlspanner-0.2-fork.jar && cp -f libs/htmlcleaner-2.2.jar android-libs/HtmlSpanner/htmlspanner/libs/ && echo "android.library.reference.3=$$RootCommands$$" >> project.properties && echo "android.library.reference.4=android-libs/HtmlSpanner/htmlspanner" >> project.properties && find . -type f -print0 | xargs -0 sed -i \'s/org.rootcommands/org.sufficientlysecure.rootcommands/g\' && cp android-libs/Donations/ant-templates/other/DonationsConfig.java android-libs/Donations/src/org/donations/'
-p382
-sg121
+p440
+sg103
 I00
-sg122
-Nsa(dp383
-g72
+sg104
+S'v2.3'
+p441
+sa(dp442
+g60
 I00
-sg73
+sg61
 S'45'
-p384
-sg75
+p443
+sg63
+I00
+sg64
 I00
-sg76
+sg65
+(lp444
+sg67
 I00
+sg68
+(lp445
+sg70
+(lp446
+sg72
+(lp447
+sg74
+Nsg75
+(lp448
 sg77
-(lp385
-sg79
-g80
-sg118
-g119
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+g30
+sg78
 S'2.6'
-p386
-sS'subdir'
-p387
+p449
+sg80
+g30
+sg81
+(lp450
+sg83
 S'AdAway'
-p388
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p451
+sg85
 I00
-sS'preassemble'
-p389
-(lp390
+sg86
+(lp452
 S'renameExecutables'
-p391
-asg98
-g99
-sg101
+p453
+asg88
+(lp454
+sg90
 I00
-sg102
+sg91
 I00
+sg92
+Nsg93
+(lp455
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp456
+sg100
+I01
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p392
-(lp393
-g109
-asg110
-g111
-sg112
-Nsg113
-g81
-sS'commit'
-p394
-S'v2.6'
-p395
-sg117
-NsS'gradle'
-p396
-(lp397
-g109
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp398
-g72
+sg104
+S'v2.6'
+p457
+sa(dp458
+g60
 I00
-sg73
+sg61
 S'46'
-p399
-sg75
+p459
+sg63
 I00
-sg76
+sg64
 I00
+sg65
+(lp460
+sg67
+I00
+sg68
+(lp461
+sg70
+(lp462
+sg72
+(lp463
+sg74
+Nsg75
+(lp464
 sg77
-(lp400
-sg79
-g80
-sg118
-g119
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+g30
+sg78
 S'2.7'
-p401
-sS'subdir'
-p402
+p465
+sg80
+g30
+sg81
+(lp466
+sg83
 S'AdAway'
-p403
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p467
+sg85
 I00
-sS'preassemble'
-p404
-(lp405
+sg86
+(lp468
 S'renameExecutables'
-p406
-asg98
-g99
-sg101
+p469
+asg88
+(lp470
+sg90
 I00
-sg102
+sg91
 I00
+sg92
+Nsg93
+(lp471
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp472
+sg100
+I01
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p407
-(lp408
-g109
-asg110
-g111
-sg112
-Nsg113
-g81
-sS'commit'
-p409
-S'v2.7'
-p410
-sg117
-NsS'gradle'
-p411
-(lp412
-g109
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp413
-g72
+sg104
+S'v2.7'
+p473
+sa(dp474
+g60
 I00
-sg73
+sg61
 S'47'
-p414
-sg75
-I00
-sg76
-I00
+p475
+sg63
+I00
+sg64
+I00
+sg65
+(lp476
+sg67
+I00
+sg68
+(lp477
+sg70
+(lp478
+sg72
+(lp479
+sg74
+Nsg75
+(lp480
 sg77
-(lp415
-sg79
-g80
-sg118
-g119
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+g30
+sg78
 S'2.8'
-p416
-sS'subdir'
-p417
+p481
+sg80
+g30
+sg81
+(lp482
+sg83
 S'AdAway'
-p418
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p483
+sg85
 I00
-sS'preassemble'
-p419
-(lp420
+sg86
+(lp484
 S'renameExecutables'
-p421
-asg98
-g99
-sg101
+p485
+asg88
+(lp486
+sg90
 I00
-sg102
+sg91
 I00
+sg92
+Nsg93
+(lp487
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp488
+sg100
+I01
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p422
-(lp423
-g109
-asg110
-g111
-sg112
-Nsg113
-g81
-sS'commit'
-p424
+I00
+sg104
 S'v2.8'
-p425
-sg117
-NsS'gradle'
-p426
-(lp427
-g109
-asg120
-g27
-sg121
-I00
-sg122
-Nsa(dp428
-g72
-I00
-sg73
+p489
+sa(dp490
+g60
+I00
+sg61
 S'48'
-p429
-sg75
+p491
+sg63
 I00
-sg76
+sg64
 I00
+sg65
+(lp492
+sg67
+I00
+sg68
+(lp493
+sg70
+(lp494
+sg72
+(lp495
+sg74
+Nsg75
+(lp496
 sg77
-(lp430
-sg79
-g80
-sg118
-g119
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+g30
+sg78
 S'2.8.1'
-p431
-sS'subdir'
-p432
+p497
+sg80
+g30
+sg81
+(lp498
+sg83
 S'AdAway'
-p433
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p499
+sg85
 I00
-sS'preassemble'
-p434
-(lp435
+sg86
+(lp500
 S'renameExecutables'
-p436
-asg98
-g99
-sg101
+p501
+asg88
+(lp502
+sg90
 I00
-sg102
+sg91
 I00
+sg92
+Nsg93
+(lp503
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp504
+sg100
+I01
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p437
-(lp438
-g109
-asg110
-g111
-sg112
-Nsg113
-g81
-sS'commit'
-p439
-S'v2.8.1'
-p440
-sg117
-NsS'gradle'
-p441
-(lp442
-g109
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp443
-g72
+sg104
+S'v2.8.1'
+p505
+sa(dp506
+g60
 I00
-sg73
+sg61
 S'49'
-p444
-sg75
-I00
-sg76
-I00
+p507
+sg63
+I00
+sg64
+I00
+sg65
+(lp508
+sg67
+I00
+sg68
+(lp509
+sg70
+(lp510
+sg72
+(lp511
+sg74
+Nsg75
+(lp512
 sg77
-(lp445
-sg79
-g80
-sg118
-g119
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+g30
+sg78
 S'2.9'
-p446
-sS'subdir'
-p447
+p513
+sg80
+g30
+sg81
+(lp514
+sg83
 S'AdAway'
-p448
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p515
+sg85
 I00
-sS'preassemble'
-p449
-(lp450
+sg86
+(lp516
 S'renameExecutables'
-p451
-asg98
-g99
-sg101
+p517
+asg88
+(lp518
+sg90
 I00
-sg102
+sg91
 I00
+sg92
+Nsg93
+(lp519
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp520
+sg100
+I01
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p452
-(lp453
-g109
-asg110
-g111
-sg112
-Nsg113
-g81
-sS'commit'
-p454
-S'v2.9'
-p455
-sg117
-NsS'gradle'
-p456
-(lp457
-g109
-asg120
-g27
-sg121
-I00
-sg122
-Nsa(dp458
-g72
-I00
-sg73
-S'50'
-p459
-sg75
 I00
-sg76
+sg104
+S'v2.9'
+p521
+sa(dp522
+g60
 I00
+sg61
+S'50'
+p523
+sg63
+I00
+sg64
+I00
+sg65
+(lp524
+sg67
+I00
+sg68
+(lp525
+sg70
+(lp526
+sg72
+(lp527
+sg74
+Nsg75
+(lp528
 sg77
-(lp460
-sg79
-g80
-sg118
-g119
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+g30
+sg78
 S'2.9.1'
-p461
-sS'subdir'
-p462
+p529
+sg80
+g30
+sg81
+(lp530
+sg83
 S'AdAway'
-p463
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p531
+sg85
 I00
-sS'preassemble'
-p464
-(lp465
+sg86
+(lp532
 S'renameExecutables'
-p466
-asg98
-g99
-sg101
+p533
+asg88
+(lp534
+sg90
 I00
-sg102
+sg91
 I00
+sg92
+Nsg93
+(lp535
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp536
+sg100
+I01
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p467
-(lp468
-g109
-asg110
-g111
-sg112
-Nsg113
-g81
-sS'commit'
-p469
-S'v2.9.1'
-p470
-sg117
-NsS'gradle'
-p471
-(lp472
-g109
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp473
-g72
+sg104
+S'v2.9.1'
+p537
+sa(dp538
+g60
 I00
-sg73
+sg61
 S'51'
-p474
-sg75
-I00
-sg76
-I00
+p539
+sg63
+I00
+sg64
+I00
+sg65
+(lp540
+sg67
+I00
+sg68
+(lp541
+sg70
+(lp542
+sg72
+(lp543
+sg74
+Nsg75
+(lp544
 sg77
-(lp475
-sg79
-g80
-sg118
-g119
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+g30
+sg78
 S'2.9.2'
-p476
-sS'subdir'
-p477
+p545
+sg80
+g30
+sg81
+(lp546
+sg83
 S'AdAway'
-p478
-sg92
-g27
-sg93
+p547
+sg85
 I00
-sg94
-g27
-sg95
-I00
-sS'preassemble'
-p479
-(lp480
+sg86
+(lp548
 S'renameExecutables'
-p481
-asg98
-g99
-sg101
+p549
+asg88
+(lp550
+sg90
 I00
-sg102
+sg91
 I00
+sg92
+Nsg93
+(lp551
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp552
+sg100
+I01
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p482
-(lp483
-g109
-asg110
-g111
-sg112
-Nsg113
-g81
-sS'commit'
-p484
-S'v2.9.2'
-p485
-sg117
-NsS'gradle'
-p486
-(lp487
-g109
-asg120
-g27
-sg121
 I00
-sg122
-Nsa(dp488
-g72
+sg104
+S'v2.9.2'
+p553
+sa(dp554
+g60
 I00
-sg73
+sg61
 S'52'
-p489
-sg75
-I00
-sg76
-I00
+p555
+sg63
+I00
+sg64
+I00
+sg65
+(lp556
+sg67
+I00
+sg68
+(lp557
+sg70
+(lp558
+sg72
+(lp559
+sg74
+Nsg75
+(lp560
 sg77
-(lp490
-sg79
-g80
-sg118
-g119
-sg82
-g83
-sg84
-Nsg85
-g86
-sg87
-g27
-sg88
+g30
+sg78
 S'3.0'
-p491
-sS'subdir'
-p492
+p561
+sg80
+g30
+sg81
+(lp562
+sg83
 S'AdAway'
-p493
-sg92
-g27
-sg93
-I00
-sg94
-g27
-sg95
+p563
+sg85
 I00
-sS'preassemble'
-p494
-(lp495
+sg86
+(lp564
 S'renameExecutables'
-p496
-asg98
-g99
-sg101
+p565
+asg88
+(lp566
+sg90
 I00
-sg102
+sg91
 I00
+sg92
+Nsg93
+(lp567
+sg95
+I01
+sg96
+Nsg97
+Nsg98
+(lp568
+sg100
+I01
+sg102
+g30
 sg103
-g104
-sg105
-g106
-sS'buildjni'
-p497
-(lp498
-g109
-asg110
-g111
-sg112
-Nsg113
-g81
-sS'commit'
-p499
+I00
+sg104
 S'v3.0'
-p500
-sg117
-NsS'gradle'
-p501
-(lp502
-g109
-asg120
-g27
-sg121
-I00
-sg122
-NsasS'FlattrID'
-p503
+p569
+sasS'FlattrID'
+p570
 S'369138'
-p504
+p571
 sS'metadatapath'
-p505
+p572
 S'metadata/org.adaway.json'
-p506
+p573
 sS'Disabled'
-p507
-NsS'Update Check Name'
-p508
+p574
+NsS'Web Site'
+p575
+S'http://sufficientlysecure.org/index.php/adaway'
+p576
+sS'Update Check Name'
+p577
 NsS'Vercode Operation'
-p509
-NsS'Current Version'
-p510
-S'3.0'
-p511
+p578
+NsS'Auto Update Mode'
+p579
+S'Version v%v'
+p580
 s.
\ No newline at end of file
index e181a9e04d0633ef26d52f813fec80593c75279b..f825e4ff446b80be2fd3ffeb014f8912223480df 100644 (file)
@@ -6,770 +6,687 @@ p2
 NsS'AntiFeatures'
 p3
 (lp4
-sS'Web Site'
+sS'Litecoin'
 p5
-S'http://www.smssecure.org'
+NsS'comments'
 p6
-sS'Auto Update Mode'
-p7
-S'Version v%v'
-p8
+(dp7
 sS'Provides'
-p9
+p8
 NsS'Issue Tracker'
-p10
+p9
 S'https://github.com/SMSSecure/SMSSecure/issues'
-p11
+p10
 sS'Donate'
+p11
+NsS'Archive Policy'
 p12
-NsS'Repo Type'
+NsS'Description'
 p13
-S'git'
+S"SMSSecure is an SMS/MMS application that allows you to protect your privacy while communicating with friends.\nUsing SMSSecure, you can send SMS messages and share media or attachments with complete privacy.\n\n* Easy. SMSSecure works like any other SMS application. There's nothing to sign up for and no new service your friends need to join.\n* Reliable. SMSSecure communicates using encrypted SMS messages. No servers or internet connection required.\n* Private. SMSSecure uses the TextSecure encryption protocol to provide privacy for every message, every time.\n* Safe. All messages are encrypted locally, so if your phone is lost or stolen, your messages are protected.\n* Open Source. SMSSecure is Free and Open Source, enabling anyone to verify its security by auditing the code."
 p14
-sS'Description'
+sS'Requires Root'
 p15
-(lp16
-S'SMSSecure is an SMS/MMS application that allows you to protect your privacy while communicating with friends.'
+I00
+sS'lastupdated'
+p16
+NsS'id'
 p17
-aS'Using SMSSecure, you can send SMS messages and share media or attachments with complete privacy.'
+S'org.smssecure.smssecure'
 p18
-aS''
+sS'Repo'
 p19
-aS"* Easy. SMSSecure works like any other SMS application. There's nothing to sign up for and no new service your friends need to join."
+S'https://github.com/SMSSecure/SMSSecure'
 p20
-aS'* Reliable. SMSSecure communicates using encrypted SMS messages. No servers or internet connection required.'
+sS'No Source Since'
 p21
-aS'* Private. SMSSecure uses the TextSecure encryption protocol to provide privacy for every message, every time.'
+S''
 p22
-aS'* Safe. All messages are encrypted locally, so if your phone is lost or stolen, your messages are protected.'
+sS'Repo Type'
 p23
-aS'* Open Source. SMSSecure is Free and Open Source, enabling anyone to verify its security by auditing the code.'
+S'git'
 p24
-asS'Requires Root'
+sS'Auto Name'
 p25
-I00
-sS'comments'
+S'SMSSecure'
 p26
-(lp27
-sS'id'
-p28
-S'org.smssecure.smssecure'
+sS'Categories'
+p27
+(lp28
+S'Phone & SMS'
 p29
-sS'Repo'
+asS'Source Code'
 p30
 S'https://github.com/SMSSecure/SMSSecure'
 p31
-sS'No Source Since'
+sS'added'
 p32
-g19
-sS'Auto Name'
+NsS'Update Check Ignore'
 p33
-S'SMSSecure'
+NsS'Name'
 p34
-sS'Categories'
+NsS'License'
 p35
-(lp36
-S'Phone & SMS'
+S'GPLv3'
+p36
+sS'Changelog'
 p37
-asS'Source Code'
+g22
+sS'Update Check Mode'
 p38
-S'https://github.com/SMSSecure/SMSSecure'
+S'Tags'
 p39
-sS'Litecoin'
+sS'Summary'
 p40
-NsS'Update Check Ignore'
+S'Send encrypted text messages (SMS)'
 p41
-NsS'Name'
+sS'Current Version'
 p42
-NsS'License'
+S'0.6.0'
 p43
-S'GPLv3'
-p44
-sS'Changelog'
-p45
-g19
-sS'Update Check Mode'
-p46
-S'Tags'
-p47
-sS'Summary'
-p48
-S'Send encrypted text messages (SMS)'
-p49
 sS'Maintainer Notes'
-p50
-(lp51
+p44
+g22
 sS'Current Version Code'
-p52
+p45
 S'102'
-p53
+p46
 sS'Binaries'
-p54
-NsS'Archive Policy'
-p55
+p47
 NsS'builds'
-p56
-(lp57
-(dp58
+p48
+(lp49
+(dp50
 S'submodules'
-p59
+p51
 I00
 sS'vercode'
-p60
+p52
 S'5'
-p61
+p53
 sS'forceversion'
-p62
+p54
 I00
 sS'oldsdkloc'
-p63
+p55
+I00
+sS'gradleprops'
+p56
+(lp57
+sS'kivy'
+p58
 I00
-sS'antcommands'
-p64
-NsS'scanignore'
-p65
-(lp66
 sS'patch'
-p67
-(lp68
+p59
+(lp60
+sS'scanignore'
+p61
+(lp62
 sS'srclibs'
-p69
-(lp70
+p63
+(lp64
 S'GradleWitness@10f1269c0aafdc1d478efc005ed48f3a47d44278'
-p71
+p65
 aS'PreferenceFragment@717a45433b927d2f0dfc5328f79e77c9682c37bc'
-p72
+p66
 aS'ShortcutBadger@3815ce2ec0c66acd7d7c0b4f2479df8fa70fed87'
-p73
+p67
 aS'AospMms@android-5.1.0_r3'
-p74
+p68
 asS'encoding'
-p75
+p69
 NsS'extlibs'
-p76
-(lp77
+p70
+(lp71
 sS'init'
-p78
-g19
+p72
+g22
 sS'version'
-p79
+p73
 S'0.3.3'
-p80
+p74
 sS'build'
-p81
-g19
+p75
+g22
 sS'rm'
-p82
-(lp83
+p76
+(lp77
 S'libs/*'
-p84
-asS'kivy'
-p85
-I00
-sS'subdir'
-p86
+p78
+asS'subdir'
+p79
 NsS'forcevercode'
-p87
+p80
 I01
 sS'preassemble'
-p88
-(lp89
+p81
+(lp82
 sS'update'
-p90
-(lp91
-S'auto'
-p92
-asS'maven'
-p93
+p83
+(lp84
+sS'maven'
+p85
 I00
 sS'disable'
-p94
+p86
 S'builds, merge changes into upstream'
-p95
-sS'ndk_path'
-p96
-g19
-sS'scandelete'
-p97
-(lp98
+p87
+sS'output'
+p88
+NsS'scandelete'
+p89
+(lp90
 sS'buildjni'
-p99
-(lp100
+p91
+(lp92
 sS'ndk'
-p101
-S'r10e'
-p102
-sS'target'
-p103
-NsS'type'
-p104
-S'gradle'
-p105
-sS'commit'
-p106
-S'66367479a4f57f347b5cbe8f6f8f632adaae7727'
-p107
-sS'gradleprops'
-p108
-(lp109
+p93
+NsS'target'
+p94
+NsS'antcommands'
+p95
+(lp96
 sS'gradle'
-p110
-(lp111
+p97
+(lp98
 S'yes'
-p112
+p99
 asS'prebuild'
-p113
+p100
 S"touch signing.properties && pushd $$GradleWitness$$ && gradle jar && popd && cp $$GradleWitness$$/build/libs/GradleWitness.jar libs/gradle-witness.jar && sed -i -e '20,22d' build.gradle && pushd $$PreferenceFragment$$ && gradle uploadArchives && popd && sed -i -e '/5470f5872514a6226fa1fc6f4e000991f38805691c534cf0bd2778911fc773ad/d' build.gradle && mkdir smil && pushd smil && wget -c http://www.w3.org/TR/smil-boston-dom/java-binding.zip && unzip java-binding.zip && popd && cp -fR smil/java/org src/ && rm -fR smil && sed -i -e '/org.w3c.smil/d' build.gradle && cp -fR $$AospMms$$/src/org src/"
-p114
+p101
 sS'novcheck'
-p115
+p102
 I00
-sS'output'
-p116
-Nsa(dp117
-S'submodules'
-p118
+sS'commit'
+p103
+S'66367479a4f57f347b5cbe8f6f8f632adaae7727'
+p104
+sa(dp105
+g51
 I01
-sg60
+sg52
 S'6'
-p119
-sg62
+p106
+sg54
 I00
-sg63
+sg55
 I00
-sg64
-Nsg65
-g66
-sg67
-g68
-sS'srclibs'
-p120
-(lp121
+sg56
+(lp107
+sg58
+I00
+sg59
+(lp108
+sg61
+(lp109
+sg63
+(lp110
 S'GradleWitness@10f1269c0aafdc1d478efc005ed48f3a47d44278'
-p122
-asg75
-Nsg76
-g77
-sg78
-g19
-sg79
+p111
+asg69
+Nsg70
+(lp112
+sg72
+g22
+sg73
 S'0.3.3'
-p123
-sg81
-g19
-sS'rm'
-p124
-(lp125
+p113
+sg75
+g22
+sg76
+(lp114
 S'libs/*.jar'
-p126
-asg85
+p115
+asg79
+Nsg80
 I00
-sg86
-NsS'forcevercode'
-p127
+sg81
+(lp116
+sg83
+(lp117
+sg85
 I00
+sg86
+S'builds, wait for upstream'
+p118
 sg88
-g89
-sg90
-g91
+Nsg89
+(lp119
+sg91
+(lp120
 sg93
-I00
-sS'disable'
-p128
-S'builds, wait for upstream'
-p129
-sg96
-g19
+Nsg94
+Nsg95
+(lp121
 sg97
-g98
-sg99
-g100
-sg101
-g102
-sg103
-Nsg104
-g105
-sS'commit'
-p130
-S'9675ce5eecb929dcaddb43b3d9486fdb88b9ae1a'
-p131
-sg108
-(lp132
-sS'gradle'
-p133
-(lp134
-g112
-asS'prebuild'
-p135
+(lp122
+S'yes'
+p123
+asg100
 S'touch signing.properties && pushd $$GradleWitness$$ && gradle jar && popd && cp $$GradleWitness$$/build/libs/GradleWitness.jar libs/gradle-witness.jar'
-p136
-sg115
+p124
+sg102
 I00
-sg116
-Nsa(dp137
-S'submodules'
-p138
+sg103
+S'9675ce5eecb929dcaddb43b3d9486fdb88b9ae1a'
+p125
+sa(dp126
+g51
 I01
-sg60
+sg52
 S'9'
-p139
-sg62
+p127
+sg54
 I00
-sg63
+sg55
 I00
-sg64
-Nsg65
-g66
-sg67
-g68
-sS'srclibs'
-p140
-(lp141
-sg75
-Nsg76
-g77
-sg78
-g19
-sg79
+sg56
+(lp128
+sg58
+I00
+sg59
+(lp129
+sg61
+(lp130
+sg63
+(lp131
+sg69
+Nsg70
+(lp132
+sg72
+g22
+sg73
 S'0.4.2'
-p142
-sg81
-g19
-sS'rm'
-p143
-(lp144
+p133
+sg75
+g22
+sg76
+(lp134
 S'libs/*.jar'
-p145
-asg85
+p135
+asg79
+Nsg80
 I00
-sg86
-Nsg127
+sg81
+(lp136
+sg83
+(lp137
+sg85
 I00
+sg86
+S'builds locally, but not on BS'
+p138
 sg88
-g89
-sg90
-g91
+Nsg89
+(lp139
+sg91
+(lp140
 sg93
-I00
-sS'disable'
-p146
-S'builds locally, but not on BS'
-p147
-sg96
-g19
+Nsg94
+Nsg95
+(lp141
 sg97
-g98
-sg99
-g100
-sg101
-g102
-sg103
-Nsg104
-g105
-sS'commit'
-p148
-S'v0.4.2'
-p149
-sg108
-(lp150
-sS'gradle'
-p151
-(lp152
-g112
-asS'prebuild'
-p153
+(lp142
+S'yes'
+p143
+asg100
 S'touch signing.properties && ./build-witness.sh && rm -rf libs/gradle-witness/build && echo "org.gradle.jvmargs=-Xms512m -Xmx512m -XX:MaxPermSize=512m" >> gradle.properties'
-p154
-sg115
+p144
+sg102
 I00
-sg116
-Nsa(dp155
-S'submodules'
-p156
+sg103
+S'v0.4.2'
+p145
+sa(dp146
+g51
 I01
-sg60
+sg52
 S'11'
-p157
-sg62
+p147
+sg54
 I00
-sg63
+sg55
 I00
-sg64
-Nsg65
-g66
-sg67
-g68
-sg140
-g141
-sg75
-Nsg76
-g77
-sg78
-g19
-sg79
+sg56
+(lp148
+sg58
+I00
+sg59
+(lp149
+sg61
+(lp150
+sg63
+(lp151
+sg69
+Nsg70
+(lp152
+sg72
+g22
+sg73
 S'0.5.1'
-p158
-sg81
-g19
-sS'rm'
-p159
-(lp160
+p153
+sg75
+g22
+sg76
+(lp154
 S'libs/*.jar'
-p161
-asg85
+p155
+asg79
+Nsg80
+I00
+sg81
+(lp156
+sg83
+(lp157
+sg85
 I00
 sg86
-Nsg127
 I00
 sg88
-g89
-sg90
-g91
+Nsg89
+(lp158
+sg91
+(lp159
 sg93
-I00
-sS'disable'
+Nsg94
+Nsg95
+(lp160
+sg97
+(lp161
+S'yes'
 p162
+asg100
+S'touch signing.properties && ./build-witness.sh && rm -rf libs/gradle-witness/build && echo "org.gradle.jvmargs=-Xms512m -Xmx512m -XX:MaxPermSize=512m" >> gradle.properties'
+p163
+sg102
 I00
-sg96
-g19
-sg97
-g98
-sg99
-g100
-sg101
-g102
 sg103
-Nsg104
-g105
-sS'commit'
-p163
 S'v0.5.1'
 p164
-sg108
-(lp165
-sS'gradle'
-p166
-(lp167
-g112
-asS'prebuild'
-p168
-S'touch signing.properties && ./build-witness.sh && rm -rf libs/gradle-witness/build && echo "org.gradle.jvmargs=-Xms512m -Xmx512m -XX:MaxPermSize=512m" >> gradle.properties'
-p169
-sg115
-I00
-sg116
-Nsa(dp170
-S'submodules'
-p171
+sa(dp165
+g51
 I01
-sg60
+sg52
 S'12'
-p172
-sg62
+p166
+sg54
 I00
-sg63
+sg55
 I00
-sg64
-Nsg65
-g66
-sg67
-g68
-sg140
-g141
-sg75
-Nsg76
-g77
-sg78
-g19
-sg79
+sg56
+(lp167
+sg58
+I00
+sg59
+(lp168
+sg61
+(lp169
+sg63
+(lp170
+sg69
+Nsg70
+(lp171
+sg72
+g22
+sg73
 S'0.5.2'
-p173
-sg81
-g19
-sS'rm'
+p172
+sg75
+g22
+sg76
+(lp173
+S'libs/*.jar'
 p174
+asg79
+Nsg80
+I00
+sg81
 (lp175
-S'libs/*.jar'
-p176
-asg85
+sg83
+(lp176
+sg85
 I00
 sg86
-Nsg127
-I00
+S'broken in upstream'
+p177
 sg88
-g89
-sg90
-g91
+Nsg89
+(lp178
+sg91
+(lp179
 sg93
-I00
-sS'disable'
-p177
-S'broken in upstream'
-p178
-sg96
-g19
+Nsg94
+Nsg95
+(lp180
 sg97
-g98
-sg99
-g100
-sg101
-g102
-sg103
-Nsg104
-g105
-sS'commit'
-p179
-S'v0.5.2'
-p180
-sg108
 (lp181
-sS'gradle'
+S'yes'
 p182
-(lp183
-g112
-asS'prebuild'
-p184
+asg100
 S'touch signing.properties && ./scripts/build-witness.sh && rm -rf libs/gradle-witness/build'
-p185
-sg115
+p183
+sg102
 I00
-sg116
-Nsa(dp186
-S'submodules'
-p187
+sg103
+S'v0.5.2'
+p184
+sa(dp185
+g51
 I01
-sg60
+sg52
 S'100'
-p188
-sg62
+p186
+sg54
 I00
-sg63
+sg55
 I00
-sg64
-Nsg65
-g66
-sg67
-g68
-sg140
-g141
-sg75
-Nsg76
-g77
-sg78
-g19
-sg79
-S'0.5.3'
-p189
-sg81
-g19
-sS'rm'
-p190
+sg56
+(lp187
+sg58
+I00
+sg59
+(lp188
+sg61
+(lp189
+sg63
+(lp190
+sg69
+Nsg70
 (lp191
-S'libs/*.jar'
+sg72
+g22
+sg73
+S'0.5.3'
 p192
-asg85
+sg75
+g22
+sg76
+(lp193
+S'libs/*.jar'
+p194
+asg79
+Nsg80
+I00
+sg81
+(lp195
+sg83
+(lp196
+sg85
 I00
 sg86
-Nsg127
 I00
 sg88
-g89
-sg90
-g91
+Nsg89
+(lp197
+sg91
+(lp198
 sg93
-I00
-sg162
-I00
-sg96
-g19
+Nsg94
+Nsg95
+(lp199
 sg97
-g98
-sg99
-g100
-sg101
-g102
-sg103
-Nsg104
-g105
-sS'commit'
-p193
-S'v0.5.3'
-p194
-sg108
-(lp195
-sS'gradle'
-p196
-(lp197
-g112
-asS'prebuild'
-p198
+(lp200
+S'yes'
+p201
+asg100
 S'touch signing.properties && ./scripts/build-witness.sh && rm -rf libs/gradle-witness/build'
-p199
-sg115
+p202
+sg102
 I00
-sg116
-Nsa(dp200
-S'submodules'
-p201
+sg103
+S'v0.5.3'
+p203
+sa(dp204
+g51
 I01
-sg60
+sg52
 S'101'
-p202
-sg62
+p205
+sg54
 I00
-sg63
+sg55
 I00
-sg64
-Nsg65
-g66
-sg67
-g68
-sg140
-g141
-sg75
-Nsg76
-g77
-sg78
-g19
-sg79
+sg56
+(lp206
+sg58
+I00
+sg59
+(lp207
+sg61
+(lp208
+sg63
+(lp209
+sg69
+Nsg70
+(lp210
+sg72
+g22
+sg73
 S'0.5.4'
-p203
-sg81
-g19
-sS'rm'
-p204
-(lp205
+p211
+sg75
+g22
+sg76
+(lp212
 S'libs/*.jar'
-p206
-asg85
+p213
+asg79
+Nsg80
+I00
+sg81
+(lp214
+sg83
+(lp215
+sg85
 I00
 sg86
-Nsg127
 I00
 sg88
-g89
-sg90
-g91
+Nsg89
+(lp216
+sg91
+(lp217
 sg93
-I00
-sg162
-I00
-sg96
-g19
+Nsg94
+Nsg95
+(lp218
 sg97
-g98
-sg99
-g100
-sg101
-g102
-sg103
-Nsg104
-g105
-sS'commit'
-p207
-S'v0.5.4'
-p208
-sg108
-(lp209
-sS'gradle'
-p210
-(lp211
-g112
-asS'prebuild'
-p212
+(lp219
+S'yes'
+p220
+asg100
 S'touch signing.properties && ./scripts/build-witness.sh && rm -rf libs/gradle-witness/build'
-p213
-sg115
+p221
+sg102
 I00
-sg116
-Nsa(dp214
-S'submodules'
-p215
+sg103
+S'v0.5.4'
+p222
+sa(dp223
+g51
 I01
-sg60
+sg52
 S'102'
-p216
-sg62
+p224
+sg54
 I00
-sg63
+sg55
 I00
-sg64
-Nsg65
-g66
-sg67
-g68
-sg140
-g141
-sg75
-Nsg76
-g77
-sg78
-g19
-sg79
+sg56
+(lp225
+sg58
+I00
+sg59
+(lp226
+sg61
+(lp227
+sg63
+(lp228
+sg69
+Nsg70
+(lp229
+sg72
+g22
+sg73
 S'0.6.0'
-p217
-sg81
-g19
-sS'rm'
-p218
-(lp219
+p230
+sg75
+g22
+sg76
+(lp231
 S'libs/*.jar'
-p220
-asg85
+p232
+asg79
+Nsg80
+I00
+sg81
+(lp233
+sg83
+(lp234
+sg85
 I00
 sg86
-Nsg127
 I00
 sg88
-g89
-sg90
-g91
+Nsg89
+(lp235
+sg91
+(lp236
 sg93
-I00
-sg162
-I00
-sg96
-g19
+Nsg94
+Nsg95
+(lp237
 sg97
-g98
-sg99
-g100
-sg101
-g102
-sg103
-Nsg104
-g105
-sS'commit'
-p221
-S'v0.6.0'
-p222
-sg108
-(lp223
-sS'gradle'
-p224
-(lp225
-g112
-asS'prebuild'
-p226
+(lp238
+S'yes'
+p239
+asg100
 S'touch signing.properties && ./scripts/build-witness.sh && rm -rf libs/gradle-witness/build'
-p227
-sg115
+p240
+sg102
 I00
-sg116
-NsasS'FlattrID'
-p228
+sg103
+S'v0.6.0'
+p241
+sasS'FlattrID'
+p242
 NsS'metadatapath'
-p229
+p243
 S'metadata/org.smssecure.smssecure.txt'
-p230
+p244
 sS'Disabled'
-p231
-NsS'Update Check Name'
-p232
+p245
+NsS'Web Site'
+p246
+S'http://www.smssecure.org'
+p247
+sS'Update Check Name'
+p248
 NsS'Vercode Operation'
-p233
-NsS'Current Version'
-p234
-S'0.6.0'
-p235
+p249
+NsS'Auto Update Mode'
+p250
+S'Version v%v'
+p251
 s.
\ No newline at end of file
index bc508ba386db9f238921574db26c1b8b68004c5b..4b06e9d8bca00f76ea98d72503ff211923beaa3c 100644 (file)
@@ -6,5618 +6,4630 @@ p2
 NsS'AntiFeatures'
 p3
 (lp4
-sS'Web Site'
+sS'Litecoin'
 p5
-S'http://www.videolan.org/vlc/download-android.html'
+NsS'comments'
 p6
-sS'Auto Update Mode'
-p7
-S'None'
-p8
+(dp7
 sS'Provides'
-p9
+p8
 NsS'Issue Tracker'
-p10
+p9
 S'http://www.videolan.org/support/index.html#bugs'
-p11
+p10
 sS'Donate'
-p12
+p11
 S'http://www.videolan.org/contribute.html#money'
+p12
+sS'Archive Policy'
 p13
-sS'id'
+S'9 versions'
 p14
-S'org.videolan.vlc'
-p15
 sS'Description'
+p15
+S'Video and audio player that supports a wide range of formats,\nfor both local and remote playback.\n\n[http://git.videolan.org/?p=vlc-ports/android.git;a=blob_plain;f=NEWS NEWS]\n'
 p16
-(lp17
-S'Video and audio player that supports a wide range of formats,'
+sS'Requires Root'
+p17
+I00
+sS'lastupdated'
 p18
-aS'for both local and remote playback.'
+NsS'id'
 p19
-aS''
+S'org.videolan.vlc'
 p20
-aS'[http://git.videolan.org/?p=vlc-ports/android.git;a=blob_plain;f=NEWS NEWS]'
+sS'Repo'
 p21
-asS'Requires Root'
+S'git://git.videolan.org/vlc-ports/android.git'
 p22
-I00
-sS'comments'
+sS'No Source Since'
 p23
-(lp24
+S''
+p24
 sS'Repo Type'
 p25
 S'git'
 p26
-sS'Repo'
+sS'Auto Name'
 p27
-S'git://git.videolan.org/vlc-ports/android.git'
+S'VLC'
 p28
-sS'No Source Since'
+sS'Categories'
 p29
-g20
-sS'Auto Name'
-p30
-S'VLC'
+(lp30
+S'Multimedia'
 p31
-sS'Categories'
+asS'Source Code'
 p32
-(lp33
-S'Multimedia'
+S'http://git.videolan.org/?p=vlc-ports/android.git;a=summary'
+p33
+sS'added'
 p34
-asS'Source Code'
+NsS'Update Check Ignore'
 p35
-S'http://git.videolan.org/?p=vlc-ports/android.git;a=summary'
+NsS'Name'
 p36
-sS'Litecoin'
+NsS'License'
 p37
-NsS'Update Check Ignore'
+S'GPLv3'
 p38
-NsS'Name'
+sS'Changelog'
 p39
-NsS'License'
+g24
+sS'Update Check Mode'
 p40
-S'GPLv3'
+S'Tags'
 p41
-sS'Changelog'
+sS'Summary'
 p42
-g20
-sS'Update Check Mode'
+S'Media player'
 p43
-S'Tags'
+sS'Current Version'
 p44
-sS'Summary'
+S'1.2.6'
 p45
-S'Media player'
-p46
 sS'Maintainer Notes'
+p46
+S"Instructions and dependencies here: http://wiki.videolan.org/AndroidCompile\nsee http://buildbot.videolan.org/builders/ for version code scheme\nThe VLC srclib commit can be found out from TESTED_HASH value in compile.sh\n\nOn new releases remove the updatecheck and force the CV to the last working\nbuild. This will make sure users don't get notified about the update until\nthe final build from the BS has been reviewed and tested. Once done, undo\nthose changes.\n"
 p47
-(lp48
-S'Instructions and dependencies here: http://wiki.videolan.org/AndroidCompile'
+sS'Current Version Code'
+p48
+S'1030005'
 p49
-aS'see http://buildbot.videolan.org/builders/ for version code scheme'
+sS'Binaries'
 p50
-aS'The VLC srclib commit can be found out from TESTED_HASH value in compile.sh'
+NsS'builds'
 p51
-ag20
-aS'On new releases remove the updatecheck and force the CV to the last working'
-p52
-aS"build. This will make sure users don't get notified about the update until"
-p53
-aS'the final build from the BS has been reviewed and tested. Once done, undo'
-p54
-aS'those changes.'
-p55
-asS'Current Version Code'
-p56
-S'1030005'
-p57
-sS'Binaries'
-p58
-NsS'Archive Policy'
-p59
-S'9 versions'
-p60
-sS'builds'
-p61
-(lp62
-(dp63
+(lp52
+(dp53
 S'submodules'
-p64
+p54
 I00
 sS'vercode'
-p65
+p55
 S'110'
-p66
+p56
 sS'forceversion'
-p67
+p57
 I01
 sS'oldsdkloc'
-p68
+p58
 I00
 sS'gradleprops'
-p69
-(lp70
-sS'scanignore'
-p71
-(lp72
+p59
+(lp60
+sS'kivy'
+p61
+I00
 sS'patch'
-p73
-(lp74
+p62
+(lp63
+sS'scanignore'
+p64
+(lp65
 sS'srclibs'
-p75
-(lp76
-sS'output'
-p77
-NsS'encoding'
-p78
+p66
+(lp67
+sS'encoding'
+p68
 NsS'extlibs'
-p79
-(lp80
+p69
+(lp70
 sS'init'
-p81
-g20
+p71
+g24
 sS'version'
-p82
+p72
 S'0.0.11-ARMv7'
-p83
+p73
 sS'build'
-p84
+p74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p85
+p75
 sS'rm'
-p86
-(lp87
-sS'kivy'
-p88
-I00
+p76
+(lp77
 sS'subdir'
-p89
+p78
 S'vlc-android'
-p90
+p79
 sS'forcevercode'
-p91
+p80
 I01
 sS'preassemble'
-p92
-(lp93
+p81
+(lp82
 sS'update'
-p94
-(lp95
+p83
+(lp84
 S'.'
-p96
+p85
 aS'../java-libs/SlidingMenu'
-p97
+p86
 aS'../java-libs/ActionBarSherlock'
-p98
+p87
 asS'maven'
-p99
+p88
 I00
 sS'disable'
-p100
+p89
 I00
-sS'ndk_path'
-p101
-g20
-sS'scandelete'
-p102
-(lp103
+sS'output'
+p90
+NsS'scandelete'
+p91
+(lp92
 sS'buildjni'
-p104
-(lp105
-S'no'
-p106
-asS'ndk'
-p107
-S'r10e'
-p108
-sS'target'
-p109
-NsS'type'
-p110
-S'ant'
-p111
-sS'antcommands'
-p112
-NsS'gradle'
-p113
+p93
 I00
+sS'ndk'
+p94
+NsS'target'
+p95
+NsS'antcommands'
+p96
+(lp97
+sS'gradle'
+p98
+(lp99
 sS'prebuild'
-p114
+p100
 S"sed -i '48d' ../Makefile"
-p115
+p101
 sS'novcheck'
-p116
+p102
 I00
 sS'commit'
-p117
+p103
 S'0.0.11'
-p118
-sa(dp119
-g64
+p104
+sa(dp105
+g54
 I00
-sg65
+sg55
 S'111'
-p120
-sS'forceversion'
-p121
+p106
+sg57
 I01
+sg58
+I00
+sg59
+(lp107
+sg61
+I00
+sg62
+(lp108
+sg64
+(lp109
+sg66
+(lp110
 sg68
-I00
-sg69
-(lp122
+Nsg69
+(lp111
 sg71
-g72
-sg73
-g74
-sg75
-g76
-sg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+g24
+sg72
 S'0.0.11-ARM'
-p123
-sS'build'
-p124
+p112
+sg74
 S'cd ../ && ANDROID_ABI=armeabi ./compile.sh release'
-p125
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p126
+p113
+sg76
+(lp114
+sg78
 S'vlc-android'
-p127
-sS'forcevercode'
-p128
+p115
+sg80
 I01
-sg92
-g93
-sS'update'
-p129
-(lp130
-g96
+sg81
+(lp116
+sg83
+(lp117
+S'.'
+p118
 aS'../java-libs/SlidingMenu'
-p131
+p119
 aS'../java-libs/ActionBarSherlock'
-p132
-asg99
+p120
+asg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p133
-(lp134
-S'no'
-p135
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp121
+sg93
 I00
-sS'prebuild'
-p136
+sg94
+Nsg95
+Nsg96
+(lp122
+sg98
+(lp123
+sg100
 S"sed -i '48d' ../Makefile"
-p137
-sg116
+p124
+sg102
 I00
-sS'commit'
-p138
+sg103
 S'0.0.11'
-p139
-sa(dp140
-g64
+p125
+sa(dp126
+g54
 I00
-sg65
+sg55
 S'112'
-p141
-sS'forceversion'
-p142
+p127
+sg57
 I01
-sg68
+sg58
 I00
-sg69
-(lp143
+sg59
+(lp128
+sg61
+I00
+sg62
+(lp129
+sg64
+(lp130
+sg66
+(lp131
+sg68
+Nsg69
+(lp132
 sg71
-g72
-sg73
-g74
-sg75
-g76
-sg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+g24
+sg72
 S'0.0.11-x86'
-p144
-sS'build'
-p145
+p133
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p146
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p147
+p134
+sg76
+(lp135
+sg78
 S'vlc-android'
-p148
-sS'forcevercode'
-p149
+p136
+sg80
 I01
-sg92
-g93
-sS'update'
-p150
-(lp151
-g96
+sg81
+(lp137
+sg83
+(lp138
+S'.'
+p139
 aS'../java-libs/SlidingMenu'
-p152
+p140
 aS'../java-libs/ActionBarSherlock'
-p153
-asg99
+p141
+asg88
 I00
-sS'disable'
-p154
+sg89
 S'ffmpeg error 0.0.11'
-p155
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p156
-(lp157
-S'no'
-p158
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
-I00
-sS'prebuild'
-p159
+p142
+sg90
+Nsg91
+(lp143
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp144
+sg98
+(lp145
+sg100
 S"sed -i '48d' ../Makefile"
-p160
-sg116
+p146
+sg102
 I00
-sS'commit'
-p161
+sg103
 S'unknown - see disabled'
-p162
-sa(dp163
-g64
+p147
+sa(dp148
+g54
 I00
-sg65
+sg55
 S'113'
-p164
-sS'forceversion'
-p165
+p149
+sg57
 I01
-sg68
+sg58
 I00
-sg69
-(lp166
+sg59
+(lp150
+sg61
+I00
+sg62
+(lp151
+sg64
+(lp152
+sg66
+(lp153
+sg68
+Nsg69
+(lp154
 sg71
-g72
-sg73
-g74
-sg75
-g76
-sg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+g24
+sg72
 S'0.0.11-mips'
-p167
-sS'build'
-p168
+p155
+sg74
 S'cd ../ && ANDROID_ABI=mips ./compile.sh release'
-p169
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p170
+p156
+sg76
+(lp157
+sg78
 S'vlc-android'
-p171
-sS'forcevercode'
-p172
+p158
+sg80
 I01
-sg92
-g93
-sS'update'
-p173
-(lp174
-g96
+sg81
+(lp159
+sg83
+(lp160
+S'.'
+p161
 aS'../java-libs/SlidingMenu'
-p175
+p162
 aS'../java-libs/ActionBarSherlock'
-p176
-asg99
+p163
+asg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p177
-(lp178
-S'no'
-p179
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp164
+sg93
 I00
-sS'prebuild'
-p180
+sg94
+Nsg95
+Nsg96
+(lp165
+sg98
+(lp166
+sg100
 S"sed -i '48d' ../Makefile"
-p181
-sg116
+p167
+sg102
 I00
-sS'commit'
-p182
+sg103
 S'0.0.11'
-p183
-sa(dp184
-g64
+p168
+sa(dp169
+g54
 I00
-sg65
+sg55
 S'1301'
-p185
-sS'forceversion'
-p186
+p170
+sg57
 I01
-sg68
+sg58
 I00
-sg69
-(lp187
-sg71
-g72
-sS'patch'
-p188
-(lp189
+sg59
+(lp171
+sg61
+I00
+sg62
 S'ndkr9.patch'
-p190
-asS'srclibs'
-p191
-(lp192
+p172
+sg64
+(lp173
+sg66
 S'VLC@7c52aacbe'
-p193
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p174
+sg68
+Nsg69
+(lp175
+sg71
+g24
+sg72
 S'0.1.3-MIPS'
-p194
-sS'build'
-p195
+p176
+sg74
 S'cd ../ && ANDROID_ABI=mips ./compile.sh release'
-p196
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p197
+p177
+sg76
+(lp178
+sg78
 S'vlc-android'
-p198
-sS'forcevercode'
-p199
+p179
+sg80
 I01
-sg92
-g93
-sS'update'
-p200
-(lp201
-S'auto'
-p202
-asg99
+sg81
+(lp180
+sg83
+(lp181
+sg88
 I00
-sS'disable'
-p203
+sg89
 S'build failing (at 0.1.3)'
-p204
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p205
-(lp206
-S'no'
-p207
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
-I00
-sS'prebuild'
-p208
+p182
+sg90
+Nsg91
+(lp183
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp184
+sg98
+(lp185
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p209
-sg116
+p186
+sg102
 I00
-sS'commit'
-p210
+sg103
 S'0.1.3'
-p211
-sa(dp212
-g64
+p187
+sa(dp188
+g54
 I00
-sg65
+sg55
 S'1302'
-p213
-sS'forceversion'
-p214
+p189
+sg57
 I01
-sg68
+sg58
 I00
-sg69
-(lp215
-sg71
-g72
-sS'patch'
-p216
-(lp217
+sg59
+(lp190
+sg61
+I00
+sg62
 S'ndkr9.patch'
-p218
-asS'srclibs'
-p219
-(lp220
+p191
+sg64
+(lp192
+sg66
 S'VLC@7c52aacbe'
-p221
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p193
+sg68
+Nsg69
+(lp194
+sg71
+g24
+sg72
 S'0.1.3-x86'
-p222
-sS'build'
-p223
+p195
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p224
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p225
+p196
+sg76
+(lp197
+sg78
 S'vlc-android'
-p226
-sS'forcevercode'
-p227
+p198
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
-I00
-sg100
+sg81
+(lp199
+sg83
+(lp200
+sg88
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p228
-(lp229
-S'no'
-p230
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg89
 I00
-sS'prebuild'
-p231
+sg90
+Nsg91
+(lp201
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp202
+sg98
+(lp203
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p232
-sg116
+p204
+sg102
 I00
-sS'commit'
-p233
+sg103
 S'0.1.3'
-p234
-sa(dp235
-g64
+p205
+sa(dp206
+g54
 I00
-sg65
+sg55
 S'1303'
-p236
-sS'forceversion'
-p237
+p207
+sg57
 I01
-sg68
+sg58
 I00
-sg69
-(lp238
-sg71
-g72
-sS'patch'
-p239
-(lp240
+sg59
+(lp208
+sg61
+I00
+sg62
 S'ndkr9.patch'
-p241
-asS'srclibs'
-p242
-(lp243
+p209
+sg64
+(lp210
+sg66
 S'VLC@7c52aacbe'
-p244
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p211
+sg68
+Nsg69
+(lp212
+sg71
+g24
+sg72
 S'0.1.3-ARM'
-p245
-sS'build'
-p246
+p213
+sg74
 S'cd ../ && ANDROID_ABI=armeabi ./compile.sh release'
-p247
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p248
+p214
+sg76
+(lp215
+sg78
 S'vlc-android'
-p249
-sS'forcevercode'
-p250
+p216
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp217
+sg83
+(lp218
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p251
-(lp252
-S'no'
-p253
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp219
+sg93
 I00
-sS'prebuild'
-p254
+sg94
+Nsg95
+Nsg96
+(lp220
+sg98
+(lp221
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p255
-sg116
+p222
+sg102
 I00
-sS'commit'
-p256
+sg103
 S'0.1.3'
-p257
-sa(dp258
-g64
+p223
+sa(dp224
+g54
 I00
-sg65
+sg55
 S'1304'
-p259
-sS'forceversion'
-p260
+p225
+sg57
 I01
-sg68
+sg58
 I00
-sg69
-(lp261
-sg71
-g72
-sS'patch'
-p262
-(lp263
+sg59
+(lp226
+sg61
+I00
+sg62
 S'ndkr9.patch'
-p264
-asS'srclibs'
-p265
-(lp266
+p227
+sg64
+(lp228
+sg66
 S'VLC@7c52aacbe'
-p267
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p229
+sg68
+Nsg69
+(lp230
+sg71
+g24
+sg72
 S'0.1.3-ARMv7'
-p268
-sS'build'
-p269
+p231
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p270
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p271
+p232
+sg76
+(lp233
+sg78
 S'vlc-android'
-p272
-sS'forcevercode'
-p273
+p234
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp235
+sg83
+(lp236
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p274
-(lp275
-S'no'
-p276
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp237
+sg93
 I00
-sS'prebuild'
-p277
+sg94
+Nsg95
+Nsg96
+(lp238
+sg98
+(lp239
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p278
-sg116
+p240
+sg102
 I00
-sS'commit'
-p279
+sg103
 S'0.1.3'
-p280
-sa(dp281
-g64
+p241
+sa(dp242
+g54
 I00
-sg65
+sg55
 S'9002'
-p282
-sS'forceversion'
-p283
+p243
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp284
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p285
-(lp286
+sg59
+(lp244
+sg61
+I00
+sg62
+(lp245
+sg64
+(lp246
+sg66
 S'VLC@31ffb20309264994'
-p287
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p247
+sg68
+Nsg69
+(lp248
+sg71
+g24
+sg72
 S'0.9.0'
-p288
-sS'build'
-p289
+p249
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p290
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p291
+p250
+sg76
+(lp251
+sg78
 S'vlc-android'
-p292
-sS'forcevercode'
-p293
+p252
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp253
+sg83
+(lp254
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p294
-(lp295
-S'no'
-p296
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp255
+sg93
 I00
-sS'prebuild'
-p297
+sg94
+Nsg95
+Nsg96
+(lp256
+sg98
+(lp257
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p298
-sg116
+p258
+sg102
 I00
-sS'commit'
-p299
+sg103
 S'0.9.0'
-p300
-sa(dp301
-g64
+p259
+sa(dp260
+g54
 I00
-sg65
+sg55
 S'9004'
-p302
-sg283
+p261
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp303
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p304
-(lp305
+sg59
+(lp262
+sg61
+I00
+sg62
+(lp263
+sg64
+(lp264
+sg66
 S'VLC@31ffb20309264994'
-p306
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p265
+sg68
+Nsg69
+(lp266
+sg71
+g24
+sg72
 S'0.9.0'
-p307
-sS'build'
-p308
+p267
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p309
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p310
+p268
+sg76
+(lp269
+sg78
 S'vlc-android'
-p311
-sS'forcevercode'
-p312
+p270
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp271
+sg83
+(lp272
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p313
-(lp314
-S'no'
-p315
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp273
+sg93
 I00
-sS'prebuild'
-p316
+sg94
+Nsg95
+Nsg96
+(lp274
+sg98
+(lp275
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p317
-sg116
+p276
+sg102
 I00
-sS'commit'
-p318
+sg103
 S'0.9.0'
-p319
-sa(dp320
-g64
+p277
+sa(dp278
+g54
 I00
-sg65
+sg55
 S'9102'
-p321
-sg283
+p279
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp322
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p323
-(lp324
+sg59
+(lp280
+sg61
+I00
+sg62
+(lp281
+sg64
+(lp282
+sg66
 S'VLC@37e886d113b8b567c15208579fb2f'
-p325
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
-S'0.9.1'
-p326
-sS'build'
-p327
+p283
+sg68
+Nsg69
+(lp284
+sg71
+g24
+sg72
+S'0.9.1'
+p285
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p328
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p329
+p286
+sg76
+(lp287
+sg78
 S'vlc-android'
-p330
-sS'forcevercode'
-p331
+p288
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp289
+sg83
+(lp290
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p332
-(lp333
-S'no'
-p334
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp291
+sg93
 I00
-sS'prebuild'
-p335
+sg94
+Nsg95
+Nsg96
+(lp292
+sg98
+(lp293
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p336
-sg116
+p294
+sg102
 I00
-sS'commit'
-p337
+sg103
 S'0.9.1'
-p338
-sa(dp339
-g64
+p295
+sa(dp296
+g54
 I00
-sg65
+sg55
 S'9104'
-p340
-sg283
+p297
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp341
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p342
-(lp343
+sg59
+(lp298
+sg61
+I00
+sg62
+(lp299
+sg64
+(lp300
+sg66
 S'VLC@37e886d113b8b567c15208579fb2f'
-p344
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p301
+sg68
+Nsg69
+(lp302
+sg71
+g24
+sg72
 S'0.9.1'
-p345
-sS'build'
-p346
+p303
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p347
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p348
+p304
+sg76
+(lp305
+sg78
 S'vlc-android'
-p349
-sS'forcevercode'
-p350
+p306
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp307
+sg83
+(lp308
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p351
-(lp352
-S'no'
-p353
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp309
+sg93
 I00
-sS'prebuild'
-p354
+sg94
+Nsg95
+Nsg96
+(lp310
+sg98
+(lp311
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p355
-sg116
+p312
+sg102
 I00
-sS'commit'
-p356
+sg103
 S'0.9.1'
-p357
-sa(dp358
-g64
+p313
+sa(dp314
+g54
 I00
-sg65
+sg55
 S'9502'
-p359
-sg283
+p315
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp360
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p361
-(lp362
+sg59
+(lp316
+sg61
+I00
+sg62
+(lp317
+sg64
+(lp318
+sg66
 S'VLC@052600173f376ff58ff04d53746961a2'
-p363
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p319
+sg68
+Nsg69
+(lp320
+sg71
+g24
+sg72
 S'0.9.5'
-p364
-sS'build'
-p365
+p321
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p366
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p367
+p322
+sg76
+(lp323
+sg78
 S'vlc-android'
-p368
-sS'forcevercode'
-p369
+p324
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp325
+sg83
+(lp326
+sg88
 I00
-sS'disable'
-p370
+sg89
 S"can't download gmp"
-p371
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p372
-(lp373
-S'no'
-p374
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
-I00
-sS'prebuild'
-p375
+p327
+sg90
+Nsg91
+(lp328
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp329
+sg98
+(lp330
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p376
-sg116
+p331
+sg102
 I00
-sS'commit'
-p377
+sg103
 S'0.9.5'
-p378
-sa(dp379
-g64
+p332
+sa(dp333
+g54
 I00
-sg65
+sg55
 S'9504'
-p380
-sg283
+p334
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp381
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p382
-(lp383
+sg59
+(lp335
+sg61
+I00
+sg62
+(lp336
+sg64
+(lp337
+sg66
 S'VLC@052600173f376ff58ff04d53746961a2'
-p384
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p338
+sg68
+Nsg69
+(lp339
+sg71
+g24
+sg72
 S'0.9.5'
-p385
-sS'build'
-p386
+p340
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p387
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p388
+p341
+sg76
+(lp342
+sg78
 S'vlc-android'
-p389
-sS'forcevercode'
-p390
+p343
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp344
+sg83
+(lp345
+sg88
 I00
-sS'disable'
-p391
+sg89
 S"can't download gmp"
-p392
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p393
-(lp394
-S'no'
-p395
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
-I00
-sS'prebuild'
-p396
+p346
+sg90
+Nsg91
+(lp347
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp348
+sg98
+(lp349
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC$$ ../vlc"
-p397
-sg116
+p350
+sg102
 I00
-sS'commit'
-p398
+sg103
 S'0.9.5'
-p399
-sa(dp400
-g64
+p351
+sa(dp352
+g54
 I00
-sg65
+sg55
 S'9602'
-p401
-sg283
+p353
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp402
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p403
-(lp404
+sg59
+(lp354
+sg61
+I00
+sg62
+(lp355
+sg64
+(lp356
+sg66
 S'VLC-2.2@27f4799'
-p405
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p357
+sg68
+Nsg69
+(lp358
+sg71
+g24
+sg72
 S'0.9.6'
-p406
-sS'build'
-p407
+p359
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p408
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p409
+p360
+sg76
+(lp361
+sg78
 S'vlc-android'
-p410
-sS'forcevercode'
-p411
+p362
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp363
+sg83
+(lp364
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p412
-(lp413
-S'no'
-p414
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp365
+sg93
 I00
-sS'prebuild'
-p415
+sg94
+Nsg95
+Nsg96
+(lp366
+sg98
+(lp367
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p416
-sg116
+p368
+sg102
 I00
-sS'commit'
-p417
+sg103
 S'0.9.6'
-p418
-sa(dp419
-g64
+p369
+sa(dp370
+g54
 I00
-sg65
+sg55
 S'9604'
-p420
-sg283
+p371
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp421
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p422
-(lp423
+sg59
+(lp372
+sg61
+I00
+sg62
+(lp373
+sg64
+(lp374
+sg66
 S'VLC-2.2@27f4799'
-p424
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p375
+sg68
+Nsg69
+(lp376
+sg71
+g24
+sg72
 S'0.9.6'
-p425
-sS'build'
-p426
+p377
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p427
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p428
+p378
+sg76
+(lp379
+sg78
 S'vlc-android'
-p429
-sS'forcevercode'
-p430
+p380
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
-I00
-sg100
+sg81
+(lp381
+sg83
+(lp382
+sg88
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p431
-(lp432
-S'no'
-p433
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg89
 I00
-sS'prebuild'
-p434
+sg90
+Nsg91
+(lp383
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp384
+sg98
+(lp385
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p435
-sg116
+p386
+sg102
 I00
-sS'commit'
-p436
+sg103
 S'0.9.6'
-p437
-sa(dp438
-g64
+p387
+sa(dp388
+g54
 I00
-sg65
+sg55
 S'9702'
-p439
-sg283
+p389
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp440
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p441
-(lp442
+sg59
+(lp390
+sg61
+I00
+sg62
+(lp391
+sg64
+(lp392
+sg66
 S'VLC-2.2@9e1c6ff'
-p443
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p393
+sg68
+Nsg69
+(lp394
+sg71
+g24
+sg72
 S'0.9.7'
-p444
-sS'build'
-p445
+p395
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p446
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p447
+p396
+sg76
+(lp397
+sg78
 S'vlc-android'
-p448
-sS'forcevercode'
-p449
+p398
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp399
+sg83
+(lp400
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p450
-(lp451
-S'no'
-p452
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp401
+sg93
 I00
-sS'prebuild'
-p453
+sg94
+Nsg95
+Nsg96
+(lp402
+sg98
+(lp403
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p454
-sg116
+p404
+sg102
 I00
-sS'commit'
-p455
+sg103
 S'0.9.7'
-p456
-sa(dp457
-g64
+p405
+sa(dp406
+g54
 I00
-sg65
+sg55
 S'9704'
-p458
-sg283
+p407
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp459
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p460
-(lp461
+sg59
+(lp408
+sg61
+I00
+sg62
+(lp409
+sg64
+(lp410
+sg66
 S'VLC-2.2@9e1c6ff'
-p462
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p411
+sg68
+Nsg69
+(lp412
+sg71
+g24
+sg72
 S'0.9.7'
-p463
-sS'build'
-p464
+p413
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p465
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p466
+p414
+sg76
+(lp415
+sg78
 S'vlc-android'
-p467
-sS'forcevercode'
-p468
+p416
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp417
+sg83
+(lp418
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p469
-(lp470
-S'no'
-p471
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp419
+sg93
 I00
-sS'prebuild'
-p472
+sg94
+Nsg95
+Nsg96
+(lp420
+sg98
+(lp421
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p473
-sg116
+p422
+sg102
 I00
-sS'commit'
-p474
+sg103
 S'0.9.7'
-p475
-sa(dp476
-g64
+p423
+sa(dp424
+g54
 I00
-sg65
+sg55
 S'9711'
-p477
-sg283
+p425
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp478
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p479
-(lp480
+sg59
+(lp426
+sg61
+I00
+sg62
+(lp427
+sg64
+(lp428
+sg66
 S'VLC-2.2@57cd36b'
-p481
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p429
+sg68
+Nsg69
+(lp430
+sg71
+g24
+sg72
 S'0.9.7.1'
-p482
-sS'build'
-p483
+p431
+sg74
 S'cd ../ && ANDROID_ABI=mips ./compile.sh release'
-p484
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p485
+p432
+sg76
+(lp433
+sg78
 S'vlc-android'
-p486
-sS'forcevercode'
-p487
+p434
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp435
+sg83
+(lp436
+sg88
 I00
-sS'disable'
-p488
+sg89
 S'build fails'
-p489
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p490
-(lp491
-S'no'
-p492
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
-I00
-sS'prebuild'
-p493
+p437
+sg90
+Nsg91
+(lp438
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp439
+sg98
+(lp440
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p494
-sg116
+p441
+sg102
 I00
-sS'commit'
-p495
+sg103
 S'0.9.7.1'
-p496
-sa(dp497
-g64
+p442
+sa(dp443
+g54
 I00
-sg65
+sg55
 S'9712'
-p498
-sg283
+p444
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp499
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p500
-(lp501
+sg59
+(lp445
+sg61
+I00
+sg62
+(lp446
+sg64
+(lp447
+sg66
 S'VLC-2.2@57cd36b'
-p502
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p448
+sg68
+Nsg69
+(lp449
+sg71
+g24
+sg72
 S'0.9.7.1'
-p503
-sS'build'
-p504
+p450
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p505
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p506
+p451
+sg76
+(lp452
+sg78
 S'vlc-android'
-p507
-sS'forcevercode'
-p508
+p453
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp454
+sg83
+(lp455
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p509
-(lp510
-S'no'
-p511
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp456
+sg93
 I00
-sS'prebuild'
-p512
+sg94
+Nsg95
+Nsg96
+(lp457
+sg98
+(lp458
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p513
-sg116
+p459
+sg102
 I00
-sS'commit'
-p514
+sg103
 S'0.9.7.1'
-p515
-sa(dp516
-g64
+p460
+sa(dp461
+g54
 I00
-sg65
+sg55
 S'9714'
-p517
-sg283
+p462
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp518
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p519
-(lp520
+sg59
+(lp463
+sg61
+I00
+sg62
+(lp464
+sg64
+(lp465
+sg66
 S'VLC-2.2@57cd36b'
-p521
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p466
+sg68
+Nsg69
+(lp467
+sg71
+g24
+sg72
 S'0.9.7.1'
-p522
-sS'build'
-p523
+p468
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p524
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p525
+p469
+sg76
+(lp470
+sg78
 S'vlc-android'
-p526
-sS'forcevercode'
-p527
+p471
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp472
+sg83
+(lp473
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p528
-(lp529
-S'no'
-p530
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp474
+sg93
 I00
-sS'prebuild'
-p531
+sg94
+Nsg95
+Nsg96
+(lp475
+sg98
+(lp476
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p532
-sg116
+p477
+sg102
 I00
-sS'commit'
-p533
+sg103
 S'0.9.7.1'
-p534
-sa(dp535
-g64
+p478
+sa(dp479
+g54
 I00
-sg65
+sg55
 S'9802'
-p536
-sg283
+p480
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp537
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p538
-(lp539
+sg59
+(lp481
+sg61
+I00
+sg62
+(lp482
+sg64
+(lp483
+sg66
 S'VLC-2.2@f2db364'
-p540
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p484
+sg68
+Nsg69
+(lp485
+sg71
+g24
+sg72
 S'0.9.8'
-p541
-sS'build'
-p542
+p486
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p543
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p544
+p487
+sg76
+(lp488
+sg78
 S'vlc-android'
-p545
-sS'forcevercode'
-p546
+p489
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp490
+sg83
+(lp491
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p547
-(lp548
-S'no'
-p549
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp492
+sg93
 I00
-sS'prebuild'
-p550
+sg94
+Nsg95
+Nsg96
+(lp493
+sg98
+(lp494
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p551
-sg116
+p495
+sg102
 I00
-sS'commit'
-p552
+sg103
 S'0.9.8'
-p553
-sa(dp554
-g64
+p496
+sa(dp497
+g54
 I00
-sg65
+sg55
 S'9803'
-p555
-sg283
+p498
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp556
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p557
-(lp558
+sg59
+(lp499
+sg61
+I00
+sg62
+(lp500
+sg64
+(lp501
+sg66
 S'VLC-2.2@f2db364'
-p559
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p502
+sg68
+Nsg69
+(lp503
+sg71
+g24
+sg72
 S'0.9.8'
-p560
-sS'build'
-p561
+p504
+sg74
 S'cd ../ && ANDROID_ABI=armeabi ./compile.sh release'
-p562
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p563
+p505
+sg76
+(lp506
+sg78
 S'vlc-android'
-p564
-sS'forcevercode'
-p565
+p507
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
-I00
-sg100
+sg81
+(lp508
+sg83
+(lp509
+sg88
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p566
-(lp567
-S'no'
-p568
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg89
 I00
-sS'prebuild'
-p569
+sg90
+Nsg91
+(lp510
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp511
+sg98
+(lp512
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p570
-sg116
+p513
+sg102
 I00
-sS'commit'
-p571
+sg103
 S'0.9.8'
-p572
-sa(dp573
-g64
+p514
+sa(dp515
+g54
 I00
-sg65
+sg55
 S'9804'
-p574
-sg283
+p516
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp575
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p576
-(lp577
+sg59
+(lp517
+sg61
+I00
+sg62
+(lp518
+sg64
+(lp519
+sg66
 S'VLC-2.2@f2db364'
-p578
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p520
+sg68
+Nsg69
+(lp521
+sg71
+g24
+sg72
 S'0.9.8'
-p579
-sS'build'
-p580
+p522
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p581
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p582
+p523
+sg76
+(lp524
+sg78
 S'vlc-android'
-p583
-sS'forcevercode'
-p584
+p525
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp526
+sg83
+(lp527
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p585
-(lp586
-S'no'
-p587
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp528
+sg93
 I00
-sS'prebuild'
-p588
+sg94
+Nsg95
+Nsg96
+(lp529
+sg98
+(lp530
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p589
-sg116
+p531
+sg102
 I00
-sS'commit'
-p590
+sg103
 S'0.9.8'
-p591
-sa(dp592
-g64
+p532
+sa(dp533
+g54
 I00
-sg65
+sg55
 S'9902'
-p593
-sg283
+p534
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp594
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p595
-(lp596
+sg59
+(lp535
+sg61
+I00
+sg62
+(lp536
+sg64
+(lp537
+sg66
 S'VLC-2.2@e731dc23a4f8ef6782c7cc2236bbbf41c034dad1'
-p597
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p538
+sg68
+Nsg69
+(lp539
+sg71
+g24
+sg72
 S'0.9.9'
-p598
-sS'build'
-p599
+p540
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p600
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p601
+p541
+sg76
+(lp542
+sg78
 S'vlc-android'
-p602
-sS'forcevercode'
-p603
+p543
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp544
+sg83
+(lp545
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p604
-(lp605
-S'no'
-p606
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp546
+sg93
 I00
-sS'prebuild'
-p607
+sg94
+Nsg95
+Nsg96
+(lp547
+sg98
+(lp548
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p608
-sg116
+p549
+sg102
 I00
-sS'commit'
-p609
+sg103
 S'0.9.9'
-p610
-sa(dp611
-g64
+p550
+sa(dp551
+g54
 I00
-sg65
+sg55
 S'9903'
-p612
-sg283
+p552
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp613
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p614
-(lp615
+sg59
+(lp553
+sg61
+I00
+sg62
+(lp554
+sg64
+(lp555
+sg66
 S'VLC-2.2@e731dc23a4f8ef6782c7cc2236bbbf41c034dad1'
-p616
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p556
+sg68
+Nsg69
+(lp557
+sg71
+g24
+sg72
 S'0.9.9'
-p617
-sS'build'
-p618
+p558
+sg74
 S'cd ../ && ANDROID_ABI=armeabi ./compile.sh release'
-p619
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p620
+p559
+sg76
+(lp560
+sg78
 S'vlc-android'
-p621
-sS'forcevercode'
-p622
+p561
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp562
+sg83
+(lp563
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p623
-(lp624
-S'no'
-p625
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp564
+sg93
 I00
-sS'prebuild'
-p626
+sg94
+Nsg95
+Nsg96
+(lp565
+sg98
+(lp566
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p627
-sg116
+p567
+sg102
 I00
-sS'commit'
-p628
+sg103
 S'0.9.9'
-p629
-sa(dp630
-g64
+p568
+sa(dp569
+g54
 I00
-sg65
+sg55
 S'9904'
-p631
-sg283
+p570
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp632
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p633
-(lp634
+sg59
+(lp571
+sg61
+I00
+sg62
+(lp572
+sg64
+(lp573
+sg66
 S'VLC-2.2@e731dc23a4f8ef6782c7cc2236bbbf41c034dad1'
-p635
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p574
+sg68
+Nsg69
+(lp575
+sg71
+g24
+sg72
 S'0.9.9'
-p636
-sS'build'
-p637
+p576
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p638
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p639
+p577
+sg76
+(lp578
+sg78
 S'vlc-android'
-p640
-sS'forcevercode'
-p641
+p579
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp580
+sg83
+(lp581
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p642
-(lp643
-S'no'
-p644
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp582
+sg93
 I00
-sS'prebuild'
-p645
+sg94
+Nsg95
+Nsg96
+(lp583
+sg98
+(lp584
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p646
-sg116
+p585
+sg102
 I00
-sS'commit'
-p647
+sg103
 S'0.9.9'
-p648
-sa(dp649
-g64
+p586
+sa(dp587
+g54
 I00
-sg65
+sg55
 S'10002'
-p650
-sg283
+p588
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp651
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p652
-(lp653
+sg59
+(lp589
+sg61
+I00
+sg62
+(lp590
+sg64
+(lp591
+sg66
 S'VLC-2.2@e33e5de'
-p654
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p592
+sg68
+Nsg69
+(lp593
+sg71
+g24
+sg72
 S'0.9.10'
-p655
-sS'build'
-p656
+p594
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p657
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p658
+p595
+sg76
+(lp596
+sg78
 S'vlc-android'
-p659
-sS'forcevercode'
-p660
+p597
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp598
+sg83
+(lp599
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p661
-(lp662
-S'no'
-p663
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp600
+sg93
 I00
-sS'prebuild'
-p664
+sg94
+Nsg95
+Nsg96
+(lp601
+sg98
+(lp602
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p665
-sg116
+p603
+sg102
 I00
-sS'commit'
-p666
+sg103
 S'0.9.10'
-p667
-sa(dp668
-g64
+p604
+sa(dp605
+g54
 I00
-sg65
+sg55
 S'10003'
-p669
-sg283
+p606
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp670
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p671
-(lp672
+sg59
+(lp607
+sg61
+I00
+sg62
+(lp608
+sg64
+(lp609
+sg66
 S'VLC-2.2@e33e5de'
-p673
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p610
+sg68
+Nsg69
+(lp611
+sg71
+g24
+sg72
 S'0.9.10'
-p674
-sS'build'
-p675
+p612
+sg74
 S'cd ../ && ANDROID_ABI=armeabi ./compile.sh release'
-p676
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p677
+p613
+sg76
+(lp614
+sg78
 S'vlc-android'
-p678
-sS'forcevercode'
-p679
+p615
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp616
+sg83
+(lp617
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p680
-(lp681
-S'no'
-p682
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp618
+sg93
 I00
-sS'prebuild'
-p683
+sg94
+Nsg95
+Nsg96
+(lp619
+sg98
+(lp620
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p684
-sg116
+p621
+sg102
 I00
-sS'commit'
-p685
+sg103
 S'0.9.10'
-p686
-sa(dp687
-g64
+p622
+sa(dp623
+g54
 I00
-sg65
+sg55
 S'10004'
-p688
-sg283
+p624
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp689
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p690
-(lp691
+sg59
+(lp625
+sg61
+I00
+sg62
+(lp626
+sg64
+(lp627
+sg66
 S'VLC-2.2@e33e5de'
-p692
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p628
+sg68
+Nsg69
+(lp629
+sg71
+g24
+sg72
 S'0.9.10'
-p693
-sS'build'
-p694
+p630
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p695
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p696
+p631
+sg76
+(lp632
+sg78
 S'vlc-android'
-p697
-sS'forcevercode'
-p698
+p633
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp634
+sg83
+(lp635
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p699
-(lp700
-S'no'
-p701
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp636
+sg93
 I00
-sS'prebuild'
-p702
+sg94
+Nsg95
+Nsg96
+(lp637
+sg98
+(lp638
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p703
-sg116
+p639
+sg102
 I00
-sS'commit'
-p704
+sg103
 S'0.9.10'
-p705
-sa(dp706
-g64
+p640
+sa(dp641
+g54
 I00
-sg65
+sg55
 S'10006'
-p707
-sg283
+p642
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp708
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p709
-(lp710
+sg59
+(lp643
+sg61
+I00
+sg62
+(lp644
+sg64
+(lp645
+sg66
 S'VLC-2.2@036010e'
-p711
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p646
+sg68
+Nsg69
+(lp647
+sg71
+g24
+sg72
 S'1.0.0'
-p712
-sS'build'
-p713
+p648
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p714
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p715
+p649
+sg76
+(lp650
+sg78
 S'vlc-android'
-p716
-sS'forcevercode'
-p717
+p651
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp652
+sg83
+(lp653
+sg88
 I00
-sS'disable'
-p718
+sg89
 S"doesn't build"
-p719
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p720
-(lp721
-S'no'
-p722
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
-I00
-sS'prebuild'
-p723
+p654
+sg90
+Nsg91
+(lp655
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp656
+sg98
+(lp657
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p724
-sg116
+p658
+sg102
 I00
-sS'commit'
-p725
+sg103
 S'1.0.0'
-p726
-sa(dp727
-g64
+p659
+sa(dp660
+g54
 I00
-sg65
+sg55
 S'10007'
-p728
-sg283
+p661
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp729
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p730
-(lp731
+sg59
+(lp662
+sg61
+I00
+sg62
+(lp663
+sg64
+(lp664
+sg66
 S'VLC-2.2@036010e'
-p732
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p665
+sg68
+Nsg69
+(lp666
+sg71
+g24
+sg72
 S'1.0.0'
-p733
-sS'build'
-p734
+p667
+sg74
 S'cd ../ && ANDROID_ABI=armeabi ./compile.sh release'
-p735
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p736
+p668
+sg76
+(lp669
+sg78
 S'vlc-android'
-p737
-sS'forcevercode'
-p738
+p670
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp671
+sg83
+(lp672
+sg88
 I00
-sS'disable'
-p739
+sg89
 S"doesn't build"
-p740
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p741
-(lp742
-S'no'
-p743
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
-I00
-sS'prebuild'
-p744
+p673
+sg90
+Nsg91
+(lp674
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp675
+sg98
+(lp676
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p745
-sg116
+p677
+sg102
 I00
-sS'commit'
-p746
+sg103
 S'1.0.0'
-p747
-sa(dp748
-g64
+p678
+sa(dp679
+g54
 I00
-sg65
+sg55
 S'10008'
-p749
-sg283
+p680
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp750
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p751
-(lp752
+sg59
+(lp681
+sg61
+I00
+sg62
+(lp682
+sg64
+(lp683
+sg66
 S'VLC-2.2@036010e'
-p753
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p684
+sg68
+Nsg69
+(lp685
+sg71
+g24
+sg72
 S'1.0.0'
-p754
-sS'build'
-p755
+p686
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p756
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p757
+p687
+sg76
+(lp688
+sg78
 S'vlc-android'
-p758
-sS'forcevercode'
-p759
+p689
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp690
+sg83
+(lp691
+sg88
 I00
-sS'disable'
-p760
+sg89
 S"doesn't build"
-p761
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p762
-(lp763
-S'no'
-p764
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
-I00
-sS'prebuild'
-p765
+p692
+sg90
+Nsg91
+(lp693
+sg93
+I00
+sg94
+Nsg95
+Nsg96
+(lp694
+sg98
+(lp695
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p766
-sg116
+p696
+sg102
 I00
-sS'commit'
-p767
+sg103
 S'1.0.0'
-p768
-sa(dp769
-g64
+p697
+sa(dp698
+g54
 I00
-sg65
+sg55
 S'10102'
-p770
-sg283
+p699
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp771
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p772
-(lp773
+sg59
+(lp700
+sg61
+I00
+sg62
+(lp701
+sg64
+(lp702
+sg66
 S'VLC-2.2@59409d5'
-p774
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p703
+sg68
+Nsg69
+(lp704
+sg71
+g24
+sg72
 S'1.0.1'
-p775
-sS'build'
-p776
+p705
+sg74
 S'cd ../ && ANDROID_ABI=x86 ./compile.sh release'
-p777
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p778
+p706
+sg76
+(lp707
+sg78
 S'vlc-android'
-p779
-sS'forcevercode'
-p780
+p708
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp709
+sg83
+(lp710
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p781
-(lp782
-S'no'
-p783
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp711
+sg93
 I00
-sS'prebuild'
-p784
+sg94
+Nsg95
+Nsg96
+(lp712
+sg98
+(lp713
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p785
-sg116
+p714
+sg102
 I00
-sS'commit'
-p786
+sg103
 S'1.0.1'
-p787
-sa(dp788
-g64
+p715
+sa(dp716
+g54
 I00
-sg65
+sg55
 S'10103'
-p789
-sg283
+p717
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp790
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p791
-(lp792
+sg59
+(lp718
+sg61
+I00
+sg62
+(lp719
+sg64
+(lp720
+sg66
 S'VLC-2.2@59409d5'
-p793
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p721
+sg68
+Nsg69
+(lp722
+sg71
+g24
+sg72
 S'1.0.1'
-p794
-sS'build'
-p795
+p723
+sg74
 S'cd ../ && ANDROID_ABI=armeabi ./compile.sh release'
-p796
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p797
+p724
+sg76
+(lp725
+sg78
 S'vlc-android'
-p798
-sS'forcevercode'
-p799
+p726
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp727
+sg83
+(lp728
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p800
-(lp801
-S'no'
-p802
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp729
+sg93
 I00
-sS'prebuild'
-p803
+sg94
+Nsg95
+Nsg96
+(lp730
+sg98
+(lp731
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p804
-sg116
+p732
+sg102
 I00
-sS'commit'
-p805
+sg103
 S'1.0.1'
-p806
-sa(dp807
-g64
+p733
+sa(dp734
+g54
 I00
-sg65
+sg55
 S'10104'
-p808
-sg283
+p735
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp809
-sg71
-g72
-sg73
-g74
-sS'srclibs'
-p810
-(lp811
+sg59
+(lp736
+sg61
+I00
+sg62
+(lp737
+sg64
+(lp738
+sg66
 S'VLC-2.2@59409d5'
-p812
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p739
+sg68
+Nsg69
+(lp740
+sg71
+g24
+sg72
 S'1.0.1'
-p813
-sS'build'
-p814
+p741
+sg74
 S'cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release'
-p815
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p816
+p742
+sg76
+(lp743
+sg78
 S'vlc-android'
-p817
-sS'forcevercode'
-p818
+p744
+sg80
 I01
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp745
+sg83
+(lp746
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p819
-(lp820
-S'no'
-p821
-asg107
-g108
-sg109
-Nsg110
-g111
-sg112
-Nsg113
+sg90
+Nsg91
+(lp747
+sg93
 I00
-sS'prebuild'
-p822
+sg94
+Nsg95
+Nsg96
+(lp748
+sg98
+(lp749
+sg100
 S"sed -i '/ant/d' ../Makefile && ln -s vlc-android/$$VLC-2.2$$ ../vlc"
-p823
-sg116
+p750
+sg102
 I00
-sS'commit'
-p824
+sg103
 S'1.0.1'
-p825
-sa(dp826
-g64
+p751
+sa(dp752
+g54
 I00
-sg65
+sg55
 S'1010303'
-p827
-sg283
+p753
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp828
-sg71
-g72
-sS'gradle'
-p829
-(lp830
-S'VanillaARMv6fpu'
-p831
-asS'srclibs'
-p832
-(lp833
+sg59
+(lp754
+sg61
+I00
+sg62
+(lp755
+sg64
+(lp756
+sg66
 S'VLC@a9b19e4'
-p834
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p757
+sg68
+Nsg69
+(lp758
+sg71
+g24
+sg72
 S'1.1.3'
-p835
-sS'build'
-p836
+p759
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p837
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p838
+p760
+sg76
+(lp761
+sg78
 S'vlc-android'
-p839
-sS'forcevercode'
-p840
+p762
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp763
+sg83
+(lp764
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p841
-(lp842
-S'no'
-p843
-asS'ndk'
-p844
+sg90
+Nsg91
+(lp765
+sg93
+I00
+sg94
 S'r10d'
-p845
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p846
+p766
+sg95
+Nsg96
+(lp767
+sg98
+S'VanillaARMv6fpu'
+p768
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p847
-sg116
+p769
+sg102
 I00
-sS'commit'
-p848
+sg103
 S'1.1.3'
-p849
-sa(dp850
-g64
+p770
+sa(dp771
+g54
 I00
-sg65
+sg55
 S'1010304'
-p851
-sg283
+p772
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp852
-sg71
-g72
-sS'gradle'
-p853
-(lp854
-S'VanillaARMv7'
-p855
-asS'srclibs'
-p856
-(lp857
+sg59
+(lp773
+sg61
+I00
+sg62
+(lp774
+sg64
+(lp775
+sg66
 S'VLC@a9b19e4'
-p858
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p776
+sg68
+Nsg69
+(lp777
+sg71
+g24
+sg72
 S'1.1.3'
-p859
-sS'build'
-p860
+p778
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p861
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p862
+p779
+sg76
+(lp780
+sg78
 S'vlc-android'
-p863
-sg840
+p781
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp782
+sg83
+(lp783
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p864
-(lp865
-S'no'
-p866
-asS'ndk'
-p867
+sg90
+Nsg91
+(lp784
+sg93
+I00
+sg94
 S'r10d'
-p868
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p869
+p785
+sg95
+Nsg96
+(lp786
+sg98
+S'VanillaARMv7'
+p787
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p870
-sg116
+p788
+sg102
 I00
-sS'commit'
-p871
+sg103
 S'1.1.3'
-p872
-sa(dp873
-g64
+p789
+sa(dp790
+g54
 I00
-sg65
+sg55
 S'1010305'
-p874
-sg283
+p791
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp875
-sg71
-g72
-sS'gradle'
-p876
-(lp877
-S'VanillaX86'
-p878
-asS'srclibs'
-p879
-(lp880
+sg59
+(lp792
+sg61
+I00
+sg62
+(lp793
+sg64
+(lp794
+sg66
 S'VLC@a9b19e4'
-p881
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
-S'1.1.3'
-p882
-sS'build'
-p883
+p795
+sg68
+Nsg69
+(lp796
+sg71
+g24
+sg72
+S'1.1.3'
+p797
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p884
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p885
+p798
+sg76
+(lp799
+sg78
 S'vlc-android'
-p886
-sg840
+p800
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp801
+sg83
+(lp802
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p887
-(lp888
-S'no'
-p889
-asS'ndk'
-p890
+sg90
+Nsg91
+(lp803
+sg93
+I00
+sg94
 S'r10d'
-p891
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p892
+p804
+sg95
+Nsg96
+(lp805
+sg98
+S'VanillaX86'
+p806
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p893
-sg116
+p807
+sg102
 I00
-sS'commit'
-p894
+sg103
 S'1.1.3'
-p895
-sa(dp896
-g64
+p808
+sa(dp809
+g54
 I00
-sg65
+sg55
 S'1010503'
-p897
-sg283
+p810
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp898
-sg71
-g72
-sS'gradle'
-p899
-(lp900
-S'VanillaARMv6fpu'
-p901
-asS'srclibs'
-p902
-(lp903
+sg59
+(lp811
+sg61
+I00
+sg62
+(lp812
+sg64
+(lp813
+sg66
 S'VLC@e6b4585'
-p904
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p814
+sg68
+Nsg69
+(lp815
+sg71
+g24
+sg72
 S'1.1.5'
-p905
-sS'build'
-p906
+p816
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p907
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p908
+p817
+sg76
+(lp818
+sg78
 S'vlc-android'
-p909
-sg840
+p819
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp820
+sg83
+(lp821
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p910
-(lp911
-S'no'
-p912
-asS'ndk'
-p913
+sg90
+Nsg91
+(lp822
+sg93
+I00
+sg94
 S'r10d'
-p914
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p915
+p823
+sg95
+Nsg96
+(lp824
+sg98
+S'VanillaARMv6fpu'
+p825
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p916
-sg116
+p826
+sg102
 I00
-sS'commit'
-p917
+sg103
 S'1.1.5'
-p918
-sa(dp919
-g64
+p827
+sa(dp828
+g54
 I00
-sg65
+sg55
 S'1010504'
-p920
-sg283
+p829
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp921
-sg71
-g72
-sS'gradle'
-p922
-(lp923
-S'VanillaARMv7'
-p924
-asS'srclibs'
-p925
-(lp926
+sg59
+(lp830
+sg61
+I00
+sg62
+(lp831
+sg64
+(lp832
+sg66
 S'VLC@e6b4585'
-p927
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p833
+sg68
+Nsg69
+(lp834
+sg71
+g24
+sg72
 S'1.1.5'
-p928
-sS'build'
-p929
+p835
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p930
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p931
+p836
+sg76
+(lp837
+sg78
 S'vlc-android'
-p932
-sg840
+p838
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp839
+sg83
+(lp840
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p933
-(lp934
-S'no'
-p935
-asS'ndk'
-p936
+sg90
+Nsg91
+(lp841
+sg93
+I00
+sg94
 S'r10d'
-p937
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p938
+p842
+sg95
+Nsg96
+(lp843
+sg98
+S'VanillaARMv7'
+p844
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p939
-sg116
+p845
+sg102
 I00
-sS'commit'
-p940
+sg103
 S'1.1.5'
-p941
-sa(dp942
-g64
+p846
+sa(dp847
+g54
 I00
-sg65
+sg55
 S'1010505'
-p943
-sg283
+p848
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp944
-sg71
-g72
-sS'gradle'
-p945
-(lp946
-S'VanillaX86'
-p947
-asS'srclibs'
-p948
-(lp949
+sg59
+(lp849
+sg61
+I00
+sg62
+(lp850
+sg64
+(lp851
+sg66
 S'VLC@e6b4585'
-p950
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p852
+sg68
+Nsg69
+(lp853
+sg71
+g24
+sg72
 S'1.1.5'
-p951
-sS'build'
-p952
+p854
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p953
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p954
+p855
+sg76
+(lp856
+sg78
 S'vlc-android'
-p955
-sg840
+p857
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp858
+sg83
+(lp859
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p956
-(lp957
-S'no'
-p958
-asS'ndk'
-p959
+sg90
+Nsg91
+(lp860
+sg93
+I00
+sg94
 S'r10d'
-p960
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p961
+p861
+sg95
+Nsg96
+(lp862
+sg98
+S'VanillaX86'
+p863
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p962
-sg116
+p864
+sg102
 I00
-sS'commit'
-p963
+sg103
 S'1.1.5'
-p964
-sa(dp965
-g64
+p865
+sa(dp866
+g54
 I00
-sg65
+sg55
 S'1010603'
-p966
-sg283
+p867
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp967
-sg71
-g72
-sS'gradle'
-p968
-(lp969
-S'VanillaARMv6fpu'
-p970
-asS'srclibs'
-p971
-(lp972
+sg59
+(lp868
+sg61
+I00
+sg62
+(lp869
+sg64
+(lp870
+sg66
 S'VLC@551b670'
-p973
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p871
+sg68
+Nsg69
+(lp872
+sg71
+g24
+sg72
 S'1.1.6'
-p974
-sS'build'
-p975
+p873
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p976
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p977
+p874
+sg76
+(lp875
+sg78
 S'vlc-android'
-p978
-sg840
+p876
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp877
+sg83
+(lp878
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p979
-(lp980
-S'no'
-p981
-asS'ndk'
-p982
+sg90
+Nsg91
+(lp879
+sg93
+I00
+sg94
 S'r10d'
-p983
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p984
+p880
+sg95
+Nsg96
+(lp881
+sg98
+S'VanillaARMv6fpu'
+p882
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p985
-sg116
+p883
+sg102
 I00
-sS'commit'
-p986
+sg103
 S'1.1.6'
-p987
-sa(dp988
-g64
+p884
+sa(dp885
+g54
 I00
-sg65
+sg55
 S'1010604'
-p989
-sg283
+p886
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp990
-sg71
-g72
-sS'gradle'
-p991
-(lp992
-S'VanillaARMv7'
-p993
-asS'srclibs'
-p994
-(lp995
+sg59
+(lp887
+sg61
+I00
+sg62
+(lp888
+sg64
+(lp889
+sg66
 S'VLC@551b670'
-p996
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p890
+sg68
+Nsg69
+(lp891
+sg71
+g24
+sg72
 S'1.1.6'
-p997
-sS'build'
-p998
+p892
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p999
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1000
+p893
+sg76
+(lp894
+sg78
 S'vlc-android'
-p1001
-sg840
+p895
+sg80
+I00
+sg81
+(lp896
+sg83
+(lp897
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp898
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1002
-(lp1003
-S'no'
-p1004
-asS'ndk'
-p1005
+sg94
 S'r10d'
-p1006
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1007
+p899
+sg95
+Nsg96
+(lp900
+sg98
+S'VanillaARMv7'
+p901
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1008
-sg116
+p902
+sg102
 I00
-sS'commit'
-p1009
+sg103
 S'1.1.6'
-p1010
-sa(dp1011
-g64
+p903
+sa(dp904
+g54
 I00
-sg65
+sg55
 S'1010605'
-p1012
-sg283
+p905
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1013
-sg71
-g72
-sS'gradle'
-p1014
-(lp1015
-S'VanillaX86'
-p1016
-asS'srclibs'
-p1017
-(lp1018
+sg59
+(lp906
+sg61
+I00
+sg62
+(lp907
+sg64
+(lp908
+sg66
 S'VLC@551b670'
-p1019
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p909
+sg68
+Nsg69
+(lp910
+sg71
+g24
+sg72
 S'1.1.6'
-p1020
-sS'build'
-p1021
+p911
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p1022
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1023
+p912
+sg76
+(lp913
+sg78
 S'vlc-android'
-p1024
-sg840
+p914
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp915
+sg83
+(lp916
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1025
-(lp1026
-S'no'
-p1027
-asS'ndk'
-p1028
+sg90
+Nsg91
+(lp917
+sg93
+I00
+sg94
 S'r10d'
-p1029
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1030
+p918
+sg95
+Nsg96
+(lp919
+sg98
+S'VanillaX86'
+p920
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1031
-sg116
+p921
+sg102
 I00
-sS'commit'
-p1032
+sg103
 S'1.1.6'
-p1033
-sa(dp1034
-g64
+p922
+sa(dp923
+g54
 I00
-sg65
+sg55
 S'1020003'
-p1035
-sg283
+p924
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1036
-sg71
-g72
-sS'gradle'
-p1037
-(lp1038
-S'VanillaARMv6fpu'
-p1039
-asS'srclibs'
-p1040
-(lp1041
+sg59
+(lp925
+sg61
+I00
+sg62
+(lp926
+sg64
+(lp927
+sg66
 S'VLC@23c8d86'
-p1042
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p928
+sg68
+Nsg69
+(lp929
+sg71
+g24
+sg72
 S'1.2.0'
-p1043
-sS'build'
-p1044
+p930
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p1045
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1046
+p931
+sg76
+(lp932
+sg78
 S'vlc-android'
-p1047
-sg840
+p933
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp934
+sg83
+(lp935
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1048
-(lp1049
-S'no'
-p1050
-asS'ndk'
-p1051
+sg90
+Nsg91
+(lp936
+sg93
+I00
+sg94
 S'r10d'
-p1052
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1053
+p937
+sg95
+Nsg96
+(lp938
+sg98
+S'VanillaARMv6fpu'
+p939
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1054
-sg116
+p940
+sg102
 I00
-sS'commit'
-p1055
+sg103
 S'1.2.0'
-p1056
-sa(dp1057
-g64
+p941
+sa(dp942
+g54
+I00
+sg55
+S'1020004'
+p943
+sg57
 I00
-sg65
-S'1020004'
-p1058
-sg283
+sg58
 I00
-sg68
+sg59
+(lp944
+sg61
 I00
-sg69
-(lp1059
-sg71
-g72
-sS'gradle'
-p1060
-(lp1061
-S'VanillaARMv7'
-p1062
-asS'srclibs'
-p1063
-(lp1064
+sg62
+(lp945
+sg64
+(lp946
+sg66
 S'VLC@23c8d86'
-p1065
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p947
+sg68
+Nsg69
+(lp948
+sg71
+g24
+sg72
 S'1.2.0'
-p1066
-sS'build'
-p1067
+p949
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p1068
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1069
+p950
+sg76
+(lp951
+sg78
 S'vlc-android'
-p1070
-sg840
+p952
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp953
+sg83
+(lp954
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1071
-(lp1072
-S'no'
-p1073
-asS'ndk'
-p1074
+sg90
+Nsg91
+(lp955
+sg93
+I00
+sg94
 S'r10d'
-p1075
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1076
+p956
+sg95
+Nsg96
+(lp957
+sg98
+S'VanillaARMv7'
+p958
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1077
-sg116
+p959
+sg102
 I00
-sS'commit'
-p1078
+sg103
 S'1.2.0'
-p1079
-sa(dp1080
-g64
+p960
+sa(dp961
+g54
 I00
-sg65
+sg55
 S'1020005'
-p1081
-sg283
+p962
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1082
-sg71
-g72
-sS'gradle'
-p1083
-(lp1084
-S'VanillaX86'
-p1085
-asS'srclibs'
-p1086
-(lp1087
+sg59
+(lp963
+sg61
+I00
+sg62
+(lp964
+sg64
+(lp965
+sg66
 S'VLC@23c8d86'
-p1088
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p966
+sg68
+Nsg69
+(lp967
+sg71
+g24
+sg72
 S'1.2.0'
-p1089
-sS'build'
-p1090
+p968
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p1091
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1092
+p969
+sg76
+(lp970
+sg78
 S'vlc-android'
-p1093
-sg840
+p971
+sg80
+I00
+sg81
+(lp972
+sg83
+(lp973
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp974
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1094
-(lp1095
-S'no'
-p1096
-asS'ndk'
-p1097
+sg94
 S'r10d'
-p1098
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1099
+p975
+sg95
+Nsg96
+(lp976
+sg98
+S'VanillaX86'
+p977
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1100
-sg116
+p978
+sg102
 I00
-sS'commit'
-p1101
+sg103
 S'1.2.0'
-p1102
-sa(dp1103
-g64
+p979
+sa(dp980
+g54
 I00
-sg65
+sg55
 S'1020103'
-p1104
-sg283
+p981
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1105
-sg71
-g72
-sS'gradle'
-p1106
-(lp1107
-S'VanillaARMv6fpu'
-p1108
-asS'srclibs'
-p1109
-(lp1110
+sg59
+(lp982
+sg61
+I00
+sg62
+(lp983
+sg64
+(lp984
+sg66
 S'VLC@23c8d86'
-p1111
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p985
+sg68
+Nsg69
+(lp986
+sg71
+g24
+sg72
 S'1.2.1'
-p1112
-sS'build'
-p1113
+p987
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p1114
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1115
+p988
+sg76
+(lp989
+sg78
 S'vlc-android'
-p1116
-sg840
+p990
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp991
+sg83
+(lp992
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1117
-(lp1118
-S'no'
-p1119
-asS'ndk'
-p1120
+sg90
+Nsg91
+(lp993
+sg93
+I00
+sg94
 S'r10d'
-p1121
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1122
+p994
+sg95
+Nsg96
+(lp995
+sg98
+S'VanillaARMv6fpu'
+p996
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1123
-sg116
+p997
+sg102
 I00
-sS'commit'
-p1124
+sg103
 S'1.2.1'
-p1125
-sa(dp1126
-g64
+p998
+sa(dp999
+g54
 I00
-sg65
+sg55
 S'1020104'
-p1127
-sg283
+p1000
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1128
-sg71
-g72
-sS'gradle'
-p1129
-(lp1130
-S'VanillaARMv7'
-p1131
-asS'srclibs'
-p1132
-(lp1133
+sg59
+(lp1001
+sg61
+I00
+sg62
+(lp1002
+sg64
+(lp1003
+sg66
 S'VLC@23c8d86'
-p1134
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1004
+sg68
+Nsg69
+(lp1005
+sg71
+g24
+sg72
 S'1.2.1'
-p1135
-sS'build'
-p1136
+p1006
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p1137
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1138
+p1007
+sg76
+(lp1008
+sg78
 S'vlc-android'
-p1139
-sg840
+p1009
+sg80
+I00
+sg81
+(lp1010
+sg83
+(lp1011
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp1012
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1140
-(lp1141
-S'no'
-p1142
-asS'ndk'
-p1143
+sg94
 S'r10d'
-p1144
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1145
+p1013
+sg95
+Nsg96
+(lp1014
+sg98
+S'VanillaARMv7'
+p1015
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1146
-sg116
+p1016
+sg102
 I00
-sS'commit'
-p1147
+sg103
 S'1.2.1'
-p1148
-sa(dp1149
-g64
+p1017
+sa(dp1018
+g54
 I00
-sg65
+sg55
 S'1020105'
-p1150
-sg283
+p1019
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1151
-sg71
-g72
-sS'gradle'
-p1152
-(lp1153
-S'VanillaX86'
-p1154
-asS'srclibs'
-p1155
-(lp1156
+sg59
+(lp1020
+sg61
+I00
+sg62
+(lp1021
+sg64
+(lp1022
+sg66
 S'VLC@23c8d86'
-p1157
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1023
+sg68
+Nsg69
+(lp1024
+sg71
+g24
+sg72
 S'1.2.1'
-p1158
-sS'build'
-p1159
+p1025
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p1160
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1161
+p1026
+sg76
+(lp1027
+sg78
 S'vlc-android'
-p1162
-sg840
+p1028
+sg80
+I00
+sg81
+(lp1029
+sg83
+(lp1030
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp1031
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1163
-(lp1164
-S'no'
-p1165
-asS'ndk'
-p1166
+sg94
 S'r10d'
-p1167
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1168
+p1032
+sg95
+Nsg96
+(lp1033
+sg98
+S'VanillaX86'
+p1034
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1169
-sg116
+p1035
+sg102
 I00
-sS'commit'
-p1170
+sg103
 S'1.2.1'
-p1171
-sa(dp1172
-g64
+p1036
+sa(dp1037
+g54
 I00
-sg65
+sg55
 S'1020203'
-p1173
-sg283
+p1038
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1174
-sg71
-g72
-sS'gradle'
-p1175
-(lp1176
-S'VanillaARMv6fpu'
-p1177
-asS'srclibs'
-p1178
-(lp1179
+sg59
+(lp1039
+sg61
+I00
+sg62
+(lp1040
+sg64
+(lp1041
+sg66
 S'VLC@7491a5f'
-p1180
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1042
+sg68
+Nsg69
+(lp1043
+sg71
+g24
+sg72
 S'1.2.2'
-p1181
-sS'build'
-p1182
+p1044
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p1183
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1184
+p1045
+sg76
+(lp1046
+sg78
 S'vlc-android'
-p1185
-sg840
+p1047
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1048
+sg83
+(lp1049
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1186
-(lp1187
-S'no'
-p1188
-asS'ndk'
-p1189
+sg90
+Nsg91
+(lp1050
+sg93
+I00
+sg94
 S'r10d'
-p1190
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1191
+p1051
+sg95
+Nsg96
+(lp1052
+sg98
+S'VanillaARMv6fpu'
+p1053
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1192
-sg116
+p1054
+sg102
 I00
-sS'commit'
-p1193
+sg103
 S'1.2.2'
-p1194
-sa(dp1195
-g64
+p1055
+sa(dp1056
+g54
 I00
-sg65
+sg55
 S'1020204'
-p1196
-sg283
+p1057
+sg57
+I00
+sg58
 I00
-sg68
+sg59
+(lp1058
+sg61
 I00
-sg69
-(lp1197
-sg71
-g72
-sS'gradle'
-p1198
-(lp1199
-S'VanillaARMv7'
-p1200
-asS'srclibs'
-p1201
-(lp1202
+sg62
+(lp1059
+sg64
+(lp1060
+sg66
 S'VLC@7491a5f'
-p1203
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1061
+sg68
+Nsg69
+(lp1062
+sg71
+g24
+sg72
 S'1.2.2'
-p1204
-sS'build'
-p1205
+p1063
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p1206
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1207
+p1064
+sg76
+(lp1065
+sg78
 S'vlc-android'
-p1208
-sg840
+p1066
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1067
+sg83
+(lp1068
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1209
-(lp1210
-S'no'
-p1211
-asS'ndk'
-p1212
+sg90
+Nsg91
+(lp1069
+sg93
+I00
+sg94
 S'r10d'
-p1213
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1214
+p1070
+sg95
+Nsg96
+(lp1071
+sg98
+S'VanillaARMv7'
+p1072
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1215
-sg116
+p1073
+sg102
 I00
-sS'commit'
-p1216
+sg103
 S'1.2.2'
-p1217
-sa(dp1218
-g64
+p1074
+sa(dp1075
+g54
 I00
-sg65
+sg55
 S'1020205'
-p1219
-sg283
+p1076
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1220
-sg71
-g72
-sS'gradle'
-p1221
-(lp1222
-S'VanillaX86'
-p1223
-asS'srclibs'
-p1224
-(lp1225
+sg59
+(lp1077
+sg61
+I00
+sg62
+(lp1078
+sg64
+(lp1079
+sg66
 S'VLC@7491a5f'
-p1226
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1080
+sg68
+Nsg69
+(lp1081
+sg71
+g24
+sg72
 S'1.2.2'
-p1227
-sS'build'
-p1228
+p1082
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p1229
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1230
+p1083
+sg76
+(lp1084
+sg78
 S'vlc-android'
-p1231
-sg840
+p1085
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1086
+sg83
+(lp1087
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1232
-(lp1233
-S'no'
-p1234
-asS'ndk'
-p1235
+sg90
+Nsg91
+(lp1088
+sg93
+I00
+sg94
 S'r10d'
-p1236
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1237
+p1089
+sg95
+Nsg96
+(lp1090
+sg98
+S'VanillaX86'
+p1091
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1238
-sg116
+p1092
+sg102
 I00
-sS'commit'
-p1239
+sg103
 S'1.2.2'
-p1240
-sa(dp1241
-g64
+p1093
+sa(dp1094
+g54
 I00
-sg65
+sg55
 S'1020303'
-p1242
-sg283
+p1095
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1243
-sg71
-g72
-sS'gradle'
-p1244
-(lp1245
-S'VanillaARMv6fpu'
-p1246
-asS'srclibs'
-p1247
-(lp1248
+sg59
+(lp1096
+sg61
+I00
+sg62
+(lp1097
+sg64
+(lp1098
+sg66
 S'VLC@7491a5f'
-p1249
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1099
+sg68
+Nsg69
+(lp1100
+sg71
+g24
+sg72
 S'1.2.3'
-p1250
-sS'build'
-p1251
+p1101
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p1252
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1253
+p1102
+sg76
+(lp1103
+sg78
 S'vlc-android'
-p1254
-sg840
+p1104
+sg80
+I00
+sg81
+(lp1105
+sg83
+(lp1106
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp1107
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1255
-(lp1256
-S'no'
-p1257
-asS'ndk'
-p1258
+sg94
 S'r10d'
-p1259
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1260
+p1108
+sg95
+Nsg96
+(lp1109
+sg98
+S'VanillaARMv6fpu'
+p1110
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1261
-sg116
+p1111
+sg102
 I00
-sS'commit'
-p1262
+sg103
 S'1.2.3'
-p1263
-sa(dp1264
-g64
+p1112
+sa(dp1113
+g54
 I00
-sg65
+sg55
 S'1020304'
-p1265
-sg283
+p1114
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1266
-sg71
-g72
-sS'gradle'
-p1267
-(lp1268
-S'VanillaARMv7'
-p1269
-asS'srclibs'
-p1270
-(lp1271
+sg59
+(lp1115
+sg61
+I00
+sg62
+(lp1116
+sg64
+(lp1117
+sg66
 S'VLC@7491a5f'
-p1272
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1118
+sg68
+Nsg69
+(lp1119
+sg71
+g24
+sg72
 S'1.2.3'
-p1273
-sS'build'
-p1274
+p1120
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p1275
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1276
+p1121
+sg76
+(lp1122
+sg78
 S'vlc-android'
-p1277
-sg840
+p1123
+sg80
+I00
+sg81
+(lp1124
+sg83
+(lp1125
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp1126
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1278
-(lp1279
-S'no'
-p1280
-asS'ndk'
-p1281
+sg94
 S'r10d'
-p1282
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1283
+p1127
+sg95
+Nsg96
+(lp1128
+sg98
+S'VanillaARMv7'
+p1129
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1284
-sg116
+p1130
+sg102
 I00
-sS'commit'
-p1285
+sg103
 S'1.2.3'
-p1286
-sa(dp1287
-g64
+p1131
+sa(dp1132
+g54
 I00
-sg65
+sg55
 S'1020305'
-p1288
-sg283
+p1133
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1289
-sg71
-g72
-sS'gradle'
-p1290
-(lp1291
-S'VanillaX86'
-p1292
-asS'srclibs'
-p1293
-(lp1294
+sg59
+(lp1134
+sg61
+I00
+sg62
+(lp1135
+sg64
+(lp1136
+sg66
 S'VLC@7491a5f'
-p1295
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1137
+sg68
+Nsg69
+(lp1138
+sg71
+g24
+sg72
 S'1.2.3'
-p1296
-sS'build'
-p1297
+p1139
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p1298
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1299
+p1140
+sg76
+(lp1141
+sg78
 S'vlc-android'
-p1300
-sg840
+p1142
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1143
+sg83
+(lp1144
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1301
-(lp1302
-S'no'
-p1303
-asS'ndk'
-p1304
+sg90
+Nsg91
+(lp1145
+sg93
+I00
+sg94
 S'r10d'
-p1305
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1306
+p1146
+sg95
+Nsg96
+(lp1147
+sg98
+S'VanillaX86'
+p1148
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1307
-sg116
+p1149
+sg102
 I00
-sS'commit'
-p1308
+sg103
 S'1.2.3'
-p1309
-sa(dp1310
-g64
+p1150
+sa(dp1151
+g54
 I00
-sg65
+sg55
 S'1020403'
-p1311
-sg283
+p1152
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1312
-sg71
-g72
-sS'gradle'
-p1313
-(lp1314
-S'VanillaARMv6fpu'
-p1315
-asS'srclibs'
-p1316
-(lp1317
+sg59
+(lp1153
+sg61
+I00
+sg62
+(lp1154
+sg64
+(lp1155
+sg66
 S'VLC@7491a5f'
-p1318
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1156
+sg68
+Nsg69
+(lp1157
+sg71
+g24
+sg72
 S'1.2.4'
-p1319
-sS'build'
-p1320
+p1158
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p1321
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1322
+p1159
+sg76
+(lp1160
+sg78
 S'vlc-android'
-p1323
-sg840
+p1161
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1162
+sg83
+(lp1163
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1324
-(lp1325
-S'no'
-p1326
-asS'ndk'
-p1327
+sg90
+Nsg91
+(lp1164
+sg93
+I00
+sg94
 S'r10d'
-p1328
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1329
+p1165
+sg95
+Nsg96
+(lp1166
+sg98
+S'VanillaARMv6fpu'
+p1167
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1330
-sg116
+p1168
+sg102
 I00
-sS'commit'
-p1331
+sg103
 S'1.2.4'
-p1332
-sa(dp1333
-g64
+p1169
+sa(dp1170
+g54
 I00
-sg65
+sg55
 S'1020404'
-p1334
-sg283
+p1171
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1335
+sg59
+(lp1172
+sg61
+I00
+sg62
+(lp1173
+sg64
+(lp1174
+sg66
+S'VLC@7491a5f'
+p1175
+sg68
+Nsg69
+(lp1176
 sg71
-g72
-sS'gradle'
-p1336
-(lp1337
-S'VanillaARMv7'
-p1338
-asS'srclibs'
-p1339
-(lp1340
-S'VLC@7491a5f'
-p1341
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+g24
+sg72
 S'1.2.4'
-p1342
-sS'build'
-p1343
+p1177
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p1344
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1345
+p1178
+sg76
+(lp1179
+sg78
 S'vlc-android'
-p1346
-sg840
+p1180
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1181
+sg83
+(lp1182
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1347
-(lp1348
-S'no'
-p1349
-asS'ndk'
-p1350
+sg90
+Nsg91
+(lp1183
+sg93
+I00
+sg94
 S'r10d'
-p1351
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1352
+p1184
+sg95
+Nsg96
+(lp1185
+sg98
+S'VanillaARMv7'
+p1186
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1353
-sg116
+p1187
+sg102
 I00
-sS'commit'
-p1354
+sg103
 S'1.2.4'
-p1355
-sa(dp1356
-g64
+p1188
+sa(dp1189
+g54
 I00
-sg65
+sg55
 S'1020405'
-p1357
-sg283
+p1190
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1358
-sg71
-g72
-sS'gradle'
-p1359
-(lp1360
-S'VanillaX86'
-p1361
-asS'srclibs'
-p1362
-(lp1363
+sg59
+(lp1191
+sg61
+I00
+sg62
+(lp1192
+sg64
+(lp1193
+sg66
 S'VLC@7491a5f'
-p1364
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1194
+sg68
+Nsg69
+(lp1195
+sg71
+g24
+sg72
 S'1.2.4'
-p1365
-sS'build'
-p1366
+p1196
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p1367
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1368
+p1197
+sg76
+(lp1198
+sg78
 S'vlc-android'
-p1369
-sg840
+p1199
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1200
+sg83
+(lp1201
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1370
-(lp1371
-S'no'
-p1372
-asS'ndk'
-p1373
+sg90
+Nsg91
+(lp1202
+sg93
+I00
+sg94
 S'r10d'
-p1374
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1375
+p1203
+sg95
+Nsg96
+(lp1204
+sg98
+S'VanillaX86'
+p1205
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1376
-sg116
+p1206
+sg102
 I00
-sS'commit'
-p1377
+sg103
 S'1.2.4'
-p1378
-sa(dp1379
-g64
+p1207
+sa(dp1208
+g54
 I00
-sg65
+sg55
 S'1020503'
-p1380
-sg283
+p1209
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1381
-sg71
-g72
-sS'gradle'
-p1382
-(lp1383
-S'VanillaARMv6fpu'
-p1384
-asS'srclibs'
-p1385
-(lp1386
+sg59
+(lp1210
+sg61
+I00
+sg62
+(lp1211
+sg64
+(lp1212
+sg66
 S'VLC@50accb8'
-p1387
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1213
+sg68
+Nsg69
+(lp1214
+sg71
+g24
+sg72
 S'1.2.5'
-p1388
-sS'build'
-p1389
+p1215
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p1390
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1391
+p1216
+sg76
+(lp1217
+sg78
 S'vlc-android'
-p1392
-sg840
+p1218
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1219
+sg83
+(lp1220
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1393
-(lp1394
-S'no'
-p1395
-asS'ndk'
-p1396
+sg90
+Nsg91
+(lp1221
+sg93
+I00
+sg94
 S'r10d'
-p1397
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1398
+p1222
+sg95
+Nsg96
+(lp1223
+sg98
+S'VanillaARMv6fpu'
+p1224
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1399
-sg116
+p1225
+sg102
 I00
-sS'commit'
-p1400
+sg103
 S'1.2.5'
-p1401
-sa(dp1402
-g64
+p1226
+sa(dp1227
+g54
 I00
-sg65
+sg55
 S'1020504'
-p1403
-sg283
+p1228
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1404
-sg71
-g72
-sS'gradle'
-p1405
-(lp1406
-S'VanillaARMv7'
-p1407
-asS'srclibs'
-p1408
-(lp1409
+sg59
+(lp1229
+sg61
+I00
+sg62
+(lp1230
+sg64
+(lp1231
+sg66
 S'VLC@50accb8'
-p1410
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1232
+sg68
+Nsg69
+(lp1233
+sg71
+g24
+sg72
 S'1.2.5'
-p1411
-sS'build'
-p1412
+p1234
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p1413
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1414
+p1235
+sg76
+(lp1236
+sg78
 S'vlc-android'
-p1415
-sg840
+p1237
+sg80
+I00
+sg81
+(lp1238
+sg83
+(lp1239
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp1240
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1416
-(lp1417
-S'no'
-p1418
-asS'ndk'
-p1419
+sg94
 S'r10d'
-p1420
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1421
+p1241
+sg95
+Nsg96
+(lp1242
+sg98
+S'VanillaARMv7'
+p1243
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1422
-sg116
+p1244
+sg102
 I00
-sS'commit'
-p1423
+sg103
 S'1.2.5'
-p1424
-sa(dp1425
-g64
+p1245
+sa(dp1246
+g54
 I00
-sg65
+sg55
 S'1020505'
-p1426
-sg283
+p1247
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1427
-sg71
-g72
-sS'gradle'
-p1428
-(lp1429
-S'VanillaX86'
-p1430
-asS'srclibs'
-p1431
-(lp1432
+sg59
+(lp1248
+sg61
+I00
+sg62
+(lp1249
+sg64
+(lp1250
+sg66
 S'VLC@50accb8'
-p1433
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1251
+sg68
+Nsg69
+(lp1252
+sg71
+g24
+sg72
 S'1.2.5'
-p1434
-sS'build'
-p1435
+p1253
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p1436
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1437
+p1254
+sg76
+(lp1255
+sg78
 S'vlc-android'
-p1438
-sg840
+p1256
+sg80
+I00
+sg81
+(lp1257
+sg83
+(lp1258
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp1259
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1439
-(lp1440
-S'no'
-p1441
-asS'ndk'
-p1442
+sg94
 S'r10d'
-p1443
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1444
+p1260
+sg95
+Nsg96
+(lp1261
+sg98
+S'VanillaX86'
+p1262
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1445
-sg116
+p1263
+sg102
 I00
-sS'commit'
-p1446
+sg103
 S'1.2.5'
-p1447
-sa(dp1448
-g64
+p1264
+sa(dp1265
+g54
 I00
-sg65
+sg55
 S'1030003'
-p1449
-sg283
+p1266
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1450
-sg71
-g72
-sS'gradle'
-p1451
-(lp1452
-S'VanillaARMv6fpu'
-p1453
-asS'srclibs'
-p1454
-(lp1455
+sg59
+(lp1267
+sg61
+I00
+sg62
+(lp1268
+sg64
+(lp1269
+sg66
 S'VLC@d59b81a'
-p1456
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1270
+sg68
+Nsg69
+(lp1271
+sg71
+g24
+sg72
 S'1.2.6'
-p1457
-sS'build'
-p1458
+p1272
+sg74
 S'cd ../ && ./compile.sh -a "armeabi" --release'
-p1459
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1460
+p1273
+sg76
+(lp1274
+sg78
 S'vlc-android'
-p1461
-sg840
+p1275
+sg80
+I00
+sg81
+(lp1276
+sg83
+(lp1277
+sg88
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg89
 I00
-sg100
+sg90
+Nsg91
+(lp1278
+sg93
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1462
-(lp1463
-S'no'
-p1464
-asS'ndk'
-p1465
+sg94
 S'r10d'
-p1466
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1467
+p1279
+sg95
+Nsg96
+(lp1280
+sg98
+S'VanillaARMv6fpu'
+p1281
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1468
-sg116
+p1282
+sg102
 I00
-sS'commit'
-p1469
+sg103
 S'1.2.6'
-p1470
-sa(dp1471
-g64
+p1283
+sa(dp1284
+g54
 I00
-sg65
+sg55
 S'1030004'
-p1472
-sg283
+p1285
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1473
-sg71
-g72
-sS'gradle'
-p1474
-(lp1475
-S'VanillaARMv7'
-p1476
-asS'srclibs'
-p1477
-(lp1478
+sg59
+(lp1286
+sg61
+I00
+sg62
+(lp1287
+sg64
+(lp1288
+sg66
 S'VLC@d59b81a'
-p1479
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1289
+sg68
+Nsg69
+(lp1290
+sg71
+g24
+sg72
 S'1.2.6'
-p1480
-sS'build'
-p1481
+p1291
+sg74
 S'cd ../ && ./compile.sh -a "armeabi-v7a" --release'
-p1482
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1483
+p1292
+sg76
+(lp1293
+sg78
 S'vlc-android'
-p1484
-sg840
+p1294
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1295
+sg83
+(lp1296
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1485
-(lp1486
-S'no'
-p1487
-asS'ndk'
-p1488
+sg90
+Nsg91
+(lp1297
+sg93
+I00
+sg94
 S'r10d'
-p1489
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1490
+p1298
+sg95
+Nsg96
+(lp1299
+sg98
+S'VanillaARMv7'
+p1300
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1491
-sg116
+p1301
+sg102
 I00
-sS'commit'
-p1492
+sg103
 S'1.2.6'
-p1493
-sa(dp1494
-g64
+p1302
+sa(dp1303
+g54
 I00
-sg65
+sg55
 S'1030005'
-p1495
-sg283
+p1304
+sg57
 I00
-sg68
+sg58
 I00
-sg69
-(lp1496
-sg71
-g72
-sS'gradle'
-p1497
-(lp1498
-S'VanillaX86'
-p1499
-asS'srclibs'
-p1500
-(lp1501
+sg59
+(lp1305
+sg61
+I00
+sg62
+(lp1306
+sg64
+(lp1307
+sg66
 S'VLC@d59b81a'
-p1502
-asg77
-Nsg78
-Nsg79
-g80
-sg81
-g20
-sg82
+p1308
+sg68
+Nsg69
+(lp1309
+sg71
+g24
+sg72
 S'1.2.6'
-p1503
-sS'build'
-p1504
+p1310
+sg74
 S'cd ../ && ./compile.sh -a "x86" --release'
-p1505
-sg86
-g87
-sg88
-I00
-sS'subdir'
-p1506
+p1311
+sg76
+(lp1312
+sg78
 S'vlc-android'
-p1507
-sg840
+p1313
+sg80
 I00
-sg92
-g93
-sg200
-g201
-sg99
+sg81
+(lp1314
+sg83
+(lp1315
+sg88
 I00
-sg100
+sg89
 I00
-sg101
-g20
-sg102
-g103
-sS'buildjni'
-p1508
-(lp1509
-S'no'
-p1510
-asS'ndk'
-p1511
+sg90
+Nsg91
+(lp1316
+sg93
+I00
+sg94
 S'r10d'
-p1512
-sg109
-Nsg110
-g113
-sg112
-Nsg73
-g74
-sS'prebuild'
-p1513
+p1317
+sg95
+Nsg96
+(lp1318
+sg98
+S'VanillaX86'
+p1319
+sg100
 S'sed -i -e \'/^TARGET/aexit 0\' -e \'s@\\-d \\"gradle\\/wrapper\\"@1@g\' ../compile.sh && ln -s vlc-android/$$VLC$$ ../vlc'
-p1514
-sg116
+p1320
+sg102
 I00
-sS'commit'
-p1515
+sg103
 S'1.2.6'
-p1516
+p1321
 sasS'FlattrID'
-p1517
+p1322
 NsS'metadatapath'
-p1518
+p1323
 S'metadata/org.videolan.vlc.yaml'
-p1519
+p1324
 sS'Disabled'
-p1520
-NsS'Update Check Name'
-p1521
+p1325
+NsS'Web Site'
+p1326
+S'http://www.videolan.org/vlc/download-android.html'
+p1327
+sS'Update Check Name'
+p1328
 NsS'Vercode Operation'
-p1522
+p1329
 S'%c + 5'
-p1523
-sS'Current Version'
-p1524
-S'1.2.6'
-p1525
+p1330
+sS'Auto Update Mode'
+p1331
+S'None'
+p1332
 s.
\ No newline at end of file
diff --git a/tests/metadata/update-pickle.py b/tests/metadata/update-pickle.py
deleted file mode 100755 (executable)
index 2811133..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python2
-#
-# This script is for updating the .pickle test files when there are changes to
-# the default metadata, e.g. adding a new key/tag.
-
-import glob
-import pickle
-
-for picklefile in glob.glob('*.pickle'):
-    p = pickle.load(open(picklefile))
-
-    for build in p['builds']:
-        build['gradleprops'] = []
-
-    pickle.dump(p, open(picklefile, 'w'))
index ce1b0fd131edc06e68ee89e3ffdac765503c4274..da6dfde7c5455690474e2b8c2af508c156eed8dc 100755 (executable)
@@ -1,11 +1,9 @@
 #!/bin/bash
 
 set -e # quit script on error
-set -x # show each command as it is executed
 
 echo_header() {
-    echo "=============================================================================="
-    echo $1
+    { echo -e "==============================================================================\n$1"; } 2>/dev/null
 }
 
 copy_apks_into_repo() {
@@ -58,6 +56,10 @@ if [ -z "$ANDROID_HOME" ]; then
     exit 1
 fi
 
+if [ -d tests ]; then
+    cd tests
+fi
+
 if [ -z "$1" ]; then
     APKDIR=`pwd`
 else
@@ -84,6 +86,7 @@ if [ -z $python ]; then
     python=python2
 fi
 
+set -x # show each command as it is executed
 
 #------------------------------------------------------------------------------#
 echo_header "run commit hooks"