chiark / gitweb /
Add logging to verify
[fdroidserver.git] / fdroidserver / verify.py
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3 #
4 # verify.py - part of the FDroid server tools
5 # Copyright (C) 2013, Ciaran Gultnieks, ciaran@ciarang.com
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Affero General Public License for more details.
16 #
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 import sys
21 import os
22 import shutil
23 import subprocess
24 import glob
25 from optparse import OptionParser
26 import logging
27
28 import common
29 from common import FDroidPopen
30
31 options = None
32 config = None
33
34 def main():
35
36     global options, config
37
38     # Parse command line...
39     parser = OptionParser(usage="Usage: %prog [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]")
40     parser.add_option("-v", "--verbose", action="store_true", default=False,
41                       help="Spew out even more information than normal")
42     (options, args) = parser.parse_args()
43
44     config = common.read_config(options)
45
46     tmp_dir = 'tmp'
47     if not os.path.isdir(tmp_dir):
48         logging.info("Creating temporary directory")
49         os.makedirs(tmp_dir)
50
51     unsigned_dir = 'unsigned'
52     if not os.path.isdir(unsigned_dir):
53         logging.error("No unsigned directory - nothing to do")
54         sys.exit(0)
55
56     verified = 0
57     notverified = 0
58
59     vercodes = common.read_pkg_args(args, True)
60
61     for apkfile in sorted(glob.glob(os.path.join(unsigned_dir, '*.apk'))):
62
63         apkfilename = os.path.basename(apkfile)
64         appid, vercode = common.apknameinfo(apkfile)
65
66         if vercodes and appid not in vercodes:
67             continue
68         if vercodes[appid] and vercode not in vercodes[appid]:
69             continue
70
71         try:
72
73             logging.info("Processing " + apkfilename)
74
75             remoteapk = os.path.join(tmp_dir, apkfilename)
76             if os.path.exists(remoteapk):
77                 os.remove(remoteapk)
78             url = 'https://f-droid.org/repo/' + apkfilename
79             logging.info("...retrieving " + url)
80             p = FDroidPopen(['wget', url], cwd=tmp_dir)
81             if p.returncode != 0:
82                 raise Exception("Failed to get " + apkfilename)
83
84             thisdir = os.path.join(tmp_dir, 'this_apk')
85             thatdir = os.path.join(tmp_dir, 'that_apk')
86             for d in [thisdir, thatdir]:
87                 if os.path.exists(d):
88                     shutil.rmtree(d)
89                 os.mkdir(d)
90
91             if subprocess.call(['jar', 'xf',
92                 os.path.join("..", "..", unsigned_dir, apkfilename)],
93                 cwd=thisdir) != 0:
94                 raise Exception("Failed to unpack local build of " + apkfilename)
95             if subprocess.call(['jar', 'xf', os.path.join("..", "..", remoteapk)],
96                 cwd=thatdir) != 0:
97                 raise Exception("Failed to unpack remote build of " + apkfilename)
98
99             p = FDroidPopen(['diff', '-r', 'this_apk', 'that_apk'], cwd=tmp_dir)
100             lines = p.stdout.splitlines()
101             if len(lines) != 1 or 'META-INF' not in lines[0]:
102                 raise Exception("Unexpected diff output - " + p.stdout)
103
104             logging.info("...successfully verified")
105             verified += 1
106
107         except Exception, e:
108             logging.info("...NOT verified - {0}".format(e))
109             notverified += 1
110
111     logging.info("Finished")
112     print "{0} successfully verified".format(verified)
113     print "{0} NOT verified".format(notverified)
114
115 if __name__ == "__main__":
116     main()
117
118