mirror of
https://github.com/f-droid/fdroidserver.git
synced 2025-09-16 16:02:33 +03:00
Merge branch 'py3' into 'master'
Python 3 I tried to keep commits separate, so if anything causes trouble, it can be reverted or changed easily. * pre-commit hooks pass * all tests pass * My use of `build`, `checkupdates`, `lint`, `import`, `publish` and `update` work as usual * 2to3 does not report anything useful anymore (only useless parentheses and list() encapsulation of iterators) * rewritemeta works exactly as usual CC @eighthave See merge request !88
This commit is contained in:
commit
f267a1d7c9
38 changed files with 339 additions and 383 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -15,4 +15,4 @@ pylint.parseable
|
|||
docs/html/
|
||||
|
||||
# files generated by tests
|
||||
tests/getsig/tmp/
|
||||
tmp/
|
||||
|
|
|
@ -3,6 +3,7 @@ image: mvdan/fdroid-ci:latest
|
|||
test:
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install -y python-dev gcc
|
||||
- apt-get install -y python3-dev gcc
|
||||
- pip3 install -e .
|
||||
- cd tests
|
||||
- ./complete-ci-tests
|
||||
|
|
11
README.md
11
README.md
|
@ -23,8 +23,7 @@ install, and keep track of updates on your device.
|
|||
|
||||
### Installing
|
||||
|
||||
Note that only Python 2 is supported. We recommend version 2.7.7 or
|
||||
later.
|
||||
Note that only Python 3 is supported. We recommend version 3.4 or later.
|
||||
|
||||
The easiest way to install the `fdroidserver` tools is on Ubuntu, Mint or other
|
||||
Ubuntu based distributions, you can install using:
|
||||
|
@ -56,7 +55,7 @@ or Cygwin, you can use it:
|
|||
|
||||
Python's `pip` also works:
|
||||
|
||||
sudo pip install fdroidserver
|
||||
sudo pip3 install fdroidserver
|
||||
|
||||
The combination of `virtualenv` and `pip` is great for testing out the
|
||||
latest versions of `fdroidserver`. Using `pip`, `fdroidserver` can
|
||||
|
@ -67,7 +66,7 @@ via other mechanisms like Brew/dnf/pacman/emerge/Fink/MacPorts.
|
|||
|
||||
For Debian based distributions:
|
||||
|
||||
apt-get install python-dev python-pip python-virtualenv
|
||||
apt-get install python3-dev python3-pip virtualenv
|
||||
|
||||
Then here's how to install:
|
||||
|
||||
|
@ -75,5 +74,5 @@ Then here's how to install:
|
|||
cd fdroidserver
|
||||
virtualenv env/
|
||||
source env/bin/activate
|
||||
pip install -e .
|
||||
python2 setup.py install
|
||||
pip3 install -e .
|
||||
python3 setup.py install
|
||||
|
|
|
@ -83,9 +83,7 @@ intended usage. At the very least, you'll need:
|
|||
@item
|
||||
GNU/Linux
|
||||
@item
|
||||
Python 2.x
|
||||
To be sure of being able to process all apk files without error, you need
|
||||
2.7.7 or later. See @code{http://bugs.python.org/issue14315}.
|
||||
Python 3.4 or later
|
||||
@item
|
||||
The Android SDK Tools and Build-tools.
|
||||
Note that F-Droid does not assume that you have the Android SDK in your
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copy this file to config.py, then amend the settings below according to
|
||||
# your system configuration.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# You may want to alter these before running ./makebuildserver
|
||||
|
||||
|
|
3
fdroid
3
fdroid
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# fdroid.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-2015, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# build.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-2014, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -28,15 +27,15 @@ import tarfile
|
|||
import traceback
|
||||
import time
|
||||
import json
|
||||
from ConfigParser import ConfigParser
|
||||
from configparser import ConfigParser
|
||||
from argparse import ArgumentParser
|
||||
import logging
|
||||
|
||||
import common
|
||||
import net
|
||||
import metadata
|
||||
import scanner
|
||||
from common import FDroidException, BuildException, VCSException, FDroidPopen, SdkToolsPopen
|
||||
from . import common
|
||||
from . import net
|
||||
from . import metadata
|
||||
from . import scanner
|
||||
from .common import FDroidException, BuildException, VCSException, FDroidPopen, SdkToolsPopen
|
||||
|
||||
try:
|
||||
import paramiko
|
||||
|
@ -463,7 +462,7 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
|
|||
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():
|
||||
for k, v in config['ndk_paths'].items():
|
||||
if k.endswith("_orig"):
|
||||
continue
|
||||
logging.critical(" %s: %s" % (k, v))
|
||||
|
@ -1071,7 +1070,7 @@ def main():
|
|||
raise FDroidException("No apps to process.")
|
||||
|
||||
if options.latest:
|
||||
for app in apps.itervalues():
|
||||
for app in apps.values():
|
||||
for build in reversed(app.builds):
|
||||
if build.disable and not options.force:
|
||||
continue
|
||||
|
@ -1087,7 +1086,7 @@ def main():
|
|||
# Build applications...
|
||||
failed_apps = {}
|
||||
build_succeeded = []
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
|
||||
first = True
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# checkupdates.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-2015, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -21,20 +20,21 @@
|
|||
import sys
|
||||
import os
|
||||
import re
|
||||
import urllib2
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
import time
|
||||
import subprocess
|
||||
from argparse import ArgumentParser
|
||||
import traceback
|
||||
import HTMLParser
|
||||
from html.parser import HTMLParser
|
||||
from distutils.version import LooseVersion
|
||||
import logging
|
||||
import copy
|
||||
|
||||
import common
|
||||
import metadata
|
||||
from common import VCSException, FDroidException
|
||||
from metadata import MetaDataException
|
||||
from . import common
|
||||
from . import metadata
|
||||
from .common import VCSException, FDroidException
|
||||
from .metadata import MetaDataException
|
||||
|
||||
|
||||
# Check for a new version by looking at a document retrieved via HTTP.
|
||||
|
@ -52,8 +52,8 @@ def check_http(app):
|
|||
vercode = "99999999"
|
||||
if len(urlcode) > 0:
|
||||
logging.debug("...requesting {0}".format(urlcode))
|
||||
req = urllib2.Request(urlcode, None)
|
||||
resp = urllib2.urlopen(req, None, 20)
|
||||
req = urllib.request.Request(urlcode, None)
|
||||
resp = urllib.request.urlopen(req, None, 20)
|
||||
page = resp.read()
|
||||
|
||||
m = re.search(codeex, page)
|
||||
|
@ -65,8 +65,8 @@ def check_http(app):
|
|||
if len(urlver) > 0:
|
||||
if urlver != '.':
|
||||
logging.debug("...requesting {0}".format(urlver))
|
||||
req = urllib2.Request(urlver, None)
|
||||
resp = urllib2.urlopen(req, None, 20)
|
||||
req = urllib.request.Request(urlver, None)
|
||||
resp = urllib.request.urlopen(req, None, 20)
|
||||
page = resp.read()
|
||||
|
||||
m = re.search(verex, page)
|
||||
|
@ -280,11 +280,11 @@ def check_gplay(app):
|
|||
time.sleep(15)
|
||||
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)
|
||||
req = urllib.request.Request(url, None, headers)
|
||||
try:
|
||||
resp = urllib2.urlopen(req, None, 20)
|
||||
resp = urllib.request.urlopen(req, None, 20)
|
||||
page = resp.read()
|
||||
except urllib2.HTTPError as e:
|
||||
except urllib.error.HTTPError as e:
|
||||
return (None, str(e.code))
|
||||
except Exception as e:
|
||||
return (None, 'Failed:' + str(e))
|
||||
|
@ -293,7 +293,7 @@ def check_gplay(app):
|
|||
|
||||
m = re.search('itemprop="softwareVersion">[ ]*([^<]+)[ ]*</div>', page)
|
||||
if m:
|
||||
html_parser = HTMLParser.HTMLParser()
|
||||
html_parser = HTMLParser()
|
||||
version = html_parser.unescape(m.group(1))
|
||||
|
||||
if version == 'Varies with device':
|
||||
|
@ -559,7 +559,7 @@ def main():
|
|||
.format(common.getappname(app), version))
|
||||
return
|
||||
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
|
||||
if options.autoonly and app.AutoUpdateMode in ('None', 'Static'):
|
||||
logging.debug("Nothing to do for {0}...".format(appid))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# common.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-13, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -20,6 +20,7 @@
|
|||
# common.py is imported by all modules, so do not import third-party
|
||||
# libraries here as they will become a requirement for all commands.
|
||||
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
|
@ -32,19 +33,15 @@ import operator
|
|||
import logging
|
||||
import hashlib
|
||||
import socket
|
||||
import base64
|
||||
import xml.etree.ElementTree as XMLElementTree
|
||||
|
||||
try:
|
||||
# Python 2
|
||||
from Queue import Queue
|
||||
except ImportError:
|
||||
# Python 3
|
||||
from queue import Queue
|
||||
from queue import Queue
|
||||
|
||||
from zipfile import ZipFile
|
||||
|
||||
import metadata
|
||||
from fdroidserver.asynchronousfilereader import AsynchronousFileReader
|
||||
import fdroidserver.metadata
|
||||
from .asynchronousfilereader import AsynchronousFileReader
|
||||
|
||||
|
||||
XMLElementTree.register_namespace('android', 'http://schemas.android.com/apk/res/android')
|
||||
|
@ -206,7 +203,9 @@ def read_config(opts, config_file='config.py'):
|
|||
config = {}
|
||||
|
||||
logging.debug("Reading %s" % config_file)
|
||||
execfile(config_file, config)
|
||||
with io.open(config_file, "rb") as f:
|
||||
code = compile(f.read(), config_file, 'exec')
|
||||
exec(code, None, config)
|
||||
|
||||
# smartcardoptions must be a list since its command line args for Popen
|
||||
if 'smartcardoptions' in config:
|
||||
|
@ -244,9 +243,9 @@ def read_config(opts, config_file='config.py'):
|
|||
config[k] = clean_description(config[k])
|
||||
|
||||
if 'serverwebroot' in config:
|
||||
if isinstance(config['serverwebroot'], basestring):
|
||||
if isinstance(config['serverwebroot'], str):
|
||||
roots = [config['serverwebroot']]
|
||||
elif all(isinstance(item, basestring) for item in config['serverwebroot']):
|
||||
elif all(isinstance(item, str) for item in config['serverwebroot']):
|
||||
roots = config['serverwebroot']
|
||||
else:
|
||||
raise TypeError('only accepts strings, lists, and tuples')
|
||||
|
@ -339,9 +338,9 @@ def write_password_file(pwtype, password=None):
|
|||
filename = '.fdroid.' + pwtype + '.txt'
|
||||
fd = os.open(filename, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o600)
|
||||
if password is None:
|
||||
os.write(fd, config[pwtype])
|
||||
os.write(fd, config[pwtype].encode('utf-8'))
|
||||
else:
|
||||
os.write(fd, password)
|
||||
os.write(fd, password.encode('utf-8'))
|
||||
os.close(fd)
|
||||
config[pwtype + 'file'] = filename
|
||||
|
||||
|
@ -378,7 +377,7 @@ def read_app_args(args, allapps, allow_vercodes=False):
|
|||
return allapps
|
||||
|
||||
apps = {}
|
||||
for appid, app in allapps.iteritems():
|
||||
for appid, app in allapps.items():
|
||||
if appid in vercodes:
|
||||
apps[appid] = app
|
||||
|
||||
|
@ -391,7 +390,7 @@ def read_app_args(args, allapps, allow_vercodes=False):
|
|||
raise FDroidException("No packages specified")
|
||||
|
||||
error = False
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
vc = vercodes[appid]
|
||||
if not vc:
|
||||
continue
|
||||
|
@ -486,9 +485,9 @@ def getvcs(vcstype, remote, local):
|
|||
|
||||
|
||||
def getsrclibvcs(name):
|
||||
if name not in metadata.srclibs:
|
||||
if name not in fdroidserver.metadata.srclibs:
|
||||
raise VCSException("Missing srclib " + name)
|
||||
return metadata.srclibs[name]['Repo Type']
|
||||
return fdroidserver.metadata.srclibs[name]['Repo Type']
|
||||
|
||||
|
||||
class vcs:
|
||||
|
@ -532,6 +531,7 @@ class vcs:
|
|||
# automatically if either of those things changes.
|
||||
fdpath = os.path.join(self.local, '..',
|
||||
'.fdroidvcs-' + os.path.basename(self.local))
|
||||
fdpath = os.path.normpath(fdpath)
|
||||
cdata = self.repotype() + ' ' + self.remote
|
||||
writeback = True
|
||||
deleterepo = False
|
||||
|
@ -563,7 +563,8 @@ class vcs:
|
|||
|
||||
# If necessary, write the .fdroidvcs file.
|
||||
if writeback and not self.clone_failed:
|
||||
with open(fdpath, 'w') as f:
|
||||
os.makedirs(os.path.dirname(fdpath), exist_ok=True)
|
||||
with open(fdpath, 'w+') as f:
|
||||
f.write(cdata)
|
||||
|
||||
if exc is not None:
|
||||
|
@ -947,7 +948,7 @@ def retrieve_string(app_dir, string, xmlfiles=None):
|
|||
if element.text is None:
|
||||
return ""
|
||||
s = XMLElementTree.tostring(element, encoding='utf-8', method='text')
|
||||
return s.strip()
|
||||
return s.decode('utf-8').strip()
|
||||
|
||||
for path in xmlfiles:
|
||||
if not os.path.isfile(path):
|
||||
|
@ -995,7 +996,7 @@ def fetch_real_name(app_dir, flavours):
|
|||
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')
|
||||
label = app.attrib["{http://schemas.android.com/apk/res/android}label"]
|
||||
result = retrieve_string_singleline(app_dir, label)
|
||||
if result:
|
||||
result = result.strip()
|
||||
|
@ -1008,15 +1009,16 @@ def get_library_references(root_dir):
|
|||
proppath = os.path.join(root_dir, 'project.properties')
|
||||
if not os.path.isfile(proppath):
|
||||
return libraries
|
||||
for line in file(proppath):
|
||||
if not line.startswith('android.library.reference.'):
|
||||
continue
|
||||
path = line.split('=')[1].strip()
|
||||
relpath = os.path.join(root_dir, path)
|
||||
if not os.path.isdir(relpath):
|
||||
continue
|
||||
logging.debug("Found subproject at %s" % path)
|
||||
libraries.append(path)
|
||||
with open(proppath, 'r') as f:
|
||||
for line in f:
|
||||
if not line.startswith('android.library.reference.'):
|
||||
continue
|
||||
path = line.split('=')[1].strip()
|
||||
relpath = os.path.join(root_dir, path)
|
||||
if not os.path.isdir(relpath):
|
||||
continue
|
||||
logging.debug("Found subproject at %s" % path)
|
||||
libraries.append(path)
|
||||
return libraries
|
||||
|
||||
|
||||
|
@ -1082,38 +1084,39 @@ def parse_androidmanifests(paths, app):
|
|||
package = None
|
||||
|
||||
if gradle:
|
||||
for line in file(path):
|
||||
if gradle_comment.match(line):
|
||||
continue
|
||||
# Grab first occurence of each to avoid running into
|
||||
# alternative flavours and builds.
|
||||
if not package:
|
||||
matches = psearch_g(line)
|
||||
if matches:
|
||||
s = matches.group(2)
|
||||
if app_matches_packagename(app, s):
|
||||
package = s
|
||||
if not version:
|
||||
matches = vnsearch_g(line)
|
||||
if matches:
|
||||
version = matches.group(2)
|
||||
if not vercode:
|
||||
matches = vcsearch_g(line)
|
||||
if matches:
|
||||
vercode = matches.group(1)
|
||||
with open(path, 'r') as f:
|
||||
for line in f:
|
||||
if gradle_comment.match(line):
|
||||
continue
|
||||
# Grab first occurence of each to avoid running into
|
||||
# alternative flavours and builds.
|
||||
if not package:
|
||||
matches = psearch_g(line)
|
||||
if matches:
|
||||
s = matches.group(2)
|
||||
if app_matches_packagename(app, s):
|
||||
package = s
|
||||
if not version:
|
||||
matches = vnsearch_g(line)
|
||||
if matches:
|
||||
version = matches.group(2)
|
||||
if not vercode:
|
||||
matches = vcsearch_g(line)
|
||||
if matches:
|
||||
vercode = matches.group(1)
|
||||
else:
|
||||
try:
|
||||
xml = parse_xml(path)
|
||||
if "package" in xml.attrib:
|
||||
s = xml.attrib["package"].encode('utf-8')
|
||||
s = xml.attrib["package"]
|
||||
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')
|
||||
version = xml.attrib["{http://schemas.android.com/apk/res/android}versionName"]
|
||||
base_dir = os.path.dirname(path)
|
||||
version = retrieve_string_singleline(base_dir, version)
|
||||
if "{http://schemas.android.com/apk/res/android}versionCode" in xml.attrib:
|
||||
a = xml.attrib["{http://schemas.android.com/apk/res/android}versionCode"].encode('utf-8')
|
||||
a = xml.attrib["{http://schemas.android.com/apk/res/android}versionCode"]
|
||||
if string_is_integer(a):
|
||||
vercode = a
|
||||
except Exception:
|
||||
|
@ -1209,10 +1212,10 @@ def getsrclib(spec, srclib_dir, subdir=None, basepath=False,
|
|||
if '/' in name:
|
||||
name, subdir = name.split('/', 1)
|
||||
|
||||
if name not in metadata.srclibs:
|
||||
if name not in fdroidserver.metadata.srclibs:
|
||||
raise VCSException('srclib ' + name + ' not found.')
|
||||
|
||||
srclib = metadata.srclibs[name]
|
||||
srclib = fdroidserver.metadata.srclibs[name]
|
||||
|
||||
sdir = os.path.join(srclib_dir, name)
|
||||
|
||||
|
@ -1510,7 +1513,7 @@ def getpaths_map(build_dir, globpaths):
|
|||
def getpaths(build_dir, globpaths):
|
||||
paths_map = getpaths_map(build_dir, globpaths)
|
||||
paths = set()
|
||||
for k, v in paths_map.iteritems():
|
||||
for k, v in paths_map.items():
|
||||
for p in v:
|
||||
paths.add(p)
|
||||
return paths
|
||||
|
@ -1526,12 +1529,13 @@ class KnownApks:
|
|||
self.path = os.path.join('stats', 'known_apks.txt')
|
||||
self.apks = {}
|
||||
if os.path.isfile(self.path):
|
||||
for line in file(self.path):
|
||||
t = line.rstrip().split(' ')
|
||||
if len(t) == 2:
|
||||
self.apks[t[0]] = (t[1], None)
|
||||
else:
|
||||
self.apks[t[0]] = (t[1], time.strptime(t[2], '%Y-%m-%d'))
|
||||
with open(self.path, 'r') as f:
|
||||
for line in f:
|
||||
t = line.rstrip().split(' ')
|
||||
if len(t) == 2:
|
||||
self.apks[t[0]] = (t[1], None)
|
||||
else:
|
||||
self.apks[t[0]] = (t[1], time.strptime(t[2], '%Y-%m-%d'))
|
||||
self.changed = False
|
||||
|
||||
def writeifchanged(self):
|
||||
|
@ -1542,7 +1546,7 @@ class KnownApks:
|
|||
os.mkdir('stats')
|
||||
|
||||
lst = []
|
||||
for apk, app in self.apks.iteritems():
|
||||
for apk, app in self.apks.items():
|
||||
appid, added = app
|
||||
line = apk + ' ' + appid
|
||||
if added:
|
||||
|
@ -1573,7 +1577,7 @@ class KnownApks:
|
|||
# with the most recent first.
|
||||
def getlatest(self, num):
|
||||
apps = {}
|
||||
for apk, app in self.apks.iteritems():
|
||||
for apk, app in self.apks.items():
|
||||
appid, added = app
|
||||
if added:
|
||||
if appid in apps:
|
||||
|
@ -1581,7 +1585,7 @@ class KnownApks:
|
|||
apps[appid] = added
|
||||
else:
|
||||
apps[appid] = added
|
||||
sortedapps = sorted(apps.iteritems(), key=operator.itemgetter(1))[-num:]
|
||||
sortedapps = sorted(apps.items(), key=operator.itemgetter(1))[-num:]
|
||||
lst = [app for app, _ in sortedapps]
|
||||
lst.reverse()
|
||||
return lst
|
||||
|
@ -1604,8 +1608,9 @@ def isApkDebuggable(apkfile, config):
|
|||
|
||||
|
||||
class PopenResult:
|
||||
returncode = None
|
||||
output = ''
|
||||
def __init__(self):
|
||||
self.returncode = None
|
||||
self.output = None
|
||||
|
||||
|
||||
def SdkToolsPopen(commands, cwd=None, output=True):
|
||||
|
@ -1620,9 +1625,9 @@ def SdkToolsPopen(commands, cwd=None, output=True):
|
|||
cwd=cwd, output=output)
|
||||
|
||||
|
||||
def FDroidPopen(commands, cwd=None, output=True, stderr_to_stdout=True):
|
||||
def FDroidPopenBytes(commands, cwd=None, output=True, stderr_to_stdout=True):
|
||||
"""
|
||||
Run a command and capture the possibly huge output.
|
||||
Run a command and capture the possibly huge output as bytes.
|
||||
|
||||
:param commands: command and argument list like in subprocess.Popen
|
||||
:param cwd: optionally specifies a working directory
|
||||
|
@ -1653,13 +1658,14 @@ def FDroidPopen(commands, cwd=None, output=True, stderr_to_stdout=True):
|
|||
while not stderr_reader.eof():
|
||||
while not stderr_queue.empty():
|
||||
line = stderr_queue.get()
|
||||
sys.stderr.write(line)
|
||||
sys.stderr.buffer.write(line)
|
||||
sys.stderr.flush()
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
stdout_queue = Queue()
|
||||
stdout_reader = AsynchronousFileReader(p.stdout, stdout_queue)
|
||||
buf = io.BytesIO()
|
||||
|
||||
# Check the queue for output (until there is no more to get)
|
||||
while not stdout_reader.eof():
|
||||
|
@ -1667,13 +1673,28 @@ def FDroidPopen(commands, cwd=None, output=True, stderr_to_stdout=True):
|
|||
line = stdout_queue.get()
|
||||
if output and options.verbose:
|
||||
# Output directly to console
|
||||
sys.stderr.write(line)
|
||||
sys.stderr.buffer.write(line)
|
||||
sys.stderr.flush()
|
||||
result.output += line
|
||||
buf.write(line)
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
result.returncode = p.wait()
|
||||
result.output = buf.getvalue()
|
||||
buf.close()
|
||||
return result
|
||||
|
||||
|
||||
def FDroidPopen(commands, cwd=None, output=True, stderr_to_stdout=True):
|
||||
"""
|
||||
Run a command and capture the possibly huge output as a str.
|
||||
|
||||
:param commands: command and argument list like in subprocess.Popen
|
||||
:param cwd: optionally specifies a working directory
|
||||
:returns: A PopenResult.
|
||||
"""
|
||||
result = FDroidPopenBytes(commands, cwd, output, stderr_to_stdout)
|
||||
result.output = result.output.decode('utf-8')
|
||||
return result
|
||||
|
||||
|
||||
|
@ -1919,8 +1940,9 @@ def genpassword():
|
|||
'''generate a random password for when generating keys'''
|
||||
h = hashlib.sha256()
|
||||
h.update(os.urandom(16)) # salt
|
||||
h.update(bytes(socket.getfqdn()))
|
||||
return h.digest().encode('base64').strip()
|
||||
h.update(socket.getfqdn().encode('utf-8'))
|
||||
passwd = base64.b64encode(h.digest()).strip()
|
||||
return passwd.decode('utf-8')
|
||||
|
||||
|
||||
def genkeystore(localconfig):
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# gpgsign.py - part of the FDroid server tools
|
||||
# Copyright (C) 2014, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -23,8 +22,8 @@ import glob
|
|||
from argparse import ArgumentParser
|
||||
import logging
|
||||
|
||||
import common
|
||||
from common import FDroidPopen
|
||||
from . import common
|
||||
from .common import FDroidPopen
|
||||
|
||||
config = None
|
||||
options = None
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# import.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-13, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -21,12 +20,13 @@
|
|||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import urllib
|
||||
import urllib.request
|
||||
from argparse import ArgumentParser
|
||||
from ConfigParser import ConfigParser
|
||||
from configparser import ConfigParser
|
||||
import logging
|
||||
import common
|
||||
import metadata
|
||||
|
||||
from . import common
|
||||
from . import metadata
|
||||
|
||||
|
||||
# Get the repo type and address from the given web page. The page is scanned
|
||||
|
@ -35,7 +35,7 @@ import metadata
|
|||
# Returns repotype, address, or None, reason
|
||||
def getrepofrompage(url):
|
||||
|
||||
req = urllib.urlopen(url)
|
||||
req = urllib.request.urlopen(url)
|
||||
if req.getcode() != 200:
|
||||
return (None, 'Unable to get ' + url + ' - return code ' + str(req.getcode()))
|
||||
page = req.read()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# update.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-2013, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -28,7 +27,7 @@ import sys
|
|||
from argparse import ArgumentParser
|
||||
import logging
|
||||
|
||||
import common
|
||||
from . import common
|
||||
|
||||
config = {}
|
||||
options = None
|
||||
|
@ -103,8 +102,8 @@ def main():
|
|||
default_sdk_path = '/opt/android-sdk'
|
||||
while not options.no_prompt:
|
||||
try:
|
||||
s = raw_input('Enter the path to the Android SDK ('
|
||||
+ default_sdk_path + ') here:\n> ')
|
||||
s = input('Enter the path to the Android SDK ('
|
||||
+ default_sdk_path + ') here:\n> ')
|
||||
except KeyboardInterrupt:
|
||||
print('')
|
||||
sys.exit(1)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# install.py - part of the FDroid server tools
|
||||
# Copyright (C) 2013, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -24,8 +23,8 @@ import glob
|
|||
from argparse import ArgumentParser
|
||||
import logging
|
||||
|
||||
import common
|
||||
from common import SdkToolsPopen, FDroidException
|
||||
from . import common
|
||||
from .common import SdkToolsPopen, FDroidException
|
||||
|
||||
options = None
|
||||
config = None
|
||||
|
@ -82,7 +81,7 @@ def main():
|
|||
continue
|
||||
apks[appid] = apkfile
|
||||
|
||||
for appid, apk in apks.iteritems():
|
||||
for appid, apk in apks.items():
|
||||
if not apk:
|
||||
raise FDroidException("No signed apk available for %s" % appid)
|
||||
|
||||
|
@ -91,7 +90,7 @@ def main():
|
|||
apks = {common.apknameinfo(apkfile)[0]: apkfile for apkfile in
|
||||
sorted(glob.glob(os.path.join(output_dir, '*.apk')))}
|
||||
|
||||
for appid, apk in apks.iteritems():
|
||||
for appid, apk in apks.items():
|
||||
# Get device list each time to avoid device not found errors
|
||||
devs = devices()
|
||||
if not devs:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# lint.py - part of the FDroid server tool
|
||||
# Copyright (C) 2013-2014 Daniel Martí <mvdan@mvdan.cc>
|
||||
|
@ -20,11 +19,10 @@
|
|||
from argparse import ArgumentParser
|
||||
import re
|
||||
import sys
|
||||
from sets import Set
|
||||
|
||||
import common
|
||||
import metadata
|
||||
import rewritemeta
|
||||
from . import common
|
||||
from . import metadata
|
||||
from . import rewritemeta
|
||||
|
||||
config = None
|
||||
options = None
|
||||
|
@ -118,7 +116,7 @@ regex_checks = {
|
|||
|
||||
|
||||
def check_regexes(app):
|
||||
for f, checks in regex_checks.iteritems():
|
||||
for f, checks in regex_checks.items():
|
||||
for m, r in checks:
|
||||
v = app.get_field(f)
|
||||
t = metadata.fieldtype(f)
|
||||
|
@ -205,7 +203,7 @@ def check_empty_fields(app):
|
|||
if not app.Categories:
|
||||
yield "Categories are not set"
|
||||
|
||||
all_categories = Set([
|
||||
all_categories = set([
|
||||
"Connectivity",
|
||||
"Development",
|
||||
"Games",
|
||||
|
@ -333,7 +331,7 @@ def main():
|
|||
allapps = metadata.read_metadata(xref=True)
|
||||
apps = common.read_app_args(options.appid, allapps, False)
|
||||
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
if app.Disabled:
|
||||
continue
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# metadata.py - part of the FDroid server tools
|
||||
# Copyright (C) 2013, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -23,11 +23,7 @@ import re
|
|||
import glob
|
||||
import cgi
|
||||
import textwrap
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except:
|
||||
from StringIO import StringIO
|
||||
import io
|
||||
|
||||
import yaml
|
||||
# use libyaml if it is available
|
||||
|
@ -41,7 +37,7 @@ except ImportError:
|
|||
# use the C implementation when available
|
||||
import xml.etree.cElementTree as ElementTree
|
||||
|
||||
import common
|
||||
import fdroidserver.common
|
||||
|
||||
srclibs = None
|
||||
|
||||
|
@ -162,11 +158,11 @@ class App():
|
|||
# names. Should only be used for tests.
|
||||
def field_dict(self):
|
||||
d = {}
|
||||
for k, v in self.__dict__.iteritems():
|
||||
for k, v in self.__dict__.items():
|
||||
if k == 'builds':
|
||||
d['builds'] = []
|
||||
for build in v:
|
||||
b = {k: v for k, v in build.__dict__.iteritems() if not k.startswith('_')}
|
||||
b = {k: v for k, v in build.__dict__.items() if not k.startswith('_')}
|
||||
d['builds'].append(b)
|
||||
elif not k.startswith('_'):
|
||||
f = App.attr_to_field(k)
|
||||
|
@ -200,7 +196,7 @@ class App():
|
|||
|
||||
# Like dict.update(), but using human-readable field names
|
||||
def update_fields(self, d):
|
||||
for f, v in d.iteritems():
|
||||
for f, v in d.items():
|
||||
if f == 'builds':
|
||||
for b in v:
|
||||
build = Build()
|
||||
|
@ -352,13 +348,13 @@ class Build():
|
|||
version = self.ndk
|
||||
if not version:
|
||||
version = 'r10e' # falls back to latest
|
||||
paths = common.config['ndk_paths']
|
||||
paths = fdroidserver.common.config['ndk_paths']
|
||||
if version not in paths:
|
||||
return ''
|
||||
return paths[version]
|
||||
|
||||
def update_flags(self, d):
|
||||
for f, v in d.iteritems():
|
||||
for f, v in d.items():
|
||||
self.set_flag(f, v)
|
||||
|
||||
flagtypes = {
|
||||
|
@ -513,8 +509,8 @@ class DescriptionFormatter:
|
|||
self.laststate = self.stNONE
|
||||
self.text_html = ''
|
||||
self.text_txt = ''
|
||||
self.html = StringIO()
|
||||
self.text = StringIO()
|
||||
self.html = io.StringIO()
|
||||
self.text = io.StringIO()
|
||||
self.para_lines = []
|
||||
self.linkResolver = None
|
||||
self.linkResolver = linkres
|
||||
|
@ -534,10 +530,10 @@ class DescriptionFormatter:
|
|||
self.state = self.stNONE
|
||||
whole_para = ' '.join(self.para_lines)
|
||||
self.addtext(whole_para)
|
||||
wrapped = textwrap.fill(whole_para.decode('utf-8'), 80,
|
||||
wrapped = textwrap.fill(whole_para, 80,
|
||||
break_long_words=False,
|
||||
break_on_hyphens=False)
|
||||
self.text.write(wrapped.encode('utf-8'))
|
||||
self.text.write(wrapped)
|
||||
self.html.write('</p>')
|
||||
del self.para_lines[:]
|
||||
|
||||
|
@ -709,7 +705,7 @@ def parse_srclib(metadatapath):
|
|||
if not os.path.exists(metadatapath):
|
||||
return thisinfo
|
||||
|
||||
metafile = open(metadatapath, "r")
|
||||
metafile = open(metadatapath, "r", encoding='utf-8')
|
||||
|
||||
n = 0
|
||||
for line in metafile:
|
||||
|
@ -797,7 +793,7 @@ def read_metadata(xref=True):
|
|||
return ("fdroid.app:" + appid, "Dummy name - don't know yet")
|
||||
raise MetaDataException("Cannot resolve app id " + appid)
|
||||
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
try:
|
||||
description_html(app.Description, linkres)
|
||||
except MetaDataException as e:
|
||||
|
@ -826,7 +822,7 @@ def get_default_app_info(metadatapath=None):
|
|||
if metadatapath is None:
|
||||
appid = None
|
||||
else:
|
||||
appid, _ = common.get_extension(os.path.basename(metadatapath))
|
||||
appid, _ = fdroidserver.common.get_extension(os.path.basename(metadatapath))
|
||||
|
||||
app = App()
|
||||
app.metadatapath = metadatapath
|
||||
|
@ -846,17 +842,14 @@ esc_newlines = re.compile(r'\\( |\n)')
|
|||
# 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
|
||||
for k in app._modified:
|
||||
v = app.__dict__[k]
|
||||
if type(v) in (float, int):
|
||||
app.__dict__[k] = str(v)
|
||||
|
||||
for build in app.builds:
|
||||
for k, v in build.__dict__.iteritems():
|
||||
|
||||
if k not in build._modified:
|
||||
continue
|
||||
for k in build._modified:
|
||||
v = build.__dict__[k]
|
||||
if type(v) in (float, int):
|
||||
build.__dict__[k] = str(v)
|
||||
continue
|
||||
|
@ -866,7 +859,7 @@ def post_metadata_parse(app):
|
|||
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):
|
||||
if isinstance(v, str):
|
||||
build.__dict__[k] = _decode_bool(v)
|
||||
elif ftype == TYPE_STRING:
|
||||
if isinstance(v, bool) and v:
|
||||
|
@ -904,36 +897,6 @@ def post_metadata_parse(app):
|
|||
#
|
||||
|
||||
|
||||
def _decode_list(data):
|
||||
'''convert items in a list from unicode to basestring'''
|
||||
rv = []
|
||||
for item in data:
|
||||
if isinstance(item, unicode):
|
||||
item = item.encode('utf-8')
|
||||
elif isinstance(item, list):
|
||||
item = _decode_list(item)
|
||||
elif isinstance(item, dict):
|
||||
item = _decode_dict(item)
|
||||
rv.append(item)
|
||||
return rv
|
||||
|
||||
|
||||
def _decode_dict(data):
|
||||
'''convert items in a dict from unicode to basestring'''
|
||||
rv = {}
|
||||
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
|
||||
|
||||
|
||||
bool_true = re.compile(r'([Yy]es|[Tt]rue)')
|
||||
bool_false = re.compile(r'([Nn]o|[Ff]alse)')
|
||||
|
||||
|
@ -947,17 +910,17 @@ def _decode_bool(s):
|
|||
|
||||
|
||||
def parse_metadata(metadatapath):
|
||||
_, ext = common.get_extension(metadatapath)
|
||||
accepted = common.config['accepted_formats']
|
||||
_, ext = fdroidserver.common.get_extension(metadatapath)
|
||||
accepted = fdroidserver.common.config['accepted_formats']
|
||||
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))
|
||||
app.id, _ = fdroidserver.common.get_extension(os.path.basename(metadatapath))
|
||||
|
||||
with open(metadatapath, 'r') as mf:
|
||||
with open(metadatapath, 'r', encoding='utf-8') as mf:
|
||||
if ext == 'txt':
|
||||
parse_txt_metadata(mf, app)
|
||||
elif ext == 'json':
|
||||
|
@ -975,11 +938,9 @@ def parse_metadata(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
|
||||
# fdroid metadata is only strings and booleans, no floats or ints.
|
||||
# TODO create schema using https://pypi.python.org/pypi/jsonschema
|
||||
jsoninfo = json.load(mf, object_hook=_decode_dict,
|
||||
parse_int=lambda s: s,
|
||||
jsoninfo = json.load(mf, parse_int=lambda s: s,
|
||||
parse_float=lambda s: s)
|
||||
app.update_fields(jsoninfo)
|
||||
for f in ['Description', 'Maintainer Notes']:
|
||||
|
@ -1253,7 +1214,7 @@ def write_plaintext_metadata(mf, app, w_comment, w_field, w_build):
|
|||
w_field_always('Binaries')
|
||||
mf.write('\n')
|
||||
|
||||
for build in sorted_builds(app.builds):
|
||||
for build in app.builds:
|
||||
|
||||
if build.version == "Ignore":
|
||||
continue
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# net.py - part of the FDroid server tools
|
||||
# Copyright (C) 2015 Hans-Christoph Steiner <hans@eds.org>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# publish.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-13, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -21,14 +20,14 @@
|
|||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import md5
|
||||
import glob
|
||||
import hashlib
|
||||
from argparse import ArgumentParser
|
||||
import logging
|
||||
|
||||
import common
|
||||
import metadata
|
||||
from common import FDroidPopen, SdkToolsPopen, BuildException
|
||||
from . import common
|
||||
from . import metadata
|
||||
from .common import FDroidPopen, SdkToolsPopen, BuildException
|
||||
|
||||
config = None
|
||||
options = None
|
||||
|
@ -91,8 +90,8 @@ def main():
|
|||
vercodes = common.read_pkg_args(options.appid, True)
|
||||
allaliases = []
|
||||
for appid in allapps:
|
||||
m = md5.new()
|
||||
m.update(appid)
|
||||
m = hashlib.md5()
|
||||
m.update(appid.encode('utf-8'))
|
||||
keyalias = m.hexdigest()[:8]
|
||||
if keyalias in allaliases:
|
||||
logging.error("There is a keyalias collision - publishing halted")
|
||||
|
@ -156,12 +155,12 @@ def main():
|
|||
# For this particular app, the key alias is overridden...
|
||||
keyalias = config['keyaliases'][appid]
|
||||
if keyalias.startswith('@'):
|
||||
m = md5.new()
|
||||
m.update(keyalias[1:])
|
||||
m = hashlib.md5()
|
||||
m.update(keyalias[1:].encode('utf-8'))
|
||||
keyalias = m.hexdigest()[:8]
|
||||
else:
|
||||
m = md5.new()
|
||||
m.update(appid)
|
||||
m = hashlib.md5()
|
||||
m.update(appid.encode('utf-8'))
|
||||
keyalias = m.hexdigest()[:8]
|
||||
logging.info("Key alias: " + keyalias)
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# readmeta.py - part of the FDroid server tools
|
||||
# Copyright (C) 2014 Daniel Martí <mvdan@mvdan.cc>
|
||||
|
@ -18,8 +17,8 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from argparse import ArgumentParser
|
||||
import common
|
||||
import metadata
|
||||
from . import common
|
||||
from . import metadata
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# rewritemeta.py - part of the FDroid server tools
|
||||
# This cleans up the original .txt metadata file format.
|
||||
|
@ -21,20 +20,17 @@
|
|||
from argparse import ArgumentParser
|
||||
import os
|
||||
import logging
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except:
|
||||
from StringIO import StringIO
|
||||
import io
|
||||
|
||||
import common
|
||||
import metadata
|
||||
from . import common
|
||||
from . import metadata
|
||||
|
||||
config = None
|
||||
options = None
|
||||
|
||||
|
||||
def proper_format(app):
|
||||
s = StringIO()
|
||||
s = io.StringIO()
|
||||
# TODO: currently reading entire file again, should reuse first
|
||||
# read in metadata.py
|
||||
with open(app.metadatapath, 'r') as f:
|
||||
|
@ -73,7 +69,7 @@ def main():
|
|||
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():
|
||||
for appid, app in apps.items():
|
||||
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))
|
||||
|
@ -85,7 +81,7 @@ def main():
|
|||
|
||||
if options.list:
|
||||
if not proper_format(app):
|
||||
print app.metadatapath
|
||||
print(app.metadatapath)
|
||||
continue
|
||||
|
||||
with open(base + '.' + to_ext, 'w') as f:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# scanner.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-13, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -23,9 +22,9 @@ import traceback
|
|||
from argparse import ArgumentParser
|
||||
import logging
|
||||
|
||||
import common
|
||||
import metadata
|
||||
from common import BuildException, VCSException
|
||||
from . import common
|
||||
from . import metadata
|
||||
from .common import BuildException, VCSException
|
||||
|
||||
config = None
|
||||
options = None
|
||||
|
@ -68,7 +67,7 @@ def scan_source(build_dir, root_dir, build):
|
|||
}
|
||||
|
||||
def suspects_found(s):
|
||||
for n, r in usual_suspects.iteritems():
|
||||
for n, r in usual_suspects.items():
|
||||
if r.match(s):
|
||||
yield n
|
||||
|
||||
|
@ -95,7 +94,7 @@ def scan_source(build_dir, root_dir, build):
|
|||
scandelete_worked = set()
|
||||
|
||||
def toignore(fd):
|
||||
for k, paths in scanignore.iteritems():
|
||||
for k, paths in scanignore.items():
|
||||
for p in paths:
|
||||
if fd.startswith(p):
|
||||
scanignore_worked.add(k)
|
||||
|
@ -103,7 +102,7 @@ def scan_source(build_dir, root_dir, build):
|
|||
return False
|
||||
|
||||
def todelete(fd):
|
||||
for k, paths in scandelete.iteritems():
|
||||
for k, paths in scandelete.items():
|
||||
for p in paths:
|
||||
if fd.startswith(p):
|
||||
scandelete_worked.add(k)
|
||||
|
@ -200,10 +199,11 @@ def scan_source(build_dir, root_dir, build):
|
|||
elif ext == 'java':
|
||||
if not os.path.isfile(fp):
|
||||
continue
|
||||
for line in file(fp):
|
||||
if 'DexClassLoader' in line:
|
||||
count += handleproblem('DexClassLoader', fd, fp)
|
||||
break
|
||||
with open(fp, 'r') as f:
|
||||
for line in f:
|
||||
if 'DexClassLoader' in line:
|
||||
count += handleproblem('DexClassLoader', fd, fp)
|
||||
break
|
||||
|
||||
elif ext == 'gradle':
|
||||
if not os.path.isfile(fp):
|
||||
|
@ -267,7 +267,7 @@ def main():
|
|||
srclib_dir = os.path.join(build_dir, 'srclib')
|
||||
extlib_dir = os.path.join(build_dir, 'extlib')
|
||||
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
|
||||
if app.Disabled:
|
||||
logging.info("Skipping %s: disabled" % appid)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# server.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-15, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -26,7 +25,8 @@ import pwd
|
|||
import subprocess
|
||||
from argparse import ArgumentParser
|
||||
import logging
|
||||
import common
|
||||
|
||||
from . import common
|
||||
|
||||
config = None
|
||||
options = None
|
||||
|
@ -296,12 +296,12 @@ def main():
|
|||
sftp = ssh.open_sftp()
|
||||
if os.path.basename(remotepath) \
|
||||
not in sftp.listdir(os.path.dirname(remotepath)):
|
||||
sftp.mkdir(remotepath, mode=0755)
|
||||
sftp.mkdir(remotepath, mode=0o755)
|
||||
for repo_section in repo_sections:
|
||||
repo_path = os.path.join(remotepath, repo_section)
|
||||
if os.path.basename(repo_path) \
|
||||
not in sftp.listdir(remotepath):
|
||||
sftp.mkdir(repo_path, mode=0755)
|
||||
sftp.mkdir(repo_path, mode=0o755)
|
||||
sftp.close()
|
||||
ssh.close()
|
||||
elif options.command == 'update':
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# gpgsign.py - part of the FDroid server tools
|
||||
# Copyright (C) 2015, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -22,8 +21,8 @@ import os
|
|||
from argparse import ArgumentParser
|
||||
import logging
|
||||
|
||||
import common
|
||||
from common import FDroidPopen
|
||||
from . import common
|
||||
from .common import FDroidPopen
|
||||
|
||||
config = None
|
||||
options = None
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# stats.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-13, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -28,11 +27,12 @@ from argparse import ArgumentParser
|
|||
import paramiko
|
||||
import socket
|
||||
import logging
|
||||
import common
|
||||
import metadata
|
||||
import subprocess
|
||||
from collections import Counter
|
||||
|
||||
from . import common
|
||||
from . import metadata
|
||||
|
||||
|
||||
def carbon_send(key, value):
|
||||
s = socket.socket()
|
||||
|
@ -75,7 +75,7 @@ def main():
|
|||
sys.exit(1)
|
||||
|
||||
# Get all metadata-defined apps...
|
||||
allmetaapps = [app for app in metadata.read_metadata().itervalues()]
|
||||
allmetaapps = [app for app in metadata.read_metadata().values()]
|
||||
metaapps = [app for app in allmetaapps if not app.Disabled]
|
||||
|
||||
statsdir = 'stats'
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# update.py - part of the FDroid server tools
|
||||
# Copyright (C) 2010-2015, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -27,7 +26,7 @@ import socket
|
|||
import zipfile
|
||||
import hashlib
|
||||
import pickle
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
from datetime import datetime, timedelta
|
||||
from xml.dom.minidom import Document
|
||||
from argparse import ArgumentParser
|
||||
|
@ -35,16 +34,15 @@ import time
|
|||
from pyasn1.error import PyAsn1Error
|
||||
from pyasn1.codec.der import decoder, encoder
|
||||
from pyasn1_modules import rfc2315
|
||||
from hashlib import md5
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
from PIL import Image
|
||||
import logging
|
||||
|
||||
import common
|
||||
import metadata
|
||||
from common import FDroidPopen, SdkToolsPopen
|
||||
from metadata import MetaDataException
|
||||
from . import common
|
||||
from . import metadata
|
||||
from .common import FDroidPopen, FDroidPopenBytes, SdkToolsPopen
|
||||
from .metadata import MetaDataException
|
||||
|
||||
screen_densities = ['640', '480', '320', '240', '160', '120']
|
||||
|
||||
|
@ -292,7 +290,7 @@ def delete_disabled_builds(apps, apkcache, repodirs):
|
|||
:param apkcache: current apk cache information
|
||||
:param repodirs: the repo directories to process
|
||||
"""
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
for build in app.builds:
|
||||
if not build.disable:
|
||||
continue
|
||||
|
@ -402,7 +400,7 @@ def getsig(apkpath):
|
|||
|
||||
cert_encoded = encoder.encode(certificates)[4:]
|
||||
|
||||
return md5(cert_encoded.encode('hex')).hexdigest()
|
||||
return hashlib.md5(hexlify(cert_encoded)).hexdigest()
|
||||
|
||||
|
||||
def scan_apks(apps, apkcache, repodir, knownapks, use_date_from_apk=False):
|
||||
|
@ -713,7 +711,7 @@ repo_pubkey_fingerprint = None
|
|||
def cert_fingerprint(data):
|
||||
digest = hashlib.sha256(data).digest()
|
||||
ret = []
|
||||
ret.append(' '.join("%02X" % ord(b) for b in digest))
|
||||
ret.append(' '.join("%02X" % b for b in bytearray(digest)))
|
||||
return " ".join(ret)
|
||||
|
||||
|
||||
|
@ -722,12 +720,12 @@ def extract_pubkey():
|
|||
if 'repo_pubkey' in config:
|
||||
pubkey = unhexlify(config['repo_pubkey'])
|
||||
else:
|
||||
p = FDroidPopen([config['keytool'], '-exportcert',
|
||||
'-alias', config['repo_keyalias'],
|
||||
'-keystore', config['keystore'],
|
||||
'-storepass:file', config['keystorepassfile']]
|
||||
+ config['smartcardoptions'],
|
||||
output=False, stderr_to_stdout=False)
|
||||
p = FDroidPopenBytes([config['keytool'], '-exportcert',
|
||||
'-alias', config['repo_keyalias'],
|
||||
'-keystore', config['keystore'],
|
||||
'-storepass:file', config['keystorepassfile']]
|
||||
+ config['smartcardoptions'],
|
||||
output=False, stderr_to_stdout=False)
|
||||
if p.returncode != 0 or len(p.output) < 20:
|
||||
msg = "Failed to get repo pubkey!"
|
||||
if config['keystore'] == 'NONE':
|
||||
|
@ -774,7 +772,7 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
|
|||
|
||||
mirrorcheckfailed = False
|
||||
for mirror in config.get('mirrors', []):
|
||||
base = os.path.basename(urlparse.urlparse(mirror).path.rstrip('/'))
|
||||
base = os.path.basename(urllib.parse.urlparse(mirror).path.rstrip('/'))
|
||||
if config.get('nonstandardwebroot') is not True and base != 'fdroid':
|
||||
logging.error("mirror '" + mirror + "' does not end with 'fdroid'!")
|
||||
mirrorcheckfailed = True
|
||||
|
@ -788,9 +786,9 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
|
|||
repoel.setAttribute("icon", os.path.basename(config['archive_icon']))
|
||||
repoel.setAttribute("url", config['archive_url'])
|
||||
addElement('description', config['archive_description'], doc, repoel)
|
||||
urlbasepath = os.path.basename(urlparse.urlparse(config['archive_url']).path)
|
||||
urlbasepath = os.path.basename(urllib.parse.urlparse(config['archive_url']).path)
|
||||
for mirror in config.get('mirrors', []):
|
||||
addElement('mirror', urlparse.urljoin(mirror, urlbasepath), doc, repoel)
|
||||
addElement('mirror', urllib.parse.urljoin(mirror, urlbasepath), doc, repoel)
|
||||
|
||||
else:
|
||||
repoel.setAttribute("name", config['repo_name'])
|
||||
|
@ -799,9 +797,9 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
|
|||
repoel.setAttribute("icon", os.path.basename(config['repo_icon']))
|
||||
repoel.setAttribute("url", config['repo_url'])
|
||||
addElement('description', config['repo_description'], doc, repoel)
|
||||
urlbasepath = os.path.basename(urlparse.urlparse(config['repo_url']).path)
|
||||
urlbasepath = os.path.basename(urllib.parse.urlparse(config['repo_url']).path)
|
||||
for mirror in config.get('mirrors', []):
|
||||
addElement('mirror', urlparse.urljoin(mirror, urlbasepath), doc, repoel)
|
||||
addElement('mirror', urllib.parse.urljoin(mirror, urlbasepath), doc, repoel)
|
||||
|
||||
repoel.setAttribute("version", "15")
|
||||
repoel.setAttribute("timestamp", str(int(time.time())))
|
||||
|
@ -828,7 +826,7 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
|
|||
logging.warning("\tfdroid update --create-key")
|
||||
sys.exit(1)
|
||||
|
||||
repoel.setAttribute("pubkey", extract_pubkey())
|
||||
repoel.setAttribute("pubkey", extract_pubkey().decode('utf-8'))
|
||||
root.appendChild(repoel)
|
||||
|
||||
for appid in sortedids:
|
||||
|
@ -968,9 +966,9 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
|
|||
os.symlink(sigfile_path, siglinkname)
|
||||
|
||||
if options.pretty:
|
||||
output = doc.toprettyxml()
|
||||
output = doc.toprettyxml(encoding='utf-8')
|
||||
else:
|
||||
output = doc.toxml()
|
||||
output = doc.toxml(encoding='utf-8')
|
||||
|
||||
with open(os.path.join(repodir, 'index.xml'), 'wb') as f:
|
||||
f.write(output)
|
||||
|
@ -1025,7 +1023,7 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
|
|||
|
||||
def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversions):
|
||||
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
|
||||
if app.ArchivePolicy:
|
||||
keepversions = int(app.ArchivePolicy[:-9])
|
||||
|
@ -1199,7 +1197,7 @@ def main():
|
|||
|
||||
# Generate a list of categories...
|
||||
categories = set()
|
||||
for app in apps.itervalues():
|
||||
for app in apps.values():
|
||||
categories.update(app.Categories)
|
||||
|
||||
# Read known apks data (will be updated and written back when we've finished)
|
||||
|
@ -1269,7 +1267,7 @@ def main():
|
|||
# level. When doing this, we use the info from the most recent version's apk.
|
||||
# We deal with figuring out when the app was added and last updated at the
|
||||
# same time.
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
bestver = 0
|
||||
for apk in apks + archapks:
|
||||
if apk['id'] == appid:
|
||||
|
@ -1303,13 +1301,13 @@ def main():
|
|||
# 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.keys(), 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
|
||||
if config['per_app_repos']:
|
||||
add_apks_to_per_app_repos(repodirs[0], apks)
|
||||
for appid, app in apps.iteritems():
|
||||
for appid, app in apps.items():
|
||||
repodir = os.path.join(appid, 'fdroid', 'repo')
|
||||
appdict = dict()
|
||||
appdict[appid] = app
|
||||
|
@ -1338,14 +1336,15 @@ def main():
|
|||
# Generate latest apps data for widget
|
||||
if os.path.exists(os.path.join('stats', 'latestapps.txt')):
|
||||
data = ''
|
||||
for line in file(os.path.join('stats', 'latestapps.txt')):
|
||||
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"
|
||||
with open(os.path.join('stats', 'latestapps.txt'), 'r') as f:
|
||||
for line in f:
|
||||
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"
|
||||
with open(os.path.join(repodirs[0], 'latestapps.dat'), 'w') as f:
|
||||
f.write(data)
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# verify.py - part of the FDroid server tools
|
||||
# Copyright (C) 2013, Ciaran Gultnieks, ciaran@ciarang.com
|
||||
|
@ -23,9 +22,9 @@ import glob
|
|||
from argparse import ArgumentParser
|
||||
import logging
|
||||
|
||||
import common
|
||||
import net
|
||||
from common import FDroidException
|
||||
from . import common
|
||||
from . import net
|
||||
from .common import FDroidException
|
||||
|
||||
options = None
|
||||
config = None
|
||||
|
|
|
@ -46,17 +46,16 @@ else
|
|||
done
|
||||
fi
|
||||
|
||||
# In the default configuration, the checks E123, E133, E226, E241 and E242 are
|
||||
# ignored because they are not rules unanimously accepted
|
||||
# On top of those, we ignore:
|
||||
# We ignore the following PEP8 warnings
|
||||
# * E123: closing bracket does not match indentation of opening bracket's line
|
||||
# - Broken if multiple indentation levels start on a single line
|
||||
# * E501: line too long (82 > 79 characters)
|
||||
# - Recommended for readability but not enforced
|
||||
# - Some lines are awkward to wrap around a char limit
|
||||
# * W503: line break before binary operator
|
||||
# - It's quite new
|
||||
# - Quite pedantic
|
||||
|
||||
PEP8_IGNORE="E123,E133,E226,E241,E242,E501,W503"
|
||||
PEP8_IGNORE="E123,E501,W503"
|
||||
|
||||
err() {
|
||||
echo ERROR: "$@"
|
||||
|
@ -71,22 +70,21 @@ cmd_exists() {
|
|||
command -v $1 1>/dev/null
|
||||
}
|
||||
|
||||
if cmd_exists pyflakes-python2; then
|
||||
PYFLAKES=pyflakes-python2
|
||||
elif cmd_exists pyflakes; then
|
||||
PYFLAKES=pyflakes
|
||||
else
|
||||
PYFLAKES=echo
|
||||
warn "pyflakes is not installed, using dummy placeholder!"
|
||||
fi
|
||||
find_command() {
|
||||
local name=$1
|
||||
for suff in "3" "-python3" ""; do
|
||||
cmd=${1}${suff}
|
||||
if cmd_exists $cmd; then
|
||||
echo -n $cmd
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
warn "$1 is not installed, using dummy placeholder!"
|
||||
echo -n echo
|
||||
}
|
||||
|
||||
if cmd_exists pep8-python2; then
|
||||
PEP8=pep8-python2
|
||||
elif cmd_exists pep8; then
|
||||
PEP8=pep8
|
||||
else
|
||||
err "pep8 is not installed!"
|
||||
fi
|
||||
PYFLAKES=$(find_command pyflakes)
|
||||
PEP8=$(find_command pep8)
|
||||
|
||||
if [ "$PY_FILES $PY_TEST_FILES" != " " ]; then
|
||||
if ! $PYFLAKES $PY_FILES $PY_TEST_FILES; then
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -26,7 +26,7 @@ def vagrant(params, cwd=None, printout=False):
|
|||
line = p.stdout.readline()
|
||||
if len(line) == 0:
|
||||
break
|
||||
print line,
|
||||
print(line)
|
||||
out += line
|
||||
p.wait()
|
||||
else:
|
||||
|
@ -63,13 +63,13 @@ config = {
|
|||
|
||||
# load config file, if present
|
||||
if os.path.exists('makebuildserver.config.py'):
|
||||
execfile('makebuildserver.config.py', config)
|
||||
exec(compile(open('makebuildserver.config.py').read(), 'makebuildserver.config.py', 'exec'), config)
|
||||
elif os.path.exists('makebs.config.py'):
|
||||
# this is the old name for the config file
|
||||
execfile('makebs.config.py', config)
|
||||
exec(compile(open('makebs.config.py').read(), 'makebs.config.py', 'exec'), config)
|
||||
|
||||
if not os.path.exists('makebuildserver') or not os.path.exists(serverdir):
|
||||
print 'This must be run from the correct directory!'
|
||||
print('This must be run from the correct directory!')
|
||||
sys.exit(1)
|
||||
|
||||
if os.path.exists(boxfile):
|
||||
|
@ -81,7 +81,7 @@ if options.clean:
|
|||
# Update cached files.
|
||||
cachedir = config['cachedir']
|
||||
if not os.path.exists(cachedir):
|
||||
os.makedirs(cachedir, 0755)
|
||||
os.makedirs(cachedir, 0o755)
|
||||
|
||||
cachefiles = [
|
||||
('android-sdk_r24.4.1-linux.tgz',
|
||||
|
@ -318,17 +318,17 @@ for f, src, shasum in cachefiles:
|
|||
if os.path.exists(relpath) and os.stat(relpath).st_size == 0:
|
||||
os.remove(relpath)
|
||||
if not os.path.exists(relpath):
|
||||
print "Downloading " + f + " to cache"
|
||||
print("Downloading " + f + " to cache")
|
||||
if subprocess.call(['wget', src, '-O', f], cwd=cachedir) != 0:
|
||||
print "...download of " + f + " failed."
|
||||
print("...download of " + f + " failed.")
|
||||
sys.exit(1)
|
||||
if shasum:
|
||||
v = sha256_for_file(relpath)
|
||||
if v != shasum:
|
||||
print "Invalid shasum of '" + v + "' detected for " + f
|
||||
print("Invalid shasum of '" + v + "' detected for " + f)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print "...shasum verified for " + f
|
||||
print("...shasum verified for " + f)
|
||||
|
||||
wanted.append(f)
|
||||
|
||||
|
@ -418,57 +418,57 @@ if os.path.exists(vf):
|
|||
with open(vf, 'r') as f:
|
||||
oldvf = f.read()
|
||||
if oldvf != vagrantfile:
|
||||
print "Server configuration has changed, rebuild from scratch is required"
|
||||
print("Server configuration has changed, rebuild from scratch is required")
|
||||
vagrant(['destroy', '-f'], serverdir)
|
||||
else:
|
||||
print "Re-provisioning existing server"
|
||||
print("Re-provisioning existing server")
|
||||
writevf = False
|
||||
else:
|
||||
print "No existing server - building from scratch"
|
||||
print("No existing server - building from scratch")
|
||||
if writevf:
|
||||
with open(vf, 'w') as f:
|
||||
f.write(vagrantfile)
|
||||
|
||||
|
||||
print "Configuring build server VM"
|
||||
print("Configuring build server VM")
|
||||
returncode, out = vagrant(['up', '--provision'], serverdir, printout=True)
|
||||
with open(os.path.join(serverdir, 'up.log'), 'w') as log:
|
||||
log.write(out)
|
||||
if returncode != 0:
|
||||
print "Failed to configure server"
|
||||
print("Failed to configure server")
|
||||
sys.exit(1)
|
||||
|
||||
print "Writing buildserver ID"
|
||||
print("Writing buildserver ID")
|
||||
p = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE)
|
||||
buildserverid = p.communicate()[0].strip()
|
||||
print "...ID is " + buildserverid
|
||||
print("...ID is " + buildserverid)
|
||||
subprocess.call(
|
||||
['vagrant', 'ssh', '-c', 'sh -c "echo {0} >/home/vagrant/buildserverid"'
|
||||
.format(buildserverid)],
|
||||
cwd=serverdir)
|
||||
|
||||
print "Stopping build server VM"
|
||||
print("Stopping build server VM")
|
||||
vagrant(['halt'], serverdir)
|
||||
|
||||
print "Waiting for build server VM to be finished"
|
||||
print("Waiting for build server VM to be finished")
|
||||
ready = False
|
||||
while not ready:
|
||||
time.sleep(2)
|
||||
returncode, out = vagrant(['status'], serverdir)
|
||||
if returncode != 0:
|
||||
print "Error while checking status"
|
||||
print("Error while checking status")
|
||||
sys.exit(1)
|
||||
for line in out.splitlines():
|
||||
if line.startswith("default"):
|
||||
if line.find("poweroff") != -1:
|
||||
ready = True
|
||||
else:
|
||||
print "Status: " + line
|
||||
print("Status: " + line)
|
||||
|
||||
print "Packaging"
|
||||
print("Packaging")
|
||||
vagrant(['package', '--output', os.path.join('..', boxfile)], serverdir,
|
||||
printout=options.verbose)
|
||||
print "Adding box"
|
||||
print("Adding box")
|
||||
vagrant(['box', 'add', 'buildserver', boxfile, '-f'],
|
||||
printout=options.verbose)
|
||||
|
||||
|
|
2
setup.py
2
setup.py
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from setuptools import setup
|
||||
import sys
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163
|
||||
|
||||
|
@ -37,7 +36,7 @@ class BuildTest(unittest.TestCase):
|
|||
break
|
||||
return True
|
||||
else:
|
||||
print 'no build-tools found: ' + build_tools
|
||||
print('no build-tools found: ' + build_tools)
|
||||
return False
|
||||
|
||||
def _find_all(self):
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163
|
||||
|
||||
|
@ -37,7 +36,7 @@ class CommonTest(unittest.TestCase):
|
|||
break
|
||||
return True
|
||||
else:
|
||||
print 'no build-tools found: ' + build_tools
|
||||
print('no build-tools found: ' + build_tools)
|
||||
return False
|
||||
|
||||
def _find_all(self):
|
||||
|
@ -61,7 +60,7 @@ class CommonTest(unittest.TestCase):
|
|||
if self._set_build_tools():
|
||||
self._find_all()
|
||||
else:
|
||||
print 'no build-tools found: ' + build_tools
|
||||
print('no build-tools found: ' + build_tools)
|
||||
|
||||
def testIsApkDebuggable(self):
|
||||
config = dict()
|
||||
|
|
|
@ -51,10 +51,10 @@ cd $WORKSPACE/tests
|
|||
#------------------------------------------------------------------------------#
|
||||
# test building the source tarball, then installing it
|
||||
cd $WORKSPACE
|
||||
python2 setup.py sdist
|
||||
python3 setup.py sdist
|
||||
|
||||
rm -rf $WORKSPACE/env
|
||||
virtualenv --python=python2 $WORKSPACE/env
|
||||
virtualenv --python=python3 $WORKSPACE/env
|
||||
. $WORKSPACE/env/bin/activate
|
||||
pip install dist/fdroidserver-*.tar.gz
|
||||
|
||||
|
@ -66,10 +66,10 @@ fdroid=$WORKSPACE/env/bin/fdroid $WORKSPACE/tests/run-tests $apksource
|
|||
# test install using install direct from git repo
|
||||
cd $WORKSPACE
|
||||
rm -rf $WORKSPACE/env
|
||||
virtualenv --python=python2 --system-site-packages $WORKSPACE/env
|
||||
virtualenv --python=python3 --system-site-packages $WORKSPACE/env
|
||||
. $WORKSPACE/env/bin/activate
|
||||
pip install -e $WORKSPACE
|
||||
python2 setup.py install
|
||||
python3 setup.py install
|
||||
|
||||
# run tests in new pip+virtualenv install
|
||||
fdroid=$WORKSPACE/env/bin/fdroid $WORKSPACE/tests/run-tests $apksource
|
||||
|
@ -86,7 +86,7 @@ sh hooks/pre-commit
|
|||
cd $WORKSPACE
|
||||
set +e
|
||||
# use the virtualenv python so pylint checks against its installed libs
|
||||
PYTHONPATH=$WORKSPACE/.pylint-plugins python2 /usr/bin/pylint \
|
||||
PYTHONPATH=$WORKSPACE/.pylint-plugins python3 /usr/bin/pylint \
|
||||
--output-format=parseable --reports=n \
|
||||
--load-plugins astng_hashlib \
|
||||
fdroidserver/*.py fdroid makebuildserver setup.py > $WORKSPACE/pylint.parseable
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163
|
||||
|
||||
|
@ -32,7 +31,7 @@ class InstallTest(unittest.TestCase):
|
|||
devices = fdroidserver.install.devices()
|
||||
self.assertIsInstance(devices, list, 'install.devices() did not return a list!')
|
||||
for device in devices:
|
||||
self.assertIsInstance(device, basestring)
|
||||
self.assertIsInstance(device, str)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163
|
||||
|
||||
|
@ -43,7 +42,7 @@ class MetadataTest(unittest.TestCase):
|
|||
savepath = os.path.join('metadata', appid + '.pickle')
|
||||
frommeta = app.field_dict()
|
||||
self.assertTrue(appid in apps)
|
||||
with open(savepath, 'r') as f:
|
||||
with open(savepath, 'rb') as f:
|
||||
frompickle = pickle.load(f)
|
||||
self.assertEquals(frommeta, frompickle)
|
||||
# Uncomment to overwrite
|
||||
|
|
|
@ -83,7 +83,7 @@ fi
|
|||
|
||||
# allow the location of python to be overridden
|
||||
if [ -z $python ]; then
|
||||
python=python2
|
||||
python=python3
|
||||
fi
|
||||
|
||||
set -x # show each command as it is executed
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163
|
||||
|
||||
|
@ -9,6 +8,7 @@ import optparse
|
|||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
localmodule = os.path.realpath(
|
||||
os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..'))
|
||||
|
@ -56,10 +56,10 @@ class UpdateTest(unittest.TestCase):
|
|||
self.assertEquals(len(sig), len(pysig),
|
||||
"the length of the two sigs are different!")
|
||||
try:
|
||||
self.assertEquals(sig.decode('hex'), pysig.decode('hex'),
|
||||
self.assertEquals(unhexlify(sig), unhexlify(pysig),
|
||||
"the length of the two sigs are different!")
|
||||
except TypeError as e:
|
||||
print e
|
||||
print(e)
|
||||
self.assertTrue(False, 'TypeError!')
|
||||
|
||||
def testBadGetsig(self):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue