mirror of
https://github.com/f-droid/fdroidserver.git
synced 2025-11-04 22:40:29 +03:00
Merge branch 'first-working-localization' into 'master'
First working localization See merge request fdroid/fdroidserver!340
This commit is contained in:
commit
c225e0c363
19 changed files with 780 additions and 785 deletions
2
fdroid
2
fdroid
|
|
@ -31,7 +31,7 @@ commands = OrderedDict([
|
||||||
("build", _("Build a package from source")),
|
("build", _("Build a package from source")),
|
||||||
("init", _("Quickly start a new repository")),
|
("init", _("Quickly start a new repository")),
|
||||||
("publish", _("Sign and place packages in the repo")),
|
("publish", _("Sign and place packages in the repo")),
|
||||||
("gpgsign", _("Add gpg signatures for packages in repo")),
|
("gpgsign", _("Add PGP signatures using GnuPG for packages in repo")),
|
||||||
("update", _("Update repo information for new packages")),
|
("update", _("Update repo information for new packages")),
|
||||||
("verify", _("Verify the integrity of downloaded packages")),
|
("verify", _("Verify the integrity of downloaded packages")),
|
||||||
("checkupdates", _("Check for updates to applications")),
|
("checkupdates", _("Check for updates to applications")),
|
||||||
|
|
|
||||||
|
|
@ -1016,7 +1016,7 @@ def parse_commandline():
|
||||||
parser.add_argument("--skip-scan", dest="skipscan", action="store_true", default=False,
|
parser.add_argument("--skip-scan", dest="skipscan", action="store_true", default=False,
|
||||||
help=_("Skip scanning the source code for binaries and other problems"))
|
help=_("Skip scanning the source code for binaries and other problems"))
|
||||||
parser.add_argument("--dscanner", action="store_true", default=False,
|
parser.add_argument("--dscanner", action="store_true", default=False,
|
||||||
help=_("Setup an emulator, install the apk on it and perform a drozer scan"))
|
help=_("Setup an emulator, install the APK on it and perform a Drozer scan"))
|
||||||
parser.add_argument("--no-tarball", dest="notarball", action="store_true", default=False,
|
parser.add_argument("--no-tarball", dest="notarball", action="store_true", default=False,
|
||||||
help=_("Don't create a source tarball, useful when testing a build"))
|
help=_("Don't create a source tarball, useful when testing a build"))
|
||||||
parser.add_argument("--no-refresh", dest="refresh", action="store_false", default=True,
|
parser.add_argument("--no-refresh", dest="refresh", action="store_false", default=True,
|
||||||
|
|
|
||||||
|
|
@ -558,15 +558,16 @@ def main():
|
||||||
for appid, app in apps.items():
|
for appid, app in apps.items():
|
||||||
|
|
||||||
if options.autoonly and app.AutoUpdateMode in ('None', 'Static'):
|
if options.autoonly and app.AutoUpdateMode in ('None', 'Static'):
|
||||||
logging.debug("Nothing to do for {0}...".format(appid))
|
logging.debug(_("Nothing to do for {appid}.").format(appid=appid))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logging.info("Processing " + appid + '...')
|
logging.info(_("Processing {appid}").format(appid=appid))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
checkupdates_app(app)
|
checkupdates_app(app)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("...checkupdate failed for {0} : {1}".format(appid, e))
|
logging.error(_("...checkupdate failed for {appid} : {error}")
|
||||||
|
.format(appid=appid, error=e))
|
||||||
|
|
||||||
logging.info(_("Finished"))
|
logging.info(_("Finished"))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -235,18 +235,19 @@ def read_config(opts, config_file='config.py'):
|
||||||
config = {}
|
config = {}
|
||||||
|
|
||||||
if os.path.isfile(config_file):
|
if os.path.isfile(config_file):
|
||||||
logging.debug("Reading %s" % config_file)
|
logging.debug(_("Reading '{config_file}'").format(config_file=config_file))
|
||||||
with io.open(config_file, "rb") as f:
|
with io.open(config_file, "rb") as f:
|
||||||
code = compile(f.read(), config_file, 'exec')
|
code = compile(f.read(), config_file, 'exec')
|
||||||
exec(code, None, config)
|
exec(code, None, config)
|
||||||
else:
|
else:
|
||||||
logging.warning("No config.py found - using defaults.")
|
logging.warning(_("No 'config.py' found, using defaults."))
|
||||||
|
|
||||||
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:
|
||||||
if not type(config[k]) in (str, list, tuple):
|
if not type(config[k]) in (str, list, tuple):
|
||||||
logging.warn('"' + k + '" will be in random order!'
|
logging.warning(
|
||||||
+ ' Use () or [] brackets if order is important!')
|
_("'{field}' will be in random order! Use () or [] brackets if order is important!")
|
||||||
|
.format(field=k))
|
||||||
|
|
||||||
# smartcardoptions must be a list since its command line args for Popen
|
# smartcardoptions must be a list since its command line args for Popen
|
||||||
if 'smartcardoptions' in config:
|
if 'smartcardoptions' in config:
|
||||||
|
|
@ -261,7 +262,8 @@ def read_config(opts, config_file='config.py'):
|
||||||
if any(k in config for k in ["keystore", "keystorepass", "keypass"]):
|
if any(k in config for k in ["keystore", "keystorepass", "keypass"]):
|
||||||
st = os.stat(config_file)
|
st = os.stat(config_file)
|
||||||
if st.st_mode & stat.S_IRWXG or st.st_mode & stat.S_IRWXO:
|
if st.st_mode & stat.S_IRWXG or st.st_mode & stat.S_IRWXO:
|
||||||
logging.warning("unsafe permissions on {0} (should be 0600)!".format(config_file))
|
logging.warning(_("unsafe permissions on '{config_file}' (should be 0600)!")
|
||||||
|
.format(config_file=config_file))
|
||||||
|
|
||||||
fill_config_defaults(config)
|
fill_config_defaults(config)
|
||||||
|
|
||||||
|
|
@ -275,7 +277,7 @@ def read_config(opts, config_file='config.py'):
|
||||||
elif all(isinstance(item, str) for item in config['serverwebroot']):
|
elif all(isinstance(item, str) for item in config['serverwebroot']):
|
||||||
roots = config['serverwebroot']
|
roots = config['serverwebroot']
|
||||||
else:
|
else:
|
||||||
raise TypeError('only accepts strings, lists, and tuples')
|
raise TypeError(_('only accepts strings, lists, and tuples'))
|
||||||
rootlist = []
|
rootlist = []
|
||||||
for rootstr in roots:
|
for rootstr in roots:
|
||||||
# since this is used with rsync, where trailing slashes have
|
# since this is used with rsync, where trailing slashes have
|
||||||
|
|
@ -291,7 +293,7 @@ def read_config(opts, config_file='config.py'):
|
||||||
elif all(isinstance(item, str) for item in config['servergitmirrors']):
|
elif all(isinstance(item, str) for item in config['servergitmirrors']):
|
||||||
roots = config['servergitmirrors']
|
roots = config['servergitmirrors']
|
||||||
else:
|
else:
|
||||||
raise TypeError('only accepts strings, lists, and tuples')
|
raise TypeError(_('only accepts strings, lists, and tuples'))
|
||||||
config['servergitmirrors'] = roots
|
config['servergitmirrors'] = roots
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
@ -336,7 +338,7 @@ def test_aapt_version(aapt):
|
||||||
'''Check whether the version of aapt is new enough'''
|
'''Check whether the version of aapt is new enough'''
|
||||||
output = subprocess.check_output([aapt, 'version'], universal_newlines=True)
|
output = subprocess.check_output([aapt, 'version'], universal_newlines=True)
|
||||||
if output is None or output == '':
|
if output is None or output == '':
|
||||||
logging.error(aapt + ' failed to execute!')
|
logging.error(_("'{path}' failed to execute!").format(path=aapt))
|
||||||
else:
|
else:
|
||||||
m = re.match(r'.*v([0-9]+)\.([0-9]+)[.-]?([0-9.-]*)', output)
|
m = re.match(r'.*v([0-9]+)\.([0-9]+)[.-]?([0-9.-]*)', output)
|
||||||
if m:
|
if m:
|
||||||
|
|
@ -345,9 +347,10 @@ def test_aapt_version(aapt):
|
||||||
bugfix = m.group(3)
|
bugfix = m.group(3)
|
||||||
# the Debian package has the version string like "v0.2-23.0.2"
|
# the Debian package has the version string like "v0.2-23.0.2"
|
||||||
if '.' not in bugfix and LooseVersion('.'.join((major, minor, bugfix))) < LooseVersion('0.2.2166767'):
|
if '.' not in bugfix and LooseVersion('.'.join((major, minor, bugfix))) < LooseVersion('0.2.2166767'):
|
||||||
logging.warning(aapt + ' is too old, fdroid requires build-tools-23.0.0 or newer!')
|
logging.warning(_("'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!")
|
||||||
|
.format(aapt=aapt))
|
||||||
else:
|
else:
|
||||||
logging.warning('Unknown version of aapt, might cause problems: ' + output)
|
logging.warning(_('Unknown version of aapt, might cause problems: ') + output)
|
||||||
|
|
||||||
|
|
||||||
def test_sdk_exists(thisconfig):
|
def test_sdk_exists(thisconfig):
|
||||||
|
|
@ -356,35 +359,38 @@ def test_sdk_exists(thisconfig):
|
||||||
test_aapt_version(thisconfig['aapt'])
|
test_aapt_version(thisconfig['aapt'])
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logging.error("'sdk_path' not set in config.py!")
|
logging.error(_("'sdk_path' not set in 'config.py'!"))
|
||||||
return False
|
return False
|
||||||
if thisconfig['sdk_path'] == default_config['sdk_path']:
|
if thisconfig['sdk_path'] == default_config['sdk_path']:
|
||||||
logging.error('No Android SDK found!')
|
logging.error(_('No Android SDK found!'))
|
||||||
logging.error('You can use ANDROID_HOME to set the path to your SDK, i.e.:')
|
logging.error(_('You can use ANDROID_HOME to set the path to your SDK, i.e.:'))
|
||||||
logging.error('\texport ANDROID_HOME=/opt/android-sdk')
|
logging.error('\texport ANDROID_HOME=/opt/android-sdk')
|
||||||
return False
|
return False
|
||||||
if not os.path.exists(thisconfig['sdk_path']):
|
if not os.path.exists(thisconfig['sdk_path']):
|
||||||
logging.critical('Android SDK path "' + thisconfig['sdk_path'] + '" does not exist!')
|
logging.critical(_("Android SDK path '{path}' does not exist!")
|
||||||
|
.format(path=thisconfig['sdk_path']))
|
||||||
return False
|
return False
|
||||||
if not os.path.isdir(thisconfig['sdk_path']):
|
if not os.path.isdir(thisconfig['sdk_path']):
|
||||||
logging.critical('Android SDK path "' + thisconfig['sdk_path'] + '" is not a directory!')
|
logging.critical(_("Android SDK path '{path}' is not a directory!")
|
||||||
|
.format(path=thisconfig['sdk_path']))
|
||||||
return False
|
return False
|
||||||
for d in ['build-tools', 'platform-tools', 'tools']:
|
for d in ['build-tools', 'platform-tools', 'tools']:
|
||||||
if not os.path.isdir(os.path.join(thisconfig['sdk_path'], d)):
|
if not os.path.isdir(os.path.join(thisconfig['sdk_path'], d)):
|
||||||
logging.critical('Android SDK path "%s" does not contain "%s/"!' % (
|
logging.critical(_("Android SDK '{path}' does not have '{dirname}' installed!")
|
||||||
thisconfig['sdk_path'], d))
|
.format(path=thisconfig['sdk_path'], dirname=d))
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def ensure_build_tools_exists(thisconfig):
|
def ensure_build_tools_exists(thisconfig):
|
||||||
if not test_sdk_exists(thisconfig):
|
if not test_sdk_exists(thisconfig):
|
||||||
raise FDroidException("Android SDK not found.")
|
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):
|
||||||
raise FDroidException(
|
raise FDroidException(
|
||||||
'Android Build Tools path "' + versioned_build_tools + '" does not exist!')
|
_("Android Build Tools path '{path}' does not exist!")
|
||||||
|
.format(path=versioned_build_tools))
|
||||||
|
|
||||||
|
|
||||||
def get_local_metadata_files():
|
def get_local_metadata_files():
|
||||||
|
|
@ -440,10 +446,10 @@ def read_app_args(args, allapps, allow_vercodes=False):
|
||||||
if len(apps) != len(vercodes):
|
if len(apps) != len(vercodes):
|
||||||
for p in vercodes:
|
for p in vercodes:
|
||||||
if p not in allapps:
|
if p not in allapps:
|
||||||
logging.critical("No such package: %s" % p)
|
logging.critical(_("No such package: %s") % p)
|
||||||
raise FDroidException("Found invalid app ids in arguments")
|
raise FDroidException(_("Found invalid appids in arguments"))
|
||||||
if not apps:
|
if not apps:
|
||||||
raise FDroidException("No packages specified")
|
raise FDroidException(_("No packages specified"))
|
||||||
|
|
||||||
error = False
|
error = False
|
||||||
for appid, app in apps.items():
|
for appid, app in apps.items():
|
||||||
|
|
@ -456,10 +462,11 @@ def read_app_args(args, allapps, allow_vercodes=False):
|
||||||
allvcs = [b.versionCode for b in app.builds]
|
allvcs = [b.versionCode for b in app.builds]
|
||||||
for v in vercodes[appid]:
|
for v in vercodes[appid]:
|
||||||
if v not in allvcs:
|
if v not in allvcs:
|
||||||
logging.critical("No such vercode %s for app %s" % (v, appid))
|
logging.critical(_("No such versionCode {versionCode} for app {appid}")
|
||||||
|
.format(versionCode=v, appid=appid))
|
||||||
|
|
||||||
if error:
|
if error:
|
||||||
raise FDroidException("Found invalid vercodes for some apps")
|
raise FDroidException(_("Found invalid versionCodes for some apps"))
|
||||||
|
|
||||||
return apps
|
return apps
|
||||||
|
|
||||||
|
|
@ -498,7 +505,7 @@ def publishednameinfo(filename):
|
||||||
try:
|
try:
|
||||||
result = (m.group(1), m.group(2))
|
result = (m.group(1), m.group(2))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise FDroidException("Invalid name for published file: %s" % filename)
|
raise FDroidException(_("Invalid name for published file: %s") % filename)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -590,7 +597,7 @@ class vcs:
|
||||||
raise VCSException("Authentication is not supported for git-svn")
|
raise VCSException("Authentication is not supported for git-svn")
|
||||||
self.username, remote = remote.split('@')
|
self.username, remote = remote.split('@')
|
||||||
if ':' not in self.username:
|
if ':' not in self.username:
|
||||||
raise VCSException("Password required with username")
|
raise VCSException(_("Password required with username"))
|
||||||
self.username, self.password = self.username.split(':')
|
self.username, self.password = self.username.split(':')
|
||||||
|
|
||||||
self.remote = remote
|
self.remote = remote
|
||||||
|
|
@ -612,7 +619,7 @@ class vcs:
|
||||||
def gotorevision(self, rev, refresh=True):
|
def gotorevision(self, rev, refresh=True):
|
||||||
|
|
||||||
if self.clone_failed:
|
if self.clone_failed:
|
||||||
raise VCSException("Downloading the repository already failed once, not trying again.")
|
raise VCSException(_("Downloading the repository already failed once, not trying again."))
|
||||||
|
|
||||||
# The .fdroidvcs-id file for a repo tells us what VCS type
|
# The .fdroidvcs-id file for a repo tells us what VCS type
|
||||||
# and remote that directory was created from, allowing us to drop it
|
# and remote that directory was created from, allowing us to drop it
|
||||||
|
|
@ -720,48 +727,48 @@ class vcs_git(vcs):
|
||||||
p = FDroidPopen(['git', 'submodule', 'foreach', '--recursive',
|
p = FDroidPopen(['git', 'submodule', 'foreach', '--recursive',
|
||||||
'git', 'reset', '--hard'], cwd=self.local, output=False)
|
'git', 'reset', '--hard'], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git reset failed", p.output)
|
raise VCSException(_("Git reset failed"), p.output)
|
||||||
# Remove untracked files now, in case they're tracked in the target
|
# Remove untracked files now, in case they're tracked in the target
|
||||||
# revision (it happens!)
|
# revision (it happens!)
|
||||||
p = FDroidPopen(['git', 'submodule', 'foreach', '--recursive',
|
p = FDroidPopen(['git', 'submodule', 'foreach', '--recursive',
|
||||||
'git', 'clean', '-dffx'], cwd=self.local, output=False)
|
'git', 'clean', '-dffx'], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git clean failed", p.output)
|
raise VCSException(_("Git clean failed"), p.output)
|
||||||
if not self.refreshed:
|
if not self.refreshed:
|
||||||
# Get latest commits and tags from remote
|
# Get latest commits and tags from remote
|
||||||
p = FDroidPopen(['git', 'fetch', 'origin'], cwd=self.local)
|
p = FDroidPopen(['git', 'fetch', 'origin'], cwd=self.local)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git fetch failed", p.output)
|
raise VCSException(_("Git fetch failed"), p.output)
|
||||||
p = FDroidPopen(['git', 'fetch', '--prune', '--tags', 'origin'], cwd=self.local, output=False)
|
p = FDroidPopen(['git', 'fetch', '--prune', '--tags', 'origin'], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git fetch failed", p.output)
|
raise VCSException(_("Git fetch failed"), p.output)
|
||||||
# Recreate origin/HEAD as git clone would do it, in case it disappeared
|
# Recreate origin/HEAD as git clone would do it, in case it disappeared
|
||||||
p = FDroidPopen(['git', 'remote', 'set-head', 'origin', '--auto'], cwd=self.local, output=False)
|
p = FDroidPopen(['git', 'remote', 'set-head', 'origin', '--auto'], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
lines = p.output.splitlines()
|
lines = p.output.splitlines()
|
||||||
if 'Multiple remote HEAD branches' not in lines[0]:
|
if 'Multiple remote HEAD branches' not in lines[0]:
|
||||||
raise VCSException("Git remote set-head failed", p.output)
|
raise VCSException(_("Git remote set-head failed"), p.output)
|
||||||
branch = lines[1].split(' ')[-1]
|
branch = lines[1].split(' ')[-1]
|
||||||
p2 = FDroidPopen(['git', 'remote', 'set-head', 'origin', branch], cwd=self.local, output=False)
|
p2 = FDroidPopen(['git', 'remote', 'set-head', 'origin', branch], cwd=self.local, output=False)
|
||||||
if p2.returncode != 0:
|
if p2.returncode != 0:
|
||||||
raise VCSException("Git remote set-head failed", p.output + '\n' + p2.output)
|
raise VCSException(_("Git remote set-head failed"), p.output + '\n' + p2.output)
|
||||||
self.refreshed = True
|
self.refreshed = True
|
||||||
# origin/HEAD is the HEAD of the remote, e.g. the "default branch" on
|
# origin/HEAD is the HEAD of the remote, e.g. the "default branch" on
|
||||||
# a github repo. Most of the time this is the same as origin/master.
|
# a github repo. Most of the time this is the same as origin/master.
|
||||||
rev = rev or 'origin/HEAD'
|
rev = rev or 'origin/HEAD'
|
||||||
p = FDroidPopen(['git', 'checkout', '-f', rev], cwd=self.local, output=False)
|
p = FDroidPopen(['git', 'checkout', '-f', rev], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git checkout of '%s' failed" % rev, p.output)
|
raise VCSException(_("Git checkout of '%s' failed") % rev, p.output)
|
||||||
# Get rid of any uncontrolled files left behind
|
# Get rid of any uncontrolled files left behind
|
||||||
p = FDroidPopen(['git', 'clean', '-dffx'], cwd=self.local, output=False)
|
p = FDroidPopen(['git', 'clean', '-dffx'], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git clean failed", p.output)
|
raise VCSException(_("Git clean failed"), p.output)
|
||||||
|
|
||||||
def initsubmodules(self):
|
def initsubmodules(self):
|
||||||
self.checkrepo()
|
self.checkrepo()
|
||||||
submfile = os.path.join(self.local, '.gitmodules')
|
submfile = os.path.join(self.local, '.gitmodules')
|
||||||
if not os.path.isfile(submfile):
|
if not os.path.isfile(submfile):
|
||||||
raise VCSException("No git submodules available")
|
raise VCSException(_("No git submodules available"))
|
||||||
|
|
||||||
# fix submodules not accessible without an account and public key auth
|
# fix submodules not accessible without an account and public key auth
|
||||||
with open(submfile, 'r') as f:
|
with open(submfile, 'r') as f:
|
||||||
|
|
@ -776,10 +783,10 @@ class vcs_git(vcs):
|
||||||
|
|
||||||
p = FDroidPopen(['git', 'submodule', 'sync'], cwd=self.local, output=False)
|
p = FDroidPopen(['git', 'submodule', 'sync'], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git submodule sync failed", p.output)
|
raise VCSException(_("Git submodule sync failed"), p.output)
|
||||||
p = FDroidPopen(['git', 'submodule', 'update', '--init', '--force', '--recursive'], cwd=self.local)
|
p = FDroidPopen(['git', 'submodule', 'update', '--init', '--force', '--recursive'], cwd=self.local)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git submodule update failed", p.output)
|
raise VCSException(_("Git submodule update failed"), p.output)
|
||||||
|
|
||||||
def _gettags(self):
|
def _gettags(self):
|
||||||
self.checkrepo()
|
self.checkrepo()
|
||||||
|
|
@ -902,12 +909,12 @@ class vcs_gitsvn(vcs):
|
||||||
# Check out the git rev equivalent to the svn rev
|
# Check out the git rev equivalent to the svn rev
|
||||||
p = FDroidPopen(['git', 'checkout', git_rev], cwd=self.local, output=False)
|
p = FDroidPopen(['git', 'checkout', git_rev], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git checkout of '%s' failed" % rev, p.output)
|
raise VCSException(_("Git checkout of '%s' failed") % rev, p.output)
|
||||||
|
|
||||||
# Get rid of any uncontrolled files left behind
|
# Get rid of any uncontrolled files left behind
|
||||||
p = FDroidPopen(['git', 'clean', '-dffx'], cwd=self.local, output=False)
|
p = FDroidPopen(['git', 'clean', '-dffx'], cwd=self.local, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise VCSException("Git clean failed", p.output)
|
raise VCSException(_("Git clean failed"), p.output)
|
||||||
|
|
||||||
def _gettags(self):
|
def _gettags(self):
|
||||||
self.checkrepo()
|
self.checkrepo()
|
||||||
|
|
@ -1164,7 +1171,7 @@ def parse_androidmanifests(paths, app):
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logging.debug("Parsing manifest at {0}".format(path))
|
logging.debug(_("Parsing manifest at '{path}'").format(path=path))
|
||||||
version = None
|
version = None
|
||||||
vercode = None
|
vercode = None
|
||||||
package = None
|
package = None
|
||||||
|
|
@ -1206,7 +1213,7 @@ def parse_androidmanifests(paths, app):
|
||||||
if string_is_integer(a):
|
if string_is_integer(a):
|
||||||
vercode = a
|
vercode = a
|
||||||
except Exception:
|
except Exception:
|
||||||
logging.warning("Problem with xml at {0}".format(path))
|
logging.warning(_("Problem with xml at '{path}'").format(path=path))
|
||||||
|
|
||||||
# Remember package name, may be defined separately from version+vercode
|
# Remember package name, may be defined separately from version+vercode
|
||||||
if package is None:
|
if package is None:
|
||||||
|
|
@ -1238,7 +1245,7 @@ def parse_androidmanifests(paths, app):
|
||||||
max_version = "Unknown"
|
max_version = "Unknown"
|
||||||
|
|
||||||
if max_package and not is_valid_package_name(max_package):
|
if max_package and not is_valid_package_name(max_package):
|
||||||
raise FDroidException("Invalid package name {0}".format(max_package))
|
raise FDroidException(_("Invalid package name {0}").format(max_package))
|
||||||
|
|
||||||
return (max_version, max_vercode, max_package)
|
return (max_version, max_vercode, max_package)
|
||||||
|
|
||||||
|
|
@ -1346,7 +1353,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
|
||||||
|
|
||||||
# Initialise submodules if required
|
# Initialise submodules if required
|
||||||
if build.submodules:
|
if build.submodules:
|
||||||
logging.info("Initialising submodules")
|
logging.info(_("Initialising submodules"))
|
||||||
vcs.initsubmodules()
|
vcs.initsubmodules()
|
||||||
|
|
||||||
# Check that a subdir (if we're using one) exists. This has to happen
|
# Check that a subdir (if we're using one) exists. This has to happen
|
||||||
|
|
@ -1476,7 +1483,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=
|
||||||
|
|
||||||
# Delete unwanted files
|
# Delete unwanted files
|
||||||
if build.rm:
|
if build.rm:
|
||||||
logging.info("Removing specified files")
|
logging.info(_("Removing specified files"))
|
||||||
for part in getpaths(build_dir, build.rm):
|
for part in getpaths(build_dir, build.rm):
|
||||||
dest = os.path.join(build_dir, part)
|
dest = os.path.join(build_dir, part)
|
||||||
logging.info("Removing {0}".format(part))
|
logging.info("Removing {0}".format(part))
|
||||||
|
|
@ -1656,7 +1663,7 @@ class KnownApks:
|
||||||
else:
|
else:
|
||||||
apps[appid] = added
|
apps[appid] = added
|
||||||
sortedapps = sorted(apps.items(), key=operator.itemgetter(1))[-num:]
|
sortedapps = sorted(apps.items(), key=operator.itemgetter(1))[-num:]
|
||||||
lst = [app for app, _ in sortedapps]
|
lst = [app for app, _ignored in sortedapps]
|
||||||
lst.reverse()
|
lst.reverse()
|
||||||
return lst
|
return lst
|
||||||
|
|
||||||
|
|
@ -1672,7 +1679,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:
|
||||||
raise FDroidException("Failed to get apk manifest information")
|
raise FDroidException(_("Failed to get APK manifest information"))
|
||||||
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
|
||||||
|
|
@ -1719,7 +1726,8 @@ def get_apk_id_aapt(apkfile):
|
||||||
m = r.match(line)
|
m = r.match(line)
|
||||||
if m:
|
if m:
|
||||||
return m.group('appid'), m.group('vercode'), m.group('vername')
|
return m.group('appid'), m.group('vercode'), m.group('vername')
|
||||||
raise FDroidException("reading identification failed, APK invalid: '{}'".format(apkfile))
|
raise FDroidException(_("Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'")
|
||||||
|
.format(apkfilename=apkfile))
|
||||||
|
|
||||||
|
|
||||||
class PopenResult:
|
class PopenResult:
|
||||||
|
|
@ -1734,7 +1742,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:
|
||||||
raise FDroidException("Could not find '%s' on your system" % cmd)
|
raise FDroidException(_("Could not find '{command}' on your system").format(command=cmd))
|
||||||
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:],
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ def main():
|
||||||
help=_("Clean up all containers and then exit"))
|
help=_("Clean up all containers and then exit"))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--init-only", default=False, action='store_true',
|
"--init-only", default=False, action='store_true',
|
||||||
help=_("Prepare drozer to run a scan"))
|
help=_("Prepare Drozer to run a scan"))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--repo-path", default="repo", action="store",
|
"--repo-path", default="repo", action="store",
|
||||||
help=_("Override path for repo APKs (default: ./repo)"))
|
help=_("Override path for repo APKs (default: ./repo)"))
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ def main():
|
||||||
parser.add_argument("-u", "--url", default=None,
|
parser.add_argument("-u", "--url", default=None,
|
||||||
help=_("Project URL to import from."))
|
help=_("Project URL to import from."))
|
||||||
parser.add_argument("-s", "--subdir", default=None,
|
parser.add_argument("-s", "--subdir", default=None,
|
||||||
help=_("Path to main android project subdirectory, if not in root."))
|
help=_("Path to main Android project subdirectory, if not in root."))
|
||||||
parser.add_argument("-c", "--categories", default=None,
|
parser.add_argument("-c", "--categories", default=None,
|
||||||
help=_("Comma separated list of categories."))
|
help=_("Comma separated list of categories."))
|
||||||
parser.add_argument("-l", "--license", default=None,
|
parser.add_argument("-l", "--license", default=None,
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ def main():
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
common.setup_global_opts(parser)
|
common.setup_global_opts(parser)
|
||||||
parser.add_argument("-d", "--distinguished-name", default=None,
|
parser.add_argument("-d", "--distinguished-name", default=None,
|
||||||
help=_("X.509 'Distiguished Name' used when generating keys"))
|
help=_("X.509 'Distinguished Name' used when generating keys"))
|
||||||
parser.add_argument("--keystore", default=None,
|
parser.add_argument("--keystore", default=None,
|
||||||
help=_("Path to the keystore for the repo signing key"))
|
help=_("Path to the keystore for the repo signing key"))
|
||||||
parser.add_argument("--repo-keyalias", default=None,
|
parser.add_argument("--repo-keyalias", default=None,
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ def main():
|
||||||
raise FDroidException(_("No attached devices found"))
|
raise FDroidException(_("No attached devices found"))
|
||||||
logging.info(_("Installing %s...") % apk)
|
logging.info(_("Installing %s...") % apk)
|
||||||
for dev in devs:
|
for dev in devs:
|
||||||
logging.info(_("Installing %s on %s...") % (apk, dev))
|
logging.info(_("Installing '{apkfilename}' on {dev}...").format(apkfilename=apk, dev=dev))
|
||||||
p = SdkToolsPopen(['adb', "-s", dev, "install", apk])
|
p = SdkToolsPopen(['adb', "-s", dev, "install", apk])
|
||||||
fail = ""
|
fail = ""
|
||||||
for line in p.output.splitlines():
|
for line in p.output.splitlines():
|
||||||
|
|
@ -109,10 +109,11 @@ def main():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if fail == "INSTALL_FAILED_ALREADY_EXISTS":
|
if fail == "INSTALL_FAILED_ALREADY_EXISTS":
|
||||||
logging.warn(_("%s is already installed on %s.") % (apk, dev))
|
logging.warn(_("'{apkfilename}' is already installed on {dev}.")
|
||||||
|
.format(apkfilename=apk, dev=dev))
|
||||||
else:
|
else:
|
||||||
raise FDroidException(_("Failed to install %s on %s: %s") % (
|
raise FDroidException(_("Failed to install '{apkfilename}' on {dev}: {error}")
|
||||||
apk, dev, fail))
|
.format(apkfilename=apk, dev=dev, error=fail))
|
||||||
|
|
||||||
logging.info('\n' + _('Finished'))
|
logging.info('\n' + _('Finished'))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,20 +156,20 @@ def check_ucm_tags(app):
|
||||||
and lastbuild.versionCode == app.CurrentVersionCode
|
and lastbuild.versionCode == app.CurrentVersionCode
|
||||||
and not lastbuild.forcevercode
|
and not lastbuild.forcevercode
|
||||||
and any(s in lastbuild.commit for s in '.,_-/')):
|
and any(s in lastbuild.commit for s in '.,_-/')):
|
||||||
yield _("Last used commit '%s' looks like a tag, but Update Check Mode is '%s'") % (
|
yield _("Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'")\
|
||||||
lastbuild.commit, app.UpdateCheckMode)
|
.format(commit=lastbuild.commit, ucm=app.UpdateCheckMode)
|
||||||
|
|
||||||
|
|
||||||
def check_char_limits(app):
|
def check_char_limits(app):
|
||||||
limits = config['char_limits']
|
limits = config['char_limits']
|
||||||
|
|
||||||
if len(app.Summary) > limits['summary']:
|
if len(app.Summary) > limits['summary']:
|
||||||
yield _("Summary of length %s is over the %i char limit") % (
|
yield _("Summary of length {length} is over the {limit} char limit")\
|
||||||
len(app.Summary), limits['summary'])
|
.format(length=len(app.Summary), limit=limits['summary'])
|
||||||
|
|
||||||
if len(app.Description) > limits['description']:
|
if len(app.Description) > limits['description']:
|
||||||
yield _("Description of length %s is over the %i char limit") % (
|
yield _("Description of length {length} is over the {limit} char limit")\
|
||||||
len(app.Description), limits['description'])
|
.format(length=len(app.Description), limit=limits['description'])
|
||||||
|
|
||||||
|
|
||||||
def check_old_links(app):
|
def check_old_links(app):
|
||||||
|
|
@ -186,7 +186,8 @@ def check_old_links(app):
|
||||||
for f in ['WebSite', 'SourceCode', 'IssueTracker', 'Changelog']:
|
for f in ['WebSite', 'SourceCode', 'IssueTracker', 'Changelog']:
|
||||||
v = app.get(f)
|
v = app.get(f)
|
||||||
if any(s in v for s in old_sites):
|
if any(s in v for s in old_sites):
|
||||||
yield _("App is in '%s' but has a link to '%s'") % (app.Repo, v)
|
yield _("App is in '{repo}' but has a link to {url}")\
|
||||||
|
.format(repo=app.Repo, url=v)
|
||||||
|
|
||||||
|
|
||||||
def check_useless_fields(app):
|
def check_useless_fields(app):
|
||||||
|
|
@ -246,7 +247,7 @@ def check_duplicates(app):
|
||||||
continue
|
continue
|
||||||
v = v.lower()
|
v = v.lower()
|
||||||
if v in links_seen:
|
if v in links_seen:
|
||||||
yield _("Duplicate link in '%s': %s") % (f, v)
|
yield _("Duplicate link in '{field}': {url}").format(field=f, url=v)
|
||||||
else:
|
else:
|
||||||
links_seen.add(v)
|
links_seen.add(v)
|
||||||
|
|
||||||
|
|
@ -277,7 +278,7 @@ def check_mediawiki_links(app):
|
||||||
url = um.group(1)
|
url = um.group(1)
|
||||||
for m, r in http_checks:
|
for m, r in http_checks:
|
||||||
if m.match(url):
|
if m.match(url):
|
||||||
yield _("URL '%s' in Description: %s") % (url, r)
|
yield _("URL {url} in Description: {error}").format(url=url, error=r)
|
||||||
|
|
||||||
|
|
||||||
def check_bulleted_lists(app):
|
def check_bulleted_lists(app):
|
||||||
|
|
@ -309,11 +310,13 @@ def check_builds(app):
|
||||||
continue
|
continue
|
||||||
for s in ['master', 'origin', 'HEAD', 'default', 'trunk']:
|
for s in ['master', 'origin', 'HEAD', 'default', 'trunk']:
|
||||||
if build.commit and build.commit.startswith(s):
|
if build.commit and build.commit.startswith(s):
|
||||||
yield _("Branch '%s' used as commit in build '%s'") % (s, build.versionName)
|
yield _("Branch '{branch}' used as commit in build '{versionName}'")\
|
||||||
|
.format(branch=s, versionName=build.versionName)
|
||||||
for srclib in build.srclibs:
|
for srclib in build.srclibs:
|
||||||
ref = srclib.split('@')[1].split('/')[0]
|
ref = srclib.split('@')[1].split('/')[0]
|
||||||
if ref.startswith(s):
|
if ref.startswith(s):
|
||||||
yield _("Branch '%s' used as commit in srclib '%s'") % (s, srclib)
|
yield _("Branch '{branch}' used as commit in srclib '{srclib}'")\
|
||||||
|
.format(branch=s, srclib=srclib)
|
||||||
for key in build.keys():
|
for key in build.keys():
|
||||||
if key not in supported_flags:
|
if key not in supported_flags:
|
||||||
yield _('%s is not an accepted build field') % key
|
yield _('%s is not an accepted build field') % key
|
||||||
|
|
@ -335,7 +338,8 @@ def check_files_dir(app):
|
||||||
for build in app.builds:
|
for build in app.builds:
|
||||||
for fname in build.patch:
|
for fname in build.patch:
|
||||||
if fname not in files:
|
if fname not in files:
|
||||||
yield _("Unknown file %s in build '%s'") % (fname, build.versionName)
|
yield _("Unknown file '{filename}' in build '{versionName}'")\
|
||||||
|
.format(filename=fname, versionName=build.versionName)
|
||||||
else:
|
else:
|
||||||
used.add(fname)
|
used.add(fname)
|
||||||
|
|
||||||
|
|
@ -369,7 +373,8 @@ def check_extlib_dir(apps):
|
||||||
for build in app.builds:
|
for build in app.builds:
|
||||||
for path in build.extlibs:
|
for path in build.extlibs:
|
||||||
if path not in unused_extlib_files:
|
if path not in unused_extlib_files:
|
||||||
yield _("%s: Unknown extlib %s in build '%s'") % (app.id, path, build.versionName)
|
yield _("{appid}: Unknown extlib {path} in build '{versionName}'")\
|
||||||
|
.format(appid=app.id, path=path, versionName=build.versionName)
|
||||||
else:
|
else:
|
||||||
used.add(path)
|
used.add(path)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -732,7 +732,7 @@ def read_metadata(xref=True, check_vcs=[]):
|
||||||
+ glob.glob('.fdroid.txt')
|
+ glob.glob('.fdroid.txt')
|
||||||
+ glob.glob('.fdroid.json')
|
+ glob.glob('.fdroid.json')
|
||||||
+ glob.glob('.fdroid.yml')):
|
+ glob.glob('.fdroid.yml')):
|
||||||
packageName, _ = fdroidserver.common.get_extension(os.path.basename(metadatapath))
|
packageName, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath))
|
||||||
if packageName in apps:
|
if packageName in apps:
|
||||||
warn_or_exception("Found multiple metadata files for " + packageName)
|
warn_or_exception("Found multiple metadata files for " + packageName)
|
||||||
app = parse_metadata(metadatapath, packageName in check_vcs)
|
app = parse_metadata(metadatapath, packageName in check_vcs)
|
||||||
|
|
@ -777,7 +777,7 @@ def get_default_app_info(metadatapath=None):
|
||||||
if metadatapath is None:
|
if metadatapath is None:
|
||||||
appid = None
|
appid = None
|
||||||
else:
|
else:
|
||||||
appid, _ = fdroidserver.common.get_extension(os.path.basename(metadatapath))
|
appid, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath))
|
||||||
|
|
||||||
if appid == '.fdroid': # we have local metadata in the app's source
|
if appid == '.fdroid': # we have local metadata in the app's source
|
||||||
if os.path.exists('AndroidManifest.xml'):
|
if os.path.exists('AndroidManifest.xml'):
|
||||||
|
|
@ -929,7 +929,7 @@ def parse_metadata(metadatapath, check_vcs=False):
|
||||||
|
|
||||||
app = App()
|
app = App()
|
||||||
app.metadatapath = metadatapath
|
app.metadatapath = metadatapath
|
||||||
name, _ = fdroidserver.common.get_extension(os.path.basename(metadatapath))
|
name, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath))
|
||||||
if name == '.fdroid':
|
if name == '.fdroid':
|
||||||
check_vcs = False
|
check_vcs = False
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ def main():
|
||||||
if appid in vercodes and vercodes[appid]:
|
if appid in vercodes and vercodes[appid]:
|
||||||
if vercode not in vercodes[appid]:
|
if vercode not in vercodes[appid]:
|
||||||
continue
|
continue
|
||||||
logging.info("Processing " + apkfile)
|
logging.info(_("Processing {apkfilename}").format(apkfilename=apkfile))
|
||||||
|
|
||||||
# There ought to be valid metadata for this app, otherwise why are we
|
# There ought to be valid metadata for this app, otherwise why are we
|
||||||
# trying to publish it?
|
# trying to publish it?
|
||||||
|
|
|
||||||
|
|
@ -70,18 +70,19 @@ def main():
|
||||||
parser.error(_("Cannot use --list and --to at the same time"))
|
parser.error(_("Cannot use --list and --to at the same time"))
|
||||||
|
|
||||||
if options.to is not None and options.to not in supported:
|
if options.to is not None and options.to not in supported:
|
||||||
parser.error(_("Unsupported metadata format, use: --to [%s]") % ' '.join(supported))
|
parser.error(_("Unsupported metadata format, use: --to [{supported}]")
|
||||||
|
.format(supported=' '.join(supported)))
|
||||||
|
|
||||||
for appid, app in apps.items():
|
for appid, app in apps.items():
|
||||||
path = app.metadatapath
|
path = app.metadatapath
|
||||||
base, ext = common.get_extension(path)
|
base, ext = common.get_extension(path)
|
||||||
if not options.to and ext not in supported:
|
if not options.to and ext not in supported:
|
||||||
logging.info(_("Ignoring %s file at '%s'") % (ext, path))
|
logging.info(_("Ignoring {ext} file at '{path}'").format(ext=ext, path=path))
|
||||||
continue
|
continue
|
||||||
elif options.to is not None:
|
elif options.to is not None:
|
||||||
logging.info(_("rewriting '%s' to %s") % (appid, options.to))
|
logging.info(_("Rewriting '{appid}' to '{path}'").format(appid=appid, path=options.to))
|
||||||
else:
|
else:
|
||||||
logging.info(_("rewriting '%s'") % (appid))
|
logging.info(_("Rewriting '{appid}'").format(appid=appid))
|
||||||
|
|
||||||
to_ext = ext
|
to_ext = ext
|
||||||
if options.to is not None:
|
if options.to is not None:
|
||||||
|
|
|
||||||
|
|
@ -280,13 +280,13 @@ def main():
|
||||||
for appid, app in apps.items():
|
for appid, app in apps.items():
|
||||||
|
|
||||||
if app.Disabled:
|
if app.Disabled:
|
||||||
logging.info("Skipping %s: disabled" % appid)
|
logging.info(_("Skipping {appid}: disabled").format(appid=appid))
|
||||||
continue
|
continue
|
||||||
if not app.builds:
|
if not app.builds:
|
||||||
logging.info("Skipping %s: no builds specified" % appid)
|
logging.info(_("Skipping {appid}: no builds specified").format(appid=appid))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logging.info("Processing " + appid)
|
logging.info(_("Processing {appid}").format(appid=appid))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ def extract_signature(apkpath):
|
||||||
raise FDroidException("no valid signature in '{}'".format(apkpath))
|
raise FDroidException("no valid signature in '{}'".format(apkpath))
|
||||||
logging.debug('signature okay: %s', apkpath)
|
logging.debug('signature okay: %s', apkpath)
|
||||||
|
|
||||||
appid, vercode, _ = common.get_apk_id_aapt(apkpath)
|
appid, vercode, _ignored = common.get_apk_id_aapt(apkpath)
|
||||||
sigdir = common.metadata_get_sigdir(appid, vercode)
|
sigdir = common.metadata_get_sigdir(appid, vercode)
|
||||||
if not os.path.exists(sigdir):
|
if not os.path.exists(sigdir):
|
||||||
os.makedirs(sigdir)
|
os.makedirs(sigdir)
|
||||||
|
|
@ -62,21 +62,24 @@ def extract(config, options):
|
||||||
try:
|
try:
|
||||||
if os.path.isfile(apk):
|
if os.path.isfile(apk):
|
||||||
sigdir = extract_signature(apk)
|
sigdir = extract_signature(apk)
|
||||||
logging.info(_('fetched signatures for %s -> %s'), apk, sigdir)
|
logging.info(_("Fetched signatures for '{apkfilename}' -> '{sigdir}'")
|
||||||
|
.format(apkfilename=apk, sigdir=sigdir))
|
||||||
elif httpre.match(apk):
|
elif httpre.match(apk):
|
||||||
if apk.startswith('https') or options.no_check_https:
|
if apk.startswith('https') or options.no_check_https:
|
||||||
try:
|
try:
|
||||||
tmp_apk = os.path.join(tmp_dir, 'signed.apk')
|
tmp_apk = os.path.join(tmp_dir, 'signed.apk')
|
||||||
net.download_file(apk, tmp_apk)
|
net.download_file(apk, tmp_apk)
|
||||||
sigdir = extract_signature(tmp_apk)
|
sigdir = extract_signature(tmp_apk)
|
||||||
logging.info(_('fetched signatures for %s -> %s'), apk, sigdir)
|
logging.info(_("Fetched signatures for '{apkfilename}' -> '{sigdir}'")
|
||||||
|
.format(apkfilename=apk, sigdir=sigdir))
|
||||||
finally:
|
finally:
|
||||||
if tmp_apk and os.path.exists(tmp_apk):
|
if tmp_apk and os.path.exists(tmp_apk):
|
||||||
os.remove(tmp_apk)
|
os.remove(tmp_apk)
|
||||||
else:
|
else:
|
||||||
logging.warn(_('refuse downloading via insecure http connection (use https or specify --no-https-check): %s'), apk)
|
logging.warn(_('refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}').format(apkfilename=apk))
|
||||||
except FDroidException as e:
|
except FDroidException as e:
|
||||||
logging.warning(_("failed fetching signatures for '%s': %s"), apk, e)
|
logging.warning(_("Failed fetching signatures for '{apkfilename}': {error}")
|
||||||
|
.format(apkfilename=apk, error=e))
|
||||||
if e.detail:
|
if e.detail:
|
||||||
logging.debug(e.detail)
|
logging.debug(e.detail)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -904,7 +904,7 @@ def scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False):
|
||||||
logging.debug("Ignoring stale cache data for " + name)
|
logging.debug("Ignoring stale cache data for " + name)
|
||||||
|
|
||||||
if not usecache:
|
if not usecache:
|
||||||
logging.debug("Processing " + name_utf8)
|
logging.debug(_("Processing {apkfilename}").format(apkfilename=name_utf8))
|
||||||
repo_file = collections.OrderedDict()
|
repo_file = collections.OrderedDict()
|
||||||
repo_file['name'] = os.path.splitext(name_utf8)[0]
|
repo_file['name'] = os.path.splitext(name_utf8)[0]
|
||||||
# TODO rename apkname globally to something more generic
|
# TODO rename apkname globally to something more generic
|
||||||
|
|
@ -1221,12 +1221,13 @@ def process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk=Fal
|
||||||
logging.debug("Ignoring stale cache data for " + apkfilename)
|
logging.debug("Ignoring stale cache data for " + apkfilename)
|
||||||
|
|
||||||
if not usecache:
|
if not usecache:
|
||||||
logging.debug("Processing " + apkfilename)
|
logging.debug(_("Processing {apkfilename}").format(apkfilename=apkfilename))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
apk = scan_apk(apkfile)
|
apk = scan_apk(apkfile)
|
||||||
except BuildException:
|
except BuildException:
|
||||||
logging.warning('Skipping "%s" with invalid signature!', apkfilename)
|
logging.warning(_("Skipping '{apkfilename}' with invalid signature!")
|
||||||
|
.format(apkfilename=apkfilename))
|
||||||
return True, None, False
|
return True, None, False
|
||||||
|
|
||||||
# Check for debuggable apks...
|
# Check for debuggable apks...
|
||||||
|
|
@ -1717,11 +1718,11 @@ def main():
|
||||||
parser.add_argument("--pretty", action="store_true", default=False,
|
parser.add_argument("--pretty", action="store_true", default=False,
|
||||||
help=_("Produce human-readable index.xml"))
|
help=_("Produce human-readable index.xml"))
|
||||||
parser.add_argument("--clean", action="store_true", default=False,
|
parser.add_argument("--clean", action="store_true", default=False,
|
||||||
help=_("Clean update - don't uses caches, reprocess all apks"))
|
help=_("Clean update - don't uses caches, reprocess all APKs"))
|
||||||
parser.add_argument("--nosign", action="store_true", default=False,
|
parser.add_argument("--nosign", action="store_true", default=False,
|
||||||
help=_("When configured for signed indexes, create only unsigned indexes at this stage"))
|
help=_("When configured for signed indexes, create only unsigned indexes at this stage"))
|
||||||
parser.add_argument("--use-date-from-apk", action="store_true", default=False,
|
parser.add_argument("--use-date-from-apk", action="store_true", default=False,
|
||||||
help=_("Use date from apk instead of current time for newly added apks"))
|
help=_("Use date from APK instead of current time for newly added APKs"))
|
||||||
parser.add_argument("--rename-apks", action="store_true", default=False,
|
parser.add_argument("--rename-apks", action="store_true", default=False,
|
||||||
help=_("Rename APK files that do not match package.name_123.apk"))
|
help=_("Rename APK files that do not match package.name_123.apk"))
|
||||||
parser.add_argument("--allow-disabled-algorithms", action="store_true", default=False,
|
parser.add_argument("--allow-disabled-algorithms", action="store_true", default=False,
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ def main():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
logging.info("Processing " + apkfilename)
|
logging.info("Processing {apkfilename}".format(apkfilename=apkfilename))
|
||||||
|
|
||||||
remoteapk = os.path.join(tmp_dir, apkfilename)
|
remoteapk = os.path.join(tmp_dir, apkfilename)
|
||||||
if os.path.exists(remoteapk):
|
if os.path.exists(remoteapk):
|
||||||
|
|
@ -84,7 +84,8 @@ def main():
|
||||||
try:
|
try:
|
||||||
net.download_file(url.replace('/repo', '/archive'), dldir=tmp_dir)
|
net.download_file(url.replace('/repo', '/archive'), dldir=tmp_dir)
|
||||||
except requests.exceptions.HTTPError as e:
|
except requests.exceptions.HTTPError as e:
|
||||||
raise FDroidException(_('Downloading %s failed. %s'), (url, e))
|
raise FDroidException(_('Downloading {url} failed. {error}')
|
||||||
|
.format(url=url, error=e))
|
||||||
|
|
||||||
compare_result = common.verify_apks(
|
compare_result = common.verify_apks(
|
||||||
remoteapk,
|
remoteapk,
|
||||||
|
|
|
||||||
37
locale/Makefile
Normal file
37
locale/Makefile
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
FILES = ../fdroid $(wildcard ../fdroidserver/*.py)
|
||||||
|
|
||||||
|
# these are the supported languages
|
||||||
|
ALL_LINGUAS = de es pt_BR pt_PT tr zh_Hans zh_Hant
|
||||||
|
POFILES = $(ALL_LINGUAS:=/LC_MESSAGES/fdroidserver.po)
|
||||||
|
MOFILES = $(ALL_LINGUAS:=/LC_MESSAGES/fdroidserver.mo)
|
||||||
|
|
||||||
|
TEMPLATE = fdroidserver.pot
|
||||||
|
|
||||||
|
VERSION = $(shell git describe)
|
||||||
|
|
||||||
|
# generate .mo files from the .po files
|
||||||
|
all-local: $(MOFILES)
|
||||||
|
|
||||||
|
clean-local:
|
||||||
|
-rm -f -- $(MOFILES)
|
||||||
|
-rm -f -- $(POFILES:=~)
|
||||||
|
|
||||||
|
# refresh the template from the source code
|
||||||
|
template: $(TEMPLATE)
|
||||||
|
|
||||||
|
$(TEMPLATE): $(FILES)
|
||||||
|
xgettext --join-existing --from-code=UTF-8 \
|
||||||
|
--language=Python --keyword=_ \
|
||||||
|
--sort-output --no-location --output=$(TEMPLATE) \
|
||||||
|
--package-name="fdroidserver" --package-version=$(VERSION) \
|
||||||
|
--foreign-user \
|
||||||
|
--msgid-bugs-address=https://gitlab.com/fdroid/fdroidserver/issues \
|
||||||
|
$(FILES)
|
||||||
|
sed -i 's,CHARSET,UTF-8,' $(TEMPLATE)
|
||||||
|
|
||||||
|
%/LC_MESSAGES/fdroidserver.mo: %/LC_MESSAGES/fdroidserver.po
|
||||||
|
msgfmt --check -o $@ $(@:mo=po)
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY = all-local clean-local template
|
||||||
|
|
@ -1,400 +0,0 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: team@f-droid.org\n"
|
|
||||||
"POT-Creation-Date: 2017-06-01 17:23+0200\n"
|
|
||||||
"PO-Revision-Date: 2017-06-18 20:41+0000\n"
|
|
||||||
"Last-Translator: monolifed <monolifed@gmail.com>\n"
|
|
||||||
"Language-Team: English "
|
|
||||||
"<https://hosted.weblate.org/projects/f-droid/fdroidserver/en/>\n"
|
|
||||||
"Language: en\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
|
||||||
"X-Generator: Weblate 2.15-dev\n"
|
|
||||||
|
|
||||||
#: ../fdroid:34
|
|
||||||
msgid "Build a package from source"
|
|
||||||
msgstr "Build a package from source"
|
|
||||||
|
|
||||||
#: ../fdroid:35
|
|
||||||
msgid "Quickly start a new repository"
|
|
||||||
msgstr "Quickly start a new repository"
|
|
||||||
|
|
||||||
#: ../fdroid:36
|
|
||||||
msgid "Sign and place packages in the repo"
|
|
||||||
msgstr "Sign and place packages in the repo"
|
|
||||||
|
|
||||||
#: ../fdroid:37
|
|
||||||
msgid "Add gpg signatures for packages in repo"
|
|
||||||
msgstr "Add GPG signatures for packages in repo"
|
|
||||||
|
|
||||||
#: ../fdroid:38
|
|
||||||
msgid "Update repo information for new packages"
|
|
||||||
msgstr "Update repo information for new packages"
|
|
||||||
|
|
||||||
#: ../fdroid:39
|
|
||||||
msgid "Verify the integrity of downloaded packages"
|
|
||||||
msgstr "Verify the integrity of downloaded packages"
|
|
||||||
|
|
||||||
#: ../fdroid:40
|
|
||||||
msgid "Check for updates to applications"
|
|
||||||
msgstr "Check for updates to applications"
|
|
||||||
|
|
||||||
#: ../fdroid:41
|
|
||||||
msgid "Add a new application from its source code"
|
|
||||||
msgstr "Add a new application from its source code"
|
|
||||||
|
|
||||||
#: ../fdroid:42
|
|
||||||
msgid "Install built packages on devices"
|
|
||||||
msgstr "Install built packages on devices"
|
|
||||||
|
|
||||||
#: ../fdroid:43
|
|
||||||
msgid "Read all the metadata files and exit"
|
|
||||||
msgstr "Read all the metadata files and exit"
|
|
||||||
|
|
||||||
#: ../fdroid:44
|
|
||||||
msgid "Rewrite all the metadata files"
|
|
||||||
msgstr "Rewrite all the metadata files"
|
|
||||||
|
|
||||||
#: ../fdroid:45
|
|
||||||
msgid "Warn about possible metadata errors"
|
|
||||||
msgstr "Warn about possible metadata errors"
|
|
||||||
|
|
||||||
#: ../fdroid:46
|
|
||||||
msgid "Scan the source code of a package"
|
|
||||||
msgstr "Scan the source code of a package"
|
|
||||||
|
|
||||||
#: ../fdroid:47
|
|
||||||
msgid "Dynamically scan APKs post build"
|
|
||||||
msgstr "Dynamically scan APKs post build"
|
|
||||||
|
|
||||||
#: ../fdroid:48
|
|
||||||
msgid "Update the stats of the repo"
|
|
||||||
msgstr "Update the stats of the repo"
|
|
||||||
|
|
||||||
#: ../fdroid:49
|
|
||||||
msgid "Interact with the repo HTTP server"
|
|
||||||
msgstr "Interact with the repo HTTP server"
|
|
||||||
|
|
||||||
#: ../fdroid:50
|
|
||||||
msgid "Sign indexes created using update --nosign"
|
|
||||||
msgstr "Sign indexes created using update --nosign"
|
|
||||||
|
|
||||||
#: ../fdroid:51
|
|
||||||
msgid "Update the binary transparency log for a URL"
|
|
||||||
msgstr "Update the binary transparency log for a URL"
|
|
||||||
|
|
||||||
#: ../fdroid:56
|
|
||||||
msgid "usage: fdroid [-h|--help|--version] <command> [<args>]"
|
|
||||||
msgstr "usage: fdroid [-h|--help|--version] <command> [<args>]"
|
|
||||||
|
|
||||||
#: ../fdroid:58
|
|
||||||
msgid "Valid commands are:"
|
|
||||||
msgstr "Valid commands are:"
|
|
||||||
|
|
||||||
#: ../fdroid:104
|
|
||||||
#, c-format
|
|
||||||
msgid "Command '%s' not recognised.\n"
|
|
||||||
msgstr "Command '%s' not recognised.\n"
|
|
||||||
|
|
||||||
#: ../fdroid:150
|
|
||||||
msgid "Unknown exception found!"
|
|
||||||
msgstr "Unknown exception found!"
|
|
||||||
|
|
||||||
#: ../fdroidserver/btlog.py:154
|
|
||||||
msgid "Path to the git repo to use as the log"
|
|
||||||
msgstr "Path to the git repo to use as the log"
|
|
||||||
|
|
||||||
#: ../fdroidserver/btlog.py:156
|
|
||||||
msgid "The base URL for the repo to log (default: https://f-droid.org)"
|
|
||||||
msgstr "The base URL for the repo to log (default: https://f-droid.org)"
|
|
||||||
|
|
||||||
#: ../fdroidserver/btlog.py:158
|
|
||||||
msgid "Push the log to this git remote repository"
|
|
||||||
msgstr "Push the log to this git remote repository"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:875 ../fdroidserver/install.py:52
|
|
||||||
#: ../fdroidserver/publish.py:45 ../fdroidserver/scanner.py:255
|
|
||||||
#: ../fdroidserver/verify.py:41
|
|
||||||
msgid "app-id with optional versionCode in the form APPID[:VERCODE]"
|
|
||||||
msgstr "app-id with optional versionCode in the form APPID[:VERCODE]"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:877
|
|
||||||
msgid "Build only the latest version of each package"
|
|
||||||
msgstr "Build only the latest version of each package"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:879
|
|
||||||
msgid "Make the build stop on exceptions"
|
|
||||||
msgstr "Make the build stop on exceptions"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:881
|
|
||||||
msgid ""
|
|
||||||
"Test mode - put output in the tmp directory only, and always build, even if "
|
|
||||||
"the output already exists."
|
|
||||||
msgstr ""
|
|
||||||
"Test mode - put output in the tmp directory only, and always build, even if "
|
|
||||||
"the output already exists."
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:883
|
|
||||||
msgid "Use build server"
|
|
||||||
msgstr "Use build server"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:885
|
|
||||||
msgid ""
|
|
||||||
"Reset and create a brand new build server, even if the existing one appears "
|
|
||||||
"to be ok."
|
|
||||||
msgstr ""
|
|
||||||
"Reset and create a brand new build server, even if the existing one appears "
|
|
||||||
"to be OK."
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:887
|
|
||||||
msgid "Specify that we're running on the build server"
|
|
||||||
msgstr "Specify that we're running on the build server"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:889
|
|
||||||
msgid "Skip scanning the source code for binaries and other problems"
|
|
||||||
msgstr "Skip scanning of the source code for binaries and other problems"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:891
|
|
||||||
msgid "Setup an emulator, install the apk on it and perform a drozer scan"
|
|
||||||
msgstr "Setup an emulator, install the APK on it and perform a Drozer scan"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:893
|
|
||||||
msgid "Don't create a source tarball, useful when testing a build"
|
|
||||||
msgstr "Don't create a source tarball, useful when testing a build"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:895
|
|
||||||
msgid ""
|
|
||||||
"Don't refresh the repository, useful when testing a build with no internet "
|
|
||||||
"connection"
|
|
||||||
msgstr ""
|
|
||||||
"Don't refresh the repository, useful when testing a build with no internet "
|
|
||||||
"connection"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:897
|
|
||||||
msgid ""
|
|
||||||
"Force build of disabled apps, and carries on regardless of scan problems. "
|
|
||||||
"Only allowed in test mode."
|
|
||||||
msgstr ""
|
|
||||||
"Force build of disabled apps, and carries on regardless of scan problems. "
|
|
||||||
"Only allowed in test mode."
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:899
|
|
||||||
msgid "Build all applications available"
|
|
||||||
msgstr "Build all applications available"
|
|
||||||
|
|
||||||
#: ../fdroidserver/build.py:901 ../fdroidserver/update.py:1519
|
|
||||||
msgid "Update the wiki"
|
|
||||||
msgstr "Update the wiki"
|
|
||||||
|
|
||||||
#: ../fdroidserver/checkupdates.py:513
|
|
||||||
msgid "app-id to check for updates"
|
|
||||||
msgstr "app-id to check for updates"
|
|
||||||
|
|
||||||
#: ../fdroidserver/checkupdates.py:515
|
|
||||||
msgid "Process auto-updates"
|
|
||||||
msgstr "Process auto-updates"
|
|
||||||
|
|
||||||
#: ../fdroidserver/checkupdates.py:517
|
|
||||||
msgid "Only process apps with auto-updates"
|
|
||||||
msgstr "Only process apps with auto-updates"
|
|
||||||
|
|
||||||
#: ../fdroidserver/checkupdates.py:519
|
|
||||||
msgid "Commit changes"
|
|
||||||
msgstr "Commit changes"
|
|
||||||
|
|
||||||
#: ../fdroidserver/checkupdates.py:521
|
|
||||||
msgid "Only print differences with the Play Store"
|
|
||||||
msgstr "Only print differences with the Play Store"
|
|
||||||
|
|
||||||
#: ../fdroidserver/common.py:124
|
|
||||||
msgid "Spew out even more information than normal"
|
|
||||||
msgstr "Spew out even more information than normal"
|
|
||||||
|
|
||||||
#: ../fdroidserver/common.py:126
|
|
||||||
msgid "Restrict output to warnings and errors"
|
|
||||||
msgstr "Restrict output to warnings and errors"
|
|
||||||
|
|
||||||
#: ../fdroidserver/dscanner.py:410
|
|
||||||
msgid "app-id with optional versioncode in the form APPID[:VERCODE]"
|
|
||||||
msgstr "app-id with optional versioncode in the form APPID[:VERCODE]"
|
|
||||||
|
|
||||||
#: ../fdroidserver/dscanner.py:413
|
|
||||||
msgid "Scan only the latest version of each package"
|
|
||||||
msgstr "Scan only the latest version of each package"
|
|
||||||
|
|
||||||
#: ../fdroidserver/dscanner.py:416
|
|
||||||
msgid "Clean after all scans have finished"
|
|
||||||
msgstr "Clean after all scans have finished"
|
|
||||||
|
|
||||||
#: ../fdroidserver/dscanner.py:419
|
|
||||||
msgid "Clean before the scans start and rebuild the container"
|
|
||||||
msgstr "Clean before the scans start and rebuild the container"
|
|
||||||
|
|
||||||
#: ../fdroidserver/dscanner.py:422
|
|
||||||
msgid "Clean up all containers and then exit"
|
|
||||||
msgstr "Clean up all containers and then exit"
|
|
||||||
|
|
||||||
#: ../fdroidserver/dscanner.py:425
|
|
||||||
msgid "Prepare drozer to run a scan"
|
|
||||||
msgstr "Prepare Drozer to run a scan"
|
|
||||||
|
|
||||||
#: ../fdroidserver/dscanner.py:428
|
|
||||||
msgid "Override path for repo APKs (default: ./repo)"
|
|
||||||
msgstr "Override path for repo APKs (default: ./repo)"
|
|
||||||
|
|
||||||
#: ../fdroidserver/import.py:193
|
|
||||||
msgid "Project URL to import from."
|
|
||||||
msgstr "Project URL to import from."
|
|
||||||
|
|
||||||
#: ../fdroidserver/import.py:195
|
|
||||||
msgid "Path to main android project subdirectory, if not in root."
|
|
||||||
msgstr "Path to main Android project subdirectory, if not in root."
|
|
||||||
|
|
||||||
#: ../fdroidserver/import.py:197
|
|
||||||
msgid "Comma separated list of categories."
|
|
||||||
msgstr "Comma separated list of categories."
|
|
||||||
|
|
||||||
#: ../fdroidserver/import.py:199
|
|
||||||
msgid "Overall license of the project."
|
|
||||||
msgstr "Overall license of the project."
|
|
||||||
|
|
||||||
#: ../fdroidserver/import.py:201
|
|
||||||
msgid ""
|
|
||||||
"Allows a different revision (or git branch) to be specified for the initial "
|
|
||||||
"import"
|
|
||||||
msgstr ""
|
|
||||||
"Allows a different revision (or git branch) to be specified for the initial "
|
|
||||||
"import"
|
|
||||||
|
|
||||||
#: ../fdroidserver/init.py:56
|
|
||||||
msgid "X.509 'Distiguished Name' used when generating keys"
|
|
||||||
msgstr "X.509 'Distinguished Name' used when generating keys"
|
|
||||||
|
|
||||||
#: ../fdroidserver/init.py:58
|
|
||||||
msgid "Path to the keystore for the repo signing key"
|
|
||||||
msgstr "Path to the keystore for the repo signing key"
|
|
||||||
|
|
||||||
#: ../fdroidserver/init.py:60
|
|
||||||
msgid "Alias of the repo signing key in the keystore"
|
|
||||||
msgstr "Alias of the repo signing key in the keystore"
|
|
||||||
|
|
||||||
#: ../fdroidserver/init.py:62
|
|
||||||
msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)"
|
|
||||||
msgstr "Path to the Android SDK (sometimes set in ANDROID_HOME)"
|
|
||||||
|
|
||||||
#: ../fdroidserver/init.py:64
|
|
||||||
msgid "Do not prompt for Android SDK path, just fail"
|
|
||||||
msgstr "Do not prompt for Android SDK path, just fail"
|
|
||||||
|
|
||||||
#: ../fdroidserver/install.py:54
|
|
||||||
msgid "Install all signed applications available"
|
|
||||||
msgstr "Install all signed applications available"
|
|
||||||
|
|
||||||
#: ../fdroidserver/lint.py:393
|
|
||||||
msgid "Also warn about formatting issues, like rewritemeta -l"
|
|
||||||
msgstr "Also warn about formatting issues, like rewritemeta -l"
|
|
||||||
|
|
||||||
#: ../fdroidserver/lint.py:394 ../fdroidserver/rewritemeta.py:57
|
|
||||||
msgid "app-id in the form APPID"
|
|
||||||
msgstr "app-id in the form APPID"
|
|
||||||
|
|
||||||
#: ../fdroidserver/metadata.py:1337
|
|
||||||
msgid "force errors to be warnings, or ignore"
|
|
||||||
msgstr "force errors to be warnings, or ignore"
|
|
||||||
|
|
||||||
#: ../fdroidserver/rewritemeta.py:54
|
|
||||||
msgid "List files that would be reformatted"
|
|
||||||
msgstr "List files that would be reformatted"
|
|
||||||
|
|
||||||
#: ../fdroidserver/rewritemeta.py:56
|
|
||||||
msgid "Rewrite to a specific format: "
|
|
||||||
msgstr "Rewrite in a specific format: "
|
|
||||||
|
|
||||||
#: ../fdroidserver/server.py:547
|
|
||||||
msgid "command to execute, either 'init' or 'update'"
|
|
||||||
msgstr "command to execute, either 'init' or 'update'"
|
|
||||||
|
|
||||||
#: ../fdroidserver/server.py:549
|
|
||||||
msgid "Specify an identity file to provide to SSH for rsyncing"
|
|
||||||
msgstr "Specify an identity file to provide to SSH for rsyncing"
|
|
||||||
|
|
||||||
#: ../fdroidserver/server.py:551
|
|
||||||
msgid "Specify a local folder to sync the repo to"
|
|
||||||
msgstr "Specify a local folder to sync the repo to"
|
|
||||||
|
|
||||||
#: ../fdroidserver/server.py:553
|
|
||||||
msgid "Don't use rsync checksums"
|
|
||||||
msgstr "Don't use rsync checksums"
|
|
||||||
|
|
||||||
#: ../fdroidserver/stats.py:64
|
|
||||||
msgid "Download logs we don't have"
|
|
||||||
msgstr "Download logs we don't have"
|
|
||||||
|
|
||||||
#: ../fdroidserver/stats.py:66
|
|
||||||
msgid "Recalculate aggregate stats - use when changes "
|
|
||||||
msgstr "Recalculate aggregate stats - use when changes "
|
|
||||||
|
|
||||||
#: ../fdroidserver/stats.py:69
|
|
||||||
msgid "Don't do anything logs-related"
|
|
||||||
msgstr "Don't do anything logs-related"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1504
|
|
||||||
msgid "Create a repo signing key in a keystore"
|
|
||||||
msgstr "Create a repo signing key in a keystore"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1506
|
|
||||||
msgid "Create skeleton metadata files that are missing"
|
|
||||||
msgstr "Create skeleton metadata files that are missing"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1508
|
|
||||||
msgid "Delete APKs and/or OBBs without metadata from the repo"
|
|
||||||
msgstr "Delete APKs and/or OBBs without metadata from the repo"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1510
|
|
||||||
msgid "Report on build data status"
|
|
||||||
msgstr "Report on build data status"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1512
|
|
||||||
msgid "Interactively ask about things that need updating."
|
|
||||||
msgstr "Interactively ask about things that need updating."
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1514
|
|
||||||
msgid "Resize all the icons exceeding the max pixel size and exit"
|
|
||||||
msgstr "Resize all the icons exceeding the max pixel size and exit"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1516
|
|
||||||
#, c-format
|
|
||||||
msgid "Specify editor to use in interactive mode. Default %s"
|
|
||||||
msgstr "Specify editor to use in interactive mode. Default %s"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1521
|
|
||||||
msgid "Produce human-readable index.xml"
|
|
||||||
msgstr "Produce human-readable index.xml"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1523
|
|
||||||
msgid "Clean update - don't uses caches, reprocess all apks"
|
|
||||||
msgstr "Clean update - don't uses caches, reprocess all APKs"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1525
|
|
||||||
msgid ""
|
|
||||||
"When configured for signed indexes, create only unsigned indexes at this "
|
|
||||||
"stage"
|
|
||||||
msgstr ""
|
|
||||||
"When configured for signed indexes, create only unsigned indexes at this "
|
|
||||||
"stage"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1527
|
|
||||||
msgid "Use date from apk instead of current time for newly added apks"
|
|
||||||
msgstr "Use date from APK instead of current time for newly added APKs"
|
|
||||||
|
|
||||||
#: ../fdroidserver/update.py:1529
|
|
||||||
msgid "Rename APK files that do not match package.name_123.apk"
|
|
||||||
msgstr "Rename APK files that do not match package.name_123.apk"
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue