mirror of
https://github.com/f-droid/fdroidserver.git
synced 2025-09-14 23:12:46 +03:00
Replace sys.exit() in non-main functions by exceptions
Also move all exceptions into one module
This commit is contained in:
parent
a8420817cb
commit
1fcd8e63a3
17 changed files with 119 additions and 141 deletions
|
@ -35,12 +35,12 @@ import json
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import zipfile
|
import zipfile
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
|
from .exception import FDroidException
|
||||||
from . import common
|
from . import common
|
||||||
from . import server
|
from . import server
|
||||||
|
|
||||||
|
@ -166,8 +166,8 @@ def main():
|
||||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||||
|
|
||||||
if not os.path.exists(options.git_repo):
|
if not os.path.exists(options.git_repo):
|
||||||
logging.error('"' + options.git_repo + '/" does not exist! Create it, or use --git-repo')
|
raise FDroidException(
|
||||||
sys.exit(1)
|
'"%s" does not exist! Create it, or use --git-repo' % options.git_repo)
|
||||||
|
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,8 @@ from . import common
|
||||||
from . import net
|
from . import net
|
||||||
from . import metadata
|
from . import metadata
|
||||||
from . import scanner
|
from . import scanner
|
||||||
from .common import FDroidException, BuildException, VCSException, FDroidPopen, SdkToolsPopen
|
from .common import FDroidPopen, SdkToolsPopen
|
||||||
|
from .exception import FDroidException, BuildException, VCSException
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import paramiko
|
import paramiko
|
||||||
|
@ -582,10 +583,10 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext
|
||||||
if k.endswith("_orig"):
|
if k.endswith("_orig"):
|
||||||
continue
|
continue
|
||||||
logging.critical(" %s: %s" % (k, v))
|
logging.critical(" %s: %s" % (k, v))
|
||||||
sys.exit(3)
|
raise FDroidException()
|
||||||
elif not os.path.isdir(ndk_path):
|
elif not os.path.isdir(ndk_path):
|
||||||
logging.critical("Android NDK '%s' is not a directory!" % ndk_path)
|
logging.critical("Android NDK '%s' is not a directory!" % ndk_path)
|
||||||
sys.exit(3)
|
raise FDroidException()
|
||||||
|
|
||||||
common.set_FDroidPopen_env(build)
|
common.set_FDroidPopen_env(build)
|
||||||
|
|
||||||
|
@ -1256,7 +1257,8 @@ def main():
|
||||||
try:
|
try:
|
||||||
net.download_file(url, local_filename=of)
|
net.download_file(url, local_filename=of)
|
||||||
except requests.exceptions.HTTPError as e:
|
except requests.exceptions.HTTPError as e:
|
||||||
raise FDroidException('downloading Binaries from %s failed' % url) from e
|
raise FDroidException(
|
||||||
|
'Downloading Binaries from %s failed. %s' % (url, e))
|
||||||
|
|
||||||
# Now we check weather the build can be verified to
|
# Now we check weather the build can be verified to
|
||||||
# match the supplied binary or not. Should the
|
# match the supplied binary or not. Should the
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
@ -33,8 +32,7 @@ import copy
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from . import metadata
|
from . import metadata
|
||||||
from .common import VCSException, FDroidException
|
from .exception import VCSException, FDroidException, MetaDataException
|
||||||
from .metadata import MetaDataException
|
|
||||||
|
|
||||||
|
|
||||||
# Check for a new version by looking at a document retrieved via HTTP.
|
# Check for a new version by looking at a document retrieved via HTTP.
|
||||||
|
@ -498,8 +496,7 @@ def checkupdates_app(app, first=True):
|
||||||
gitcmd.extend(['--author', config['auto_author']])
|
gitcmd.extend(['--author', config['auto_author']])
|
||||||
gitcmd.extend(["--", metadatapath])
|
gitcmd.extend(["--", metadatapath])
|
||||||
if subprocess.call(gitcmd) != 0:
|
if subprocess.call(gitcmd) != 0:
|
||||||
logging.error("Git commit failed")
|
raise FDroidException("Git commit failed")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
config = None
|
config = None
|
||||||
|
|
|
@ -49,6 +49,7 @@ from pyasn1.error import PyAsn1Error
|
||||||
from distutils.util import strtobool
|
from distutils.util import strtobool
|
||||||
|
|
||||||
import fdroidserver.metadata
|
import fdroidserver.metadata
|
||||||
|
from fdroidserver.exception import FDroidException, VCSException, BuildException
|
||||||
from .asynchronousfilereader import AsynchronousFileReader
|
from .asynchronousfilereader import AsynchronousFileReader
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,8 +235,7 @@ def read_config(opts, config_file='config.py'):
|
||||||
code = compile(f.read(), config_file, 'exec')
|
code = compile(f.read(), config_file, 'exec')
|
||||||
exec(code, None, config)
|
exec(code, None, config)
|
||||||
elif len(get_local_metadata_files()) == 0:
|
elif len(get_local_metadata_files()) == 0:
|
||||||
logging.critical("Missing config file - is this a repo directory?")
|
raise FDroidException("Missing config file - is this a repo directory?")
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
for k in ('mirrors', 'install_list', 'uninstall_list', 'serverwebroot', 'servergitroot'):
|
for k in ('mirrors', 'install_list', 'uninstall_list', 'serverwebroot', 'servergitroot'):
|
||||||
if k in config:
|
if k in config:
|
||||||
|
@ -374,13 +374,12 @@ def test_sdk_exists(thisconfig):
|
||||||
|
|
||||||
def ensure_build_tools_exists(thisconfig):
|
def ensure_build_tools_exists(thisconfig):
|
||||||
if not test_sdk_exists(thisconfig):
|
if not test_sdk_exists(thisconfig):
|
||||||
sys.exit(3)
|
raise FDroidException("Android SDK not found.")
|
||||||
build_tools = os.path.join(thisconfig['sdk_path'], 'build-tools')
|
build_tools = os.path.join(thisconfig['sdk_path'], 'build-tools')
|
||||||
versioned_build_tools = os.path.join(build_tools, thisconfig['build_tools'])
|
versioned_build_tools = os.path.join(build_tools, thisconfig['build_tools'])
|
||||||
if not os.path.isdir(versioned_build_tools):
|
if not os.path.isdir(versioned_build_tools):
|
||||||
logging.critical('Android Build Tools path "'
|
raise FDroidException(
|
||||||
+ versioned_build_tools + '" does not exist!')
|
'Android Build Tools path "' + versioned_build_tools + '" does not exist!')
|
||||||
sys.exit(3)
|
|
||||||
|
|
||||||
|
|
||||||
def get_local_metadata_files():
|
def get_local_metadata_files():
|
||||||
|
@ -1243,39 +1242,6 @@ def is_valid_package_name(name):
|
||||||
return re.match("[A-Za-z_][A-Za-z_0-9.]+$", name)
|
return re.match("[A-Za-z_][A-Za-z_0-9.]+$", name)
|
||||||
|
|
||||||
|
|
||||||
class FDroidException(Exception):
|
|
||||||
|
|
||||||
def __init__(self, value, detail=None):
|
|
||||||
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" + self.shortened_detail() + "</pre>\n"
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
ret = self.value
|
|
||||||
if self.detail:
|
|
||||||
ret += "\n==== detail begin ====\n%s\n==== detail end ====" % self.detail.strip()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
class VCSException(FDroidException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class BuildException(FDroidException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Get the specified source library.
|
# Get the specified source library.
|
||||||
# Returns the path to it. Normally this is the path to be used when referencing
|
# Returns the path to it. Normally this is the path to be used when referencing
|
||||||
# it, which may be a subdirectory of the actual project. If you want the base
|
# it, which may be a subdirectory of the actual project. If you want the base
|
||||||
|
@ -1696,8 +1662,7 @@ def get_apk_debuggable_aapt(apkfile):
|
||||||
p = SdkToolsPopen(['aapt', 'dump', 'xmltree', apkfile, 'AndroidManifest.xml'],
|
p = SdkToolsPopen(['aapt', 'dump', 'xmltree', apkfile, 'AndroidManifest.xml'],
|
||||||
output=False)
|
output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logging.critical("Failed to get apk manifest information")
|
raise FDroidException("Failed to get apk manifest information")
|
||||||
sys.exit(1)
|
|
||||||
for line in p.output.splitlines():
|
for line in p.output.splitlines():
|
||||||
if 'android:debuggable' in line and not line.endswith('0x0'):
|
if 'android:debuggable' in line and not line.endswith('0x0'):
|
||||||
return True
|
return True
|
||||||
|
@ -1708,8 +1673,7 @@ def get_apk_debuggable_androguard(apkfile):
|
||||||
try:
|
try:
|
||||||
from androguard.core.bytecodes.apk import APK
|
from androguard.core.bytecodes.apk import APK
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logging.critical("androguard library is not installed and aapt not present")
|
raise FDroidException("androguard library is not installed and aapt not present")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
apkobject = APK(apkfile)
|
apkobject = APK(apkfile)
|
||||||
if apkobject.is_valid_APK():
|
if apkobject.is_valid_APK():
|
||||||
|
@ -1745,8 +1709,7 @@ def SdkToolsPopen(commands, cwd=None, output=True):
|
||||||
config[cmd] = find_sdk_tools_cmd(commands[0])
|
config[cmd] = find_sdk_tools_cmd(commands[0])
|
||||||
abscmd = config[cmd]
|
abscmd = config[cmd]
|
||||||
if abscmd is None:
|
if abscmd is None:
|
||||||
logging.critical("Could not find '%s' on your system" % cmd)
|
raise FDroidException("Could not find '%s' on your system" % cmd)
|
||||||
sys.exit(1)
|
|
||||||
if cmd == 'aapt':
|
if cmd == 'aapt':
|
||||||
test_aapt_version(config['aapt'])
|
test_aapt_version(config['aapt'])
|
||||||
return FDroidPopen([abscmd] + commands[1:],
|
return FDroidPopen([abscmd] + commands[1:],
|
||||||
|
|
44
fdroidserver/exception.py
Normal file
44
fdroidserver/exception.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
class FDroidException(Exception):
|
||||||
|
|
||||||
|
def __init__(self, value=None, detail=None):
|
||||||
|
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" + self.shortened_detail() + "</pre>\n"
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
ret = self.value
|
||||||
|
if self.detail:
|
||||||
|
ret += "\n==== detail begin ====\n%s\n==== detail end ====" % self.detail.strip()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
class MetaDataException(Exception):
|
||||||
|
|
||||||
|
def __init__(self, value):
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
|
class VCSException(FDroidException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BuildException(FDroidException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class VerificationException(FDroidException):
|
||||||
|
pass
|
|
@ -16,7 +16,6 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import glob
|
import glob
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
@ -24,6 +23,7 @@ import logging
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from .common import FDroidPopen
|
from .common import FDroidPopen
|
||||||
|
from .exception import FDroidException
|
||||||
|
|
||||||
config = None
|
config = None
|
||||||
options = None
|
options = None
|
||||||
|
@ -46,8 +46,7 @@ def main():
|
||||||
|
|
||||||
for output_dir in repodirs:
|
for output_dir in repodirs:
|
||||||
if not os.path.isdir(output_dir):
|
if not os.path.isdir(output_dir):
|
||||||
logging.error("Missing output directory '" + output_dir + "'")
|
raise FDroidException("Missing output directory '" + output_dir + "'")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Process any apks that are waiting to be signed...
|
# Process any apks that are waiting to be signed...
|
||||||
for f in sorted(glob.glob(os.path.join(output_dir, '*.*'))):
|
for f in sorted(glob.glob(os.path.join(output_dir, '*.*'))):
|
||||||
|
@ -70,8 +69,7 @@ def main():
|
||||||
gpgargs.append(os.path.join(output_dir, filename))
|
gpgargs.append(os.path.join(output_dir, filename))
|
||||||
p = FDroidPopen(gpgargs)
|
p = FDroidPopen(gpgargs)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logging.error("Signing failed.")
|
raise FDroidException("Signing failed.")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
logging.info('Signed ' + filename)
|
logging.info('Signed ' + filename)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import binascii
|
import binascii
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
@ -28,6 +27,7 @@ import logging
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from . import metadata
|
from . import metadata
|
||||||
|
from .exception import FDroidException
|
||||||
|
|
||||||
|
|
||||||
# Get the repo type and address from the given web page. The page is scanned
|
# Get the repo type and address from the given web page. The page is scanned
|
||||||
|
@ -123,8 +123,7 @@ def get_metadata_from_url(app, url):
|
||||||
# Figure out the repo type and adddress...
|
# Figure out the repo type and adddress...
|
||||||
repotype, repo = getrepofrompage(app.SourceCode)
|
repotype, repo = getrepofrompage(app.SourceCode)
|
||||||
if not repotype:
|
if not repotype:
|
||||||
logging.error("Unable to determine vcs type. " + repo)
|
raise FDroidException("Unable to determine vcs type. " + repo)
|
||||||
sys.exit(1)
|
|
||||||
elif url.startswith('https://') and url.endswith('.git'):
|
elif url.startswith('https://') and url.endswith('.git'):
|
||||||
projecttype = 'git'
|
projecttype = 'git'
|
||||||
repo = url
|
repo = url
|
||||||
|
@ -132,10 +131,10 @@ def get_metadata_from_url(app, url):
|
||||||
app.SourceCode = ""
|
app.SourceCode = ""
|
||||||
app.WebSite = ""
|
app.WebSite = ""
|
||||||
if not projecttype:
|
if not projecttype:
|
||||||
logging.error("Unable to determine the project type.")
|
raise FDroidException("Unable to determine the project type. " +
|
||||||
logging.error("The URL you supplied was not in one of the supported formats. Please consult")
|
"The URL you supplied was not in one of the supported formats. " +
|
||||||
logging.error("the manual for a list of supported formats, and supply one of those.")
|
"Please consult the manual for a list of supported formats, " +
|
||||||
sys.exit(1)
|
"and supply one of those.")
|
||||||
|
|
||||||
# Ensure we have a sensible-looking repo address at this point. If not, we
|
# Ensure we have a sensible-looking repo address at this point. If not, we
|
||||||
# might have got a page format we weren't expecting. (Note that we
|
# might have got a page format we weren't expecting. (Note that we
|
||||||
|
@ -144,8 +143,7 @@ def get_metadata_from_url(app, url):
|
||||||
not repo.startswith('https://') and
|
not repo.startswith('https://') and
|
||||||
not repo.startswith('git://'))) or
|
not repo.startswith('git://'))) or
|
||||||
' ' in repo):
|
' ' in repo):
|
||||||
logging.error("Repo address '{0}' does not seem to be valid".format(repo))
|
raise FDroidException("Repo address '{0}' does not seem to be valid".format(repo))
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Get a copy of the source so we can extract some info...
|
# Get a copy of the source so we can extract some info...
|
||||||
logging.info('Getting source from ' + repotype + ' repo at ' + repo)
|
logging.info('Getting source from ' + repotype + ' repo at ' + repo)
|
||||||
|
@ -205,8 +203,7 @@ def main():
|
||||||
|
|
||||||
local_metadata_files = common.get_local_metadata_files()
|
local_metadata_files = common.get_local_metadata_files()
|
||||||
if local_metadata_files != []:
|
if local_metadata_files != []:
|
||||||
logging.error("This repo already has local metadata: %s" % local_metadata_files[0])
|
raise FDroidException("This repo already has local metadata: %s" % local_metadata_files[0])
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if options.url is None and os.path.isdir('.git'):
|
if options.url is None and os.path.isdir('.git'):
|
||||||
app.AutoName = os.path.basename(os.getcwd())
|
app.AutoName = os.path.basename(os.getcwd())
|
||||||
|
@ -236,8 +233,7 @@ def main():
|
||||||
build.disable = 'Generated by import.py - check/set version fields and commit id'
|
build.disable = 'Generated by import.py - check/set version fields and commit id'
|
||||||
write_local_file = False
|
write_local_file = False
|
||||||
else:
|
else:
|
||||||
logging.error("Specify project url.")
|
raise FDroidException("Specify project url.")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Extract some information...
|
# Extract some information...
|
||||||
paths = common.manifest_paths(root_dir, [])
|
paths = common.manifest_paths(root_dir, [])
|
||||||
|
@ -245,8 +241,7 @@ def main():
|
||||||
|
|
||||||
versionName, versionCode, package = common.parse_androidmanifests(paths, app)
|
versionName, versionCode, package = common.parse_androidmanifests(paths, app)
|
||||||
if not package:
|
if not package:
|
||||||
logging.error("Couldn't find package ID")
|
raise FDroidException("Couldn't find package ID")
|
||||||
sys.exit(1)
|
|
||||||
if not versionName:
|
if not versionName:
|
||||||
logging.warn("Couldn't find latest version name")
|
logging.warn("Couldn't find latest version name")
|
||||||
if not versionCode:
|
if not versionCode:
|
||||||
|
@ -262,13 +257,11 @@ def main():
|
||||||
versionName = bconfig.get('app', 'version')
|
versionName = bconfig.get('app', 'version')
|
||||||
versionCode = None
|
versionCode = None
|
||||||
else:
|
else:
|
||||||
logging.error("No android or kivy project could be found. Specify --subdir?")
|
raise FDroidException("No android or kivy project could be found. Specify --subdir?")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Make sure it's actually new...
|
# Make sure it's actually new...
|
||||||
if package in apps:
|
if package in apps:
|
||||||
logging.error("Package " + package + " already exists")
|
raise FDroidException("Package " + package + " already exists")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Create a build line...
|
# Create a build line...
|
||||||
build.versionName = versionName or '?'
|
build.versionName = versionName or '?'
|
||||||
|
|
|
@ -27,7 +27,6 @@ import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import zipfile
|
import zipfile
|
||||||
|
@ -37,7 +36,7 @@ from xml.dom.minidom import Document
|
||||||
|
|
||||||
from fdroidserver import metadata, signindex, common, net
|
from fdroidserver import metadata, signindex, common, net
|
||||||
from fdroidserver.common import FDroidPopen, FDroidPopenBytes
|
from fdroidserver.common import FDroidPopen, FDroidPopenBytes
|
||||||
from fdroidserver.metadata import MetaDataException
|
from fdroidserver.exception import FDroidException, VerificationException, MetaDataException
|
||||||
|
|
||||||
|
|
||||||
def make(apps, sortedids, apks, repodir, archive):
|
def make(apps, sortedids, apks, repodir, archive):
|
||||||
|
@ -77,9 +76,8 @@ def make(apps, sortedids, apks, repodir, archive):
|
||||||
nosigningkey = True
|
nosigningkey = True
|
||||||
logging.critical("'" + common.config['keystore'] + "' does not exist!")
|
logging.critical("'" + common.config['keystore'] + "' does not exist!")
|
||||||
if nosigningkey:
|
if nosigningkey:
|
||||||
logging.warning("`fdroid update` requires a signing key, you can create one using:")
|
raise FDroidException("`fdroid update` requires a signing key, " +
|
||||||
logging.warning("\tfdroid update --create-key")
|
"you can create one using: fdroid update --create-key")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
repodict = collections.OrderedDict()
|
repodict = collections.OrderedDict()
|
||||||
repodict['timestamp'] = datetime.utcnow()
|
repodict['timestamp'] = datetime.utcnow()
|
||||||
|
@ -118,7 +116,7 @@ def make(apps, sortedids, apks, repodir, archive):
|
||||||
if mirror is not None:
|
if mirror is not None:
|
||||||
mirrors.append(mirror + '/')
|
mirrors.append(mirror + '/')
|
||||||
if mirrorcheckfailed:
|
if mirrorcheckfailed:
|
||||||
sys.exit(1)
|
raise FDroidException("Malformed repository mirrors.")
|
||||||
if mirrors:
|
if mirrors:
|
||||||
repodict['mirrors'] = mirrors
|
repodict['mirrors'] = mirrors
|
||||||
|
|
||||||
|
@ -364,9 +362,8 @@ def make_v0(apps, apks, repodir, repodict, requestsdict):
|
||||||
# Check for duplicates - they will make the client unhappy...
|
# Check for duplicates - they will make the client unhappy...
|
||||||
for i in range(len(apklist) - 1):
|
for i in range(len(apklist) - 1):
|
||||||
if apklist[i]['versionCode'] == apklist[i + 1]['versionCode']:
|
if apklist[i]['versionCode'] == apklist[i + 1]['versionCode']:
|
||||||
logging.critical("duplicate versions: '%s' - '%s'" % (
|
raise FDroidException("duplicate versions: '%s' - '%s'" % (
|
||||||
apklist[i]['apkName'], apklist[i + 1]['apkName']))
|
apklist[i]['apkName'], apklist[i + 1]['apkName']))
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
current_version_code = 0
|
current_version_code = 0
|
||||||
current_version_file = None
|
current_version_file = None
|
||||||
|
@ -475,8 +472,7 @@ def make_v0(apps, apks, repodir, repodict, requestsdict):
|
||||||
jar_output = 'index_unsigned.jar' if common.options.nosign else 'index.jar'
|
jar_output = 'index_unsigned.jar' if common.options.nosign else 'index.jar'
|
||||||
p = FDroidPopen(['jar', 'cf', jar_output, 'index.xml'], cwd=repodir)
|
p = FDroidPopen(['jar', 'cf', jar_output, 'index.xml'], cwd=repodir)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logging.critical("Failed to create {0}".format(jar_output))
|
raise FDroidException("Failed to create {0}".format(jar_output))
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Sign the index...
|
# Sign the index...
|
||||||
signed = os.path.join(repodir, 'index.jar')
|
signed = os.path.join(repodir, 'index.jar')
|
||||||
|
@ -513,8 +509,7 @@ def extract_pubkey():
|
||||||
msg = "Failed to get repo pubkey!"
|
msg = "Failed to get repo pubkey!"
|
||||||
if common.config['keystore'] == 'NONE':
|
if common.config['keystore'] == 'NONE':
|
||||||
msg += ' Is your crypto smartcard plugged in?'
|
msg += ' Is your crypto smartcard plugged in?'
|
||||||
logging.critical(msg)
|
raise FDroidException(msg)
|
||||||
sys.exit(1)
|
|
||||||
pubkey = p.output
|
pubkey = p.output
|
||||||
repo_pubkey_fingerprint = common.get_cert_fingerprint(pubkey)
|
repo_pubkey_fingerprint = common.get_cert_fingerprint(pubkey)
|
||||||
return hexlify(pubkey), repo_pubkey_fingerprint
|
return hexlify(pubkey), repo_pubkey_fingerprint
|
||||||
|
@ -558,10 +553,6 @@ def get_mirror_service_url(url):
|
||||||
return '/'.join(segments)
|
return '/'.join(segments)
|
||||||
|
|
||||||
|
|
||||||
class VerificationException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def download_repo_index(url_str, etag=None, verify_fingerprint=True):
|
def download_repo_index(url_str, etag=None, verify_fingerprint=True):
|
||||||
"""
|
"""
|
||||||
Downloads the repository index from the given :param url_str
|
Downloads the repository index from the given :param url_str
|
||||||
|
|
|
@ -28,6 +28,7 @@ from argparse import ArgumentParser
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
|
from .exception import FDroidException
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
options = None
|
options = None
|
||||||
|
@ -117,7 +118,7 @@ def main():
|
||||||
if common.test_sdk_exists(test_config):
|
if common.test_sdk_exists(test_config):
|
||||||
break
|
break
|
||||||
if not common.test_sdk_exists(test_config):
|
if not common.test_sdk_exists(test_config):
|
||||||
sys.exit(3)
|
raise FDroidException("Android SDK not found.")
|
||||||
|
|
||||||
if not os.path.exists('config.py'):
|
if not os.path.exists('config.py'):
|
||||||
# 'metadata' and 'tmp' are created in fdroid
|
# 'metadata' and 'tmp' are created in fdroid
|
||||||
|
@ -135,7 +136,7 @@ def main():
|
||||||
else:
|
else:
|
||||||
logging.warn('Looks like this is already an F-Droid repo, cowardly refusing to overwrite it...')
|
logging.warn('Looks like this is already an F-Droid repo, cowardly refusing to overwrite it...')
|
||||||
logging.info('Try running `fdroid init` in an empty directory.')
|
logging.info('Try running `fdroid init` in an empty directory.')
|
||||||
sys.exit()
|
raise FDroidException('Repository already exists.')
|
||||||
|
|
||||||
if 'aapt' not in test_config or not os.path.isfile(test_config['aapt']):
|
if 'aapt' not in test_config or not os.path.isfile(test_config['aapt']):
|
||||||
# try to find a working aapt, in all the recent possible paths
|
# try to find a working aapt, in all the recent possible paths
|
||||||
|
|
|
@ -24,7 +24,8 @@ from argparse import ArgumentParser
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from .common import SdkToolsPopen, FDroidException
|
from .common import SdkToolsPopen
|
||||||
|
from .exception import FDroidException
|
||||||
|
|
||||||
options = None
|
options = None
|
||||||
config = None
|
config = None
|
||||||
|
|
|
@ -36,20 +36,12 @@ except ImportError:
|
||||||
YamlLoader = Loader
|
YamlLoader = Loader
|
||||||
|
|
||||||
import fdroidserver.common
|
import fdroidserver.common
|
||||||
|
from fdroidserver.exception import MetaDataException
|
||||||
|
|
||||||
srclibs = None
|
srclibs = None
|
||||||
warnings_action = None
|
warnings_action = None
|
||||||
|
|
||||||
|
|
||||||
class MetaDataException(Exception):
|
|
||||||
|
|
||||||
def __init__(self, value):
|
|
||||||
self.value = value
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.value
|
|
||||||
|
|
||||||
|
|
||||||
def warn_or_exception(value):
|
def warn_or_exception(value):
|
||||||
'''output warning or Exception depending on -W'''
|
'''output warning or Exception depending on -W'''
|
||||||
if warnings_action == 'ignore':
|
if warnings_action == 'ignore':
|
||||||
|
|
|
@ -27,7 +27,8 @@ import logging
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from . import metadata
|
from . import metadata
|
||||||
from .common import FDroidPopen, SdkToolsPopen, BuildException
|
from .common import FDroidPopen, SdkToolsPopen
|
||||||
|
from .exception import BuildException
|
||||||
|
|
||||||
config = None
|
config = None
|
||||||
options = None
|
options = None
|
||||||
|
|
|
@ -24,7 +24,7 @@ import logging
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from . import metadata
|
from . import metadata
|
||||||
from .common import BuildException, VCSException
|
from .exception import BuildException, VCSException
|
||||||
|
|
||||||
config = None
|
config = None
|
||||||
options = None
|
options = None
|
||||||
|
|
|
@ -30,6 +30,7 @@ import logging
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
|
from .exception import FDroidException
|
||||||
|
|
||||||
config = None
|
config = None
|
||||||
options = None
|
options = None
|
||||||
|
@ -97,7 +98,7 @@ def update_awsbucket_s3cmd(repo_section):
|
||||||
'--exclude', indexjar,
|
'--exclude', indexjar,
|
||||||
'--exclude', indexv1jar,
|
'--exclude', indexv1jar,
|
||||||
repo_section, s3url]) != 0:
|
repo_section, s3url]) != 0:
|
||||||
sys.exit(1)
|
raise FDroidException()
|
||||||
logging.debug('s3cmd sync all files in ' + repo_section + ' to ' + s3url)
|
logging.debug('s3cmd sync all files in ' + repo_section + ' to ' + s3url)
|
||||||
if subprocess.call(s3cmdargs +
|
if subprocess.call(s3cmdargs +
|
||||||
['--no-check-md5',
|
['--no-check-md5',
|
||||||
|
@ -105,7 +106,7 @@ def update_awsbucket_s3cmd(repo_section):
|
||||||
'--exclude', indexjar,
|
'--exclude', indexjar,
|
||||||
'--exclude', indexv1jar,
|
'--exclude', indexv1jar,
|
||||||
repo_section, s3url]) != 0:
|
repo_section, s3url]) != 0:
|
||||||
sys.exit(1)
|
raise FDroidException()
|
||||||
|
|
||||||
logging.debug('s3cmd sync indexes ' + repo_section + ' to ' + s3url + ' and delete')
|
logging.debug('s3cmd sync indexes ' + repo_section + ' to ' + s3url + ' and delete')
|
||||||
s3cmdargs.append('--delete-removed')
|
s3cmdargs.append('--delete-removed')
|
||||||
|
@ -115,7 +116,7 @@ def update_awsbucket_s3cmd(repo_section):
|
||||||
else:
|
else:
|
||||||
s3cmdargs.append('--check-md5')
|
s3cmdargs.append('--check-md5')
|
||||||
if subprocess.call(s3cmdargs + [repo_section, s3url]) != 0:
|
if subprocess.call(s3cmdargs + [repo_section, s3url]) != 0:
|
||||||
sys.exit(1)
|
raise FDroidException()
|
||||||
|
|
||||||
|
|
||||||
def update_awsbucket_libcloud(repo_section):
|
def update_awsbucket_libcloud(repo_section):
|
||||||
|
@ -135,8 +136,8 @@ def update_awsbucket_libcloud(repo_section):
|
||||||
from libcloud.storage.providers import get_driver
|
from libcloud.storage.providers import get_driver
|
||||||
|
|
||||||
if not config.get('awsaccesskeyid') or not config.get('awssecretkey'):
|
if not config.get('awsaccesskeyid') or not config.get('awssecretkey'):
|
||||||
logging.error('To use awsbucket, you must set awssecretkey and awsaccesskeyid in config.py!')
|
raise FDroidException(
|
||||||
sys.exit(1)
|
'To use awsbucket, you must set awssecretkey and awsaccesskeyid in config.py!')
|
||||||
awsbucket = config['awsbucket']
|
awsbucket = config['awsbucket']
|
||||||
|
|
||||||
cls = get_driver(Provider.S3)
|
cls = get_driver(Provider.S3)
|
||||||
|
@ -234,9 +235,9 @@ def update_serverwebroot(serverwebroot, repo_section):
|
||||||
['--exclude', indexxml, '--exclude', indexjar,
|
['--exclude', indexxml, '--exclude', indexjar,
|
||||||
'--exclude', indexv1jar,
|
'--exclude', indexv1jar,
|
||||||
repo_section, serverwebroot]) != 0:
|
repo_section, serverwebroot]) != 0:
|
||||||
sys.exit(1)
|
raise FDroidException()
|
||||||
if subprocess.call(rsyncargs + [repo_section, serverwebroot]) != 0:
|
if subprocess.call(rsyncargs + [repo_section, serverwebroot]) != 0:
|
||||||
sys.exit(1)
|
raise FDroidException()
|
||||||
# upload "current version" symlinks if requested
|
# upload "current version" symlinks if requested
|
||||||
if config['make_current_version_link'] and repo_section == 'repo':
|
if config['make_current_version_link'] and repo_section == 'repo':
|
||||||
links_to_upload = []
|
links_to_upload = []
|
||||||
|
@ -246,7 +247,7 @@ def update_serverwebroot(serverwebroot, repo_section):
|
||||||
links_to_upload.append(f)
|
links_to_upload.append(f)
|
||||||
if len(links_to_upload) > 0:
|
if len(links_to_upload) > 0:
|
||||||
if subprocess.call(rsyncargs + links_to_upload + [serverwebroot]) != 0:
|
if subprocess.call(rsyncargs + links_to_upload + [serverwebroot]) != 0:
|
||||||
sys.exit(1)
|
raise FDroidException()
|
||||||
|
|
||||||
|
|
||||||
def _local_sync(fromdir, todir):
|
def _local_sync(fromdir, todir):
|
||||||
|
@ -262,7 +263,7 @@ def _local_sync(fromdir, todir):
|
||||||
rsyncargs += ['--quiet']
|
rsyncargs += ['--quiet']
|
||||||
logging.debug(' '.join(rsyncargs + [fromdir, todir]))
|
logging.debug(' '.join(rsyncargs + [fromdir, todir]))
|
||||||
if subprocess.call(rsyncargs + [fromdir, todir]) != 0:
|
if subprocess.call(rsyncargs + [fromdir, todir]) != 0:
|
||||||
sys.exit(1)
|
raise FDroidException()
|
||||||
|
|
||||||
|
|
||||||
def sync_from_localcopy(repo_section, local_copy_dir):
|
def sync_from_localcopy(repo_section, local_copy_dir):
|
||||||
|
|
|
@ -16,13 +16,13 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import zipfile
|
import zipfile
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
|
from .exception import FDroidException
|
||||||
|
|
||||||
config = None
|
config = None
|
||||||
options = None
|
options = None
|
||||||
|
@ -53,8 +53,7 @@ def sign_jar(jar):
|
||||||
}
|
}
|
||||||
p = common.FDroidPopen(args, envs=env_vars)
|
p = common.FDroidPopen(args, envs=env_vars)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logging.critical("Failed to sign %s!" % jar)
|
raise FDroidException("Failed to sign %s!" % jar)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def sign_index_v1(repodir, json_name):
|
def sign_index_v1(repodir, json_name):
|
||||||
|
@ -87,8 +86,8 @@ def main():
|
||||||
config = common.read_config(options)
|
config = common.read_config(options)
|
||||||
|
|
||||||
if 'jarsigner' not in config:
|
if 'jarsigner' not in config:
|
||||||
logging.critical('Java jarsigner not found! Install in standard location or set java_paths!')
|
raise FDroidException(
|
||||||
sys.exit(1)
|
'Java jarsigner not found! Install in standard location or set java_paths!')
|
||||||
|
|
||||||
repodirs = ['repo']
|
repodirs = ['repo']
|
||||||
if config['archive_older'] != 0:
|
if config['archive_older'] != 0:
|
||||||
|
@ -97,8 +96,7 @@ def main():
|
||||||
signed = 0
|
signed = 0
|
||||||
for output_dir in repodirs:
|
for output_dir in repodirs:
|
||||||
if not os.path.isdir(output_dir):
|
if not os.path.isdir(output_dir):
|
||||||
logging.error("Missing output directory '" + output_dir + "'")
|
raise FDroidException("Missing output directory '" + output_dir + "'")
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
unsigned = os.path.join(output_dir, 'index_unsigned.jar')
|
unsigned = os.path.join(output_dir, 'index_unsigned.jar')
|
||||||
if os.path.exists(unsigned):
|
if os.path.exists(unsigned):
|
||||||
|
|
|
@ -41,7 +41,8 @@ from . import btlog
|
||||||
from . import common
|
from . import common
|
||||||
from . import index
|
from . import index
|
||||||
from . import metadata
|
from . import metadata
|
||||||
from .common import BuildException, SdkToolsPopen
|
from .common import SdkToolsPopen
|
||||||
|
from .exception import BuildException, FDroidException
|
||||||
|
|
||||||
METADATA_VERSION = 18
|
METADATA_VERSION = 18
|
||||||
|
|
||||||
|
@ -820,8 +821,7 @@ def scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False):
|
||||||
continue
|
continue
|
||||||
stat = os.stat(filename)
|
stat = os.stat(filename)
|
||||||
if stat.st_size == 0:
|
if stat.st_size == 0:
|
||||||
logging.error(filename + ' is zero size!')
|
raise FDroidException(filename + ' is zero size!')
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
shasum = sha256sum(filename)
|
shasum = sha256sum(filename)
|
||||||
usecache = False
|
usecache = False
|
||||||
|
@ -897,7 +897,7 @@ def scan_apk_aapt(apk, apkfile):
|
||||||
logging.error("Could not find {0} to remove it".format(apkfile))
|
logging.error("Could not find {0} to remove it".format(apkfile))
|
||||||
else:
|
else:
|
||||||
logging.error("Failed to get apk information, skipping " + apkfile)
|
logging.error("Failed to get apk information, skipping " + apkfile)
|
||||||
raise BuildException("Invaild APK")
|
raise BuildException("Invalid APK")
|
||||||
for line in p.output.splitlines():
|
for line in p.output.splitlines():
|
||||||
if line.startswith("package:"):
|
if line.startswith("package:"):
|
||||||
try:
|
try:
|
||||||
|
@ -905,9 +905,7 @@ def scan_apk_aapt(apk, apkfile):
|
||||||
apk['versionCode'] = int(re.match(APK_VERCODE_PAT, line).group(1))
|
apk['versionCode'] = int(re.match(APK_VERCODE_PAT, line).group(1))
|
||||||
apk['versionName'] = re.match(APK_VERNAME_PAT, line).group(1)
|
apk['versionName'] = re.match(APK_VERNAME_PAT, line).group(1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("Package matching failed: " + str(e))
|
raise FDroidException("Package matching failed: " + str(e) + "\nLine was: " + line)
|
||||||
logging.info("Line was: " + line)
|
|
||||||
sys.exit(1)
|
|
||||||
elif line.startswith("application:"):
|
elif line.startswith("application:"):
|
||||||
apk['name'] = re.match(APK_LABEL_PAT, line).group(1)
|
apk['name'] = re.match(APK_LABEL_PAT, line).group(1)
|
||||||
# Keep path to non-dpi icon in case we need it
|
# Keep path to non-dpi icon in case we need it
|
||||||
|
@ -1000,11 +998,10 @@ def scan_apk_androguard(apk, apkfile):
|
||||||
logging.error("Failed to get apk information, skipping " + apkfile)
|
logging.error("Failed to get apk information, skipping " + apkfile)
|
||||||
raise BuildException("Invaild APK")
|
raise BuildException("Invaild APK")
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logging.critical("androguard library is not installed and aapt not present")
|
raise FDroidException("androguard library is not installed and aapt not present")
|
||||||
sys.exit(1)
|
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logging.error("Could not open apk file for analysis")
|
logging.error("Could not open apk file for analysis")
|
||||||
raise BuildException("Invaild APK")
|
raise BuildException("Invalid APK")
|
||||||
|
|
||||||
apk['packageName'] = apkobject.get_package()
|
apk['packageName'] = apkobject.get_package()
|
||||||
apk['versionCode'] = int(apkobject.get_androidversion_code())
|
apk['versionCode'] = int(apkobject.get_androidversion_code())
|
||||||
|
@ -1508,8 +1505,7 @@ def main():
|
||||||
config = common.read_config(options)
|
config = common.read_config(options)
|
||||||
|
|
||||||
if not ('jarsigner' in config and 'keytool' in config):
|
if not ('jarsigner' in config and 'keytool' in config):
|
||||||
logging.critical('Java JDK not found! Install in standard location or set java_paths!')
|
raise FDroidException('Java JDK not found! Install in standard location or set java_paths!')
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
repodirs = ['repo']
|
repodirs = ['repo']
|
||||||
if config['archive_older'] != 0:
|
if config['archive_older'] != 0:
|
||||||
|
|
|
@ -25,7 +25,7 @@ import logging
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from . import net
|
from . import net
|
||||||
from .common import FDroidException
|
from .exception import FDroidException
|
||||||
|
|
||||||
options = None
|
options = None
|
||||||
config = None
|
config = None
|
||||||
|
@ -80,7 +80,7 @@ def main():
|
||||||
try:
|
try:
|
||||||
net.download_file(url, dldir=tmp_dir)
|
net.download_file(url, dldir=tmp_dir)
|
||||||
except requests.exceptions.HTTPError as e:
|
except requests.exceptions.HTTPError as e:
|
||||||
raise FDroidException('downloading %s failed', url) from e
|
raise FDroidException('Downloading %s failed. %s', (url, e))
|
||||||
|
|
||||||
compare_result = common.verify_apks(
|
compare_result = common.verify_apks(
|
||||||
remoteapk,
|
remoteapk,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue