From 868516f3fdbd2c20bab7018dfc247f0031ceeef9 Mon Sep 17 00:00:00 2001 From: Michael von Glasow Date: Tue, 15 Jan 2019 12:36:17 +0000 Subject: [PATCH 0001/2775] Clarify warning message about skipped sudo commands --- fdroidserver/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 375003e3..7acc94e9 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -392,7 +392,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext f.write(common.get_android_tools_version_log(build.ndk_path())) else: if build.sudo: - logging.warning('%s:%s runs this on the buildserver with sudo:\n\t%s' + logging.warning('%s:%s runs this on the buildserver with sudo:\n\t%s\nThese commands were skipped because fdroid build is running without the --on-server option.' % (app.id, build.versionName, build.sudo)) # Prepare the source code... From f8f17a430d42419330b581c086fd9caf3c7df657 Mon Sep 17 00:00:00 2001 From: Michael von Glasow Date: Tue, 15 Jan 2019 14:14:09 +0000 Subject: [PATCH 0002/2775] Reword warning message about sudo commands being skipped --- fdroidserver/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 7acc94e9..5347475b 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -392,7 +392,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext f.write(common.get_android_tools_version_log(build.ndk_path())) else: if build.sudo: - logging.warning('%s:%s runs this on the buildserver with sudo:\n\t%s\nThese commands were skipped because fdroid build is running without the --on-server option.' + logging.warning('%s:%s runs this on the buildserver with sudo:\n\t%s\nThese commands were skipped because fdroid build is not running on a dedicated build server.' % (app.id, build.versionName, build.sudo)) # Prepare the source code... From 6634407c60a345045743378eabf6bc6f2803530e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 3 Feb 2019 16:52:12 +0100 Subject: [PATCH 0003/2775] update: allow tests to pass when apksigner is not installed This is only for the v2/v3 signatures. fdroid/fdroidserver#627 --- tests/update.TestCase | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/update.TestCase b/tests/update.TestCase index 1210c78e..bce7e41c 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -408,13 +408,16 @@ class UpdateTest(unittest.TestCase): print('USE_ANDROGUARD', use_androguard) - apksigner = fdroidserver.common.find_sdk_tools_cmd('apksigner') - if use_androguard and apksigner: # v2 parsing needs both - config['apksigner'] = apksigner - apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') - self.assertIsNone(apk_info.get('maxSdkVersion')) - self.assertEqual(apk_info.get('versionName'), 'v2-only') - self.assertEqual(apk_info.get('versionCode'), 2) + try: + apksigner = fdroidserver.common.find_sdk_tools_cmd('apksigner') + if use_androguard and apksigner: # v2 parsing needs both + config['apksigner'] = apksigner + apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') + self.assertIsNone(apk_info.get('maxSdkVersion')) + self.assertEqual(apk_info.get('versionName'), 'v2-only') + self.assertEqual(apk_info.get('versionCode'), 2) + except fdroidserver.exception.FDroidException: + print('WARNING: skipping v2-only test since apksigner cannot be found') apk_info = fdroidserver.update.scan_apk('repo/v1.v2.sig_1020.apk') self.assertIsNone(apk_info.get('maxSdkVersion')) From b3754af137761b6cd427601a9131ea033199c4d4 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Thu, 7 Feb 2019 10:26:03 +0100 Subject: [PATCH 0004/2775] Add cloudrail to blacklist --- fdroidserver/scanner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 2d9e2a1d..7c3dddef 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -76,6 +76,7 @@ def scan_source(build_dir, build=metadata.Build()): r'libspen23', r'firebase', r'''["']com.facebook.android['":]''', + r'cloudrail', ] } From 94c6b776fe8b29c5e9ca6c09da163b72c03cfd44 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 7 Feb 2019 19:48:03 +0100 Subject: [PATCH 0005/2775] build: log buildserver guest ram + cpu --- fdroidserver/build.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 9052f262..0b1c4fb2 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -1283,6 +1283,17 @@ def main(): if m: txt += "* host RAM: %s\n" % m.group(1) break + fdroid_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) + buildserver_config = os.path.join(fdroid_path, 'makebuildserver.config.py') + if os.path.isfile(buildserver_config) and os.access(buildserver_config, os.R_OK): + with open(buildserver_config) as configfile: + for line in configfile: + m = re.search(r'cpus\s*=\s*([0-9].*)', line) + if m: + txt += "* guest processors: %s\n" % m.group(1) + m = re.search(r'memory\s*=\s*([0-9].*)', line) + if m: + txt += "* guest RAM: %s MB\n" % m.group(1) txt += "* successful builds: %d\n" % len(build_succeeded) txt += "* failed builds: %d\n" % len(failed_apps) txt += "\n\n" From d03b12115279e13e576c61fefc9e9fdf7d243a68 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 3 Feb 2019 16:52:12 +0100 Subject: [PATCH 0006/2775] update: allow tests to pass when apksigner is not installed This is only for the v2/v3 signatures. fdroid/fdroidserver#627 --- tests/update.TestCase | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/update.TestCase b/tests/update.TestCase index 1210c78e..bce7e41c 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -408,13 +408,16 @@ class UpdateTest(unittest.TestCase): print('USE_ANDROGUARD', use_androguard) - apksigner = fdroidserver.common.find_sdk_tools_cmd('apksigner') - if use_androguard and apksigner: # v2 parsing needs both - config['apksigner'] = apksigner - apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') - self.assertIsNone(apk_info.get('maxSdkVersion')) - self.assertEqual(apk_info.get('versionName'), 'v2-only') - self.assertEqual(apk_info.get('versionCode'), 2) + try: + apksigner = fdroidserver.common.find_sdk_tools_cmd('apksigner') + if use_androguard and apksigner: # v2 parsing needs both + config['apksigner'] = apksigner + apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') + self.assertIsNone(apk_info.get('maxSdkVersion')) + self.assertEqual(apk_info.get('versionName'), 'v2-only') + self.assertEqual(apk_info.get('versionCode'), 2) + except fdroidserver.exception.FDroidException: + print('WARNING: skipping v2-only test since apksigner cannot be found') apk_info = fdroidserver.update.scan_apk('repo/v1.v2.sig_1020.apk') self.assertIsNone(apk_info.get('maxSdkVersion')) From 94affe9421e1e739d9690b070e117866ad634199 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 3 Feb 2019 15:58:20 +0100 Subject: [PATCH 0007/2775] version 1.2 alpha --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6a4aac60..f491e631 100755 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ def get_data_files(): setup(name='fdroidserver', - version='1.1.1', + version='1.2a', description='F-Droid Server Tools', long_description='README.md', long_description_content_type='text/markdown', From 40edb1a87ddfce280230da62eae6262f6ee00935 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 12 Feb 2019 20:38:40 +0100 Subject: [PATCH 0008/2775] jenkins: purge libvirt, the runner is now baremetal+virtualbox --- jenkins-build-all | 4 ---- jenkins-setup-build-environment | 16 ---------------- 2 files changed, 20 deletions(-) diff --git a/jenkins-build-all b/jenkins-build-all index 08e28ed7..2765ab63 100755 --- a/jenkins-build-all +++ b/jenkins-build-all @@ -39,12 +39,8 @@ if systemd-detect-virt -q ; then else echo "No virtualization is used." fi -sudo /bin/chmod -R a+rX /var/lib/libvirt/images echo 'maximum allowed number of open file descriptors: ' `ulimit -n` -ls -ld /var/lib/libvirt/images -ls -l /var/lib/libvirt/images || echo no access ls -lR ~/.vagrant.d/ || echo no access -virsh --connect qemu:///system list --all || echo cannot virsh list cat /etc/issue /sbin/ifconfig || true diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index 62c4e009..3117dfb7 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -26,7 +26,6 @@ cleanup_all() { set +e echo "$(date -u) - cleanup in progress..." ps auxww | grep -e VBox -e qemu - virsh --connect qemu:///system list --all ls -hl /var/lib/libvirt/images cd $WORKSPACE/buildserver vagrant halt @@ -54,21 +53,6 @@ fi export VAGRANT_HOME=$WORKSPACE/vagrant.d mkdir $VAGRANT_HOME -# delete leftovers from previous run -virsh -c qemu:///system undefine buildserver_default \ - --nvram --managed-save --remove-all-storage --snapshots-metadata || true -virsh -c qemu:///system undefine builder_default \ - --nvram --managed-save --remove-all-storage --snapshots-metadata || true -virsh -c qemu:///system undefine basebox-stretch64 \ - --nvram --managed-save --remove-all-storage --snapshots-metadata || true - -virsh -c qemu:///system vol-delete --pool default \ - /var/lib/libvirt/images/buildserver_vagrant_box_image_0.img || true -virsh -c qemu:///system vol-delete --pool default \ - /var/lib/libvirt/images/basebox-stretch64_vagrant_box_image_0.img || true -virsh -c qemu:///system vol-delete --pool default \ - /var/lib/libvirt/images/jessie64_vagrant_box_image_0.img || true - rm -rf "$WORKSPACE"/../*/.testfiles cd $WORKSPACE From b3cd020edb16424fa31935fe3ed3383138f3d4b6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 12 Feb 2019 20:42:17 +0100 Subject: [PATCH 0009/2775] jenkins: update makebuildserver.config.py based on new specs --- jenkins-setup-build-environment | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index 3117dfb7..74286cd2 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -56,12 +56,14 @@ mkdir $VAGRANT_HOME rm -rf "$WORKSPACE"/../*/.testfiles cd $WORKSPACE -echo "debian_mirror = 'https://deb.debian.org/debian/'" > $WORKSPACE/makebuildserver.config.py -echo "boot_timeout = 1200" >> $WORKSPACE/makebuildserver.config.py -echo "apt_package_cache = True" >> $WORKSPACE/makebuildserver.config.py -echo "copy_caches_from_host = True" >> $WORKSPACE/makebuildserver.config.py -echo "memory = 6144" >> $WORKSPACE/makebuildserver.config.py -echo "cpus = 2" >> $WORKSPACE/makebuildserver.config.py +cat < $WORKSPACE/makebuildserver.config.py +debian_mirror = 'http://deb.debian.org/debian/'" +boot_timeout = 1200 +apt_package_cache = True +copy_caches_from_host = True +memory = 8192 +cpus = 6 +EOF ./makebuildserver -vv --clean if [ -z "`vagrant box list | egrep '^buildserver\s+\((libvirt|virtualbox), [0-9]+\)$'`" ]; then From 9be0b3733be570a166a62f5e26cab8ca306b3576 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 12 Feb 2019 21:05:56 +0100 Subject: [PATCH 0010/2775] jenkins: switch test fdroidclient build to version we care about 96150 is so old, we no longer install the required version of build-tools: v23.0.0 --- jenkins-setup-build-environment | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index 74286cd2..c1e24395 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -102,4 +102,4 @@ fi # Gradle, JNI, preassemble ../fdroid build --verbose --stop org.adaway:55 # building old versions should still work -../fdroid build --verbose --stop org.fdroid.fdroid:96150 +../fdroid build --verbose --stop org.fdroid.fdroid:102350 From 40cf7311d01d2c98da081a0a9ee01c16cc72f76b Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 13 Feb 2019 18:37:26 +0100 Subject: [PATCH 0011/2775] add gradle 5.2 and 5.2.1 Only install 5.2.1 into the buildserver though. It took only 4 days until 5.2.1 came out and gradle.org recommends using the latest patch release. --- gradlew-fdroid | 4 +++- makebuildserver | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index f8375627..ffd71924 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -114,6 +114,8 @@ get_sha() { ["5.0"]="6157ac9f3410bc63644625b3b3e9e96c963afd7910ae0697792db57813ee79a6" \ ["5.1"]="7506638a380092a0406364c79d6c87d03d23017fc25a5770379d1ce23c3fcd4d" \ ["5.1.1"]="4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798" \ + ["5.2"]="ff322863250159595e93b5a4d17a6f0d21c59a1a0497c1e1cf1d53826485503f" \ + ["5.2.1"]="748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357" \ ) [ ! ${gradle_hashes[$1]+abc} ] && exit 1 echo "${gradle_hashes["$1"]}" @@ -135,7 +137,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 79ce4bac..fd17d666 100755 --- a/makebuildserver +++ b/makebuildserver @@ -370,6 +370,8 @@ cachefiles = [ '7506638a380092a0406364c79d6c87d03d23017fc25a5770379d1ce23c3fcd4d'), ('https://downloads.gradle.org/distributions/gradle-5.1.1-bin.zip', '4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798'), + ('https://downloads.gradle.org/distributions/gradle-5.2.1-bin.zip', + '748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 0bc5287db0008b03bb6f4515790548d66a362e22 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 13 Feb 2019 18:39:17 +0100 Subject: [PATCH 0012/2775] Remove gradle 5.1 from default install gradle.org recommends using the latest patch release. It can still be downloaded on demand. --- makebuildserver | 2 -- 1 file changed, 2 deletions(-) diff --git a/makebuildserver b/makebuildserver index fd17d666..508601ff 100755 --- a/makebuildserver +++ b/makebuildserver @@ -366,8 +366,6 @@ cachefiles = [ '8626cbf206b4e201ade7b87779090690447054bc93f052954c78480fa6ed186e'), ('https://downloads.gradle.org/distributions/gradle-5.0-bin.zip', '6157ac9f3410bc63644625b3b3e9e96c963afd7910ae0697792db57813ee79a6'), - ('https://downloads.gradle.org/distributions/gradle-5.1-bin.zip', - '7506638a380092a0406364c79d6c87d03d23017fc25a5770379d1ce23c3fcd4d'), ('https://downloads.gradle.org/distributions/gradle-5.1.1-bin.zip', '4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798'), ('https://downloads.gradle.org/distributions/gradle-5.2.1-bin.zip', From 9963cf1abad60d191ba46be524789d1fc8aa1e86 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 14 Feb 2019 14:09:06 +0100 Subject: [PATCH 0013/2775] jenkins-setup-build-environment: fix typo --- jenkins-setup-build-environment | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index c1e24395..678772cd 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -57,7 +57,7 @@ rm -rf "$WORKSPACE"/../*/.testfiles cd $WORKSPACE cat < $WORKSPACE/makebuildserver.config.py -debian_mirror = 'http://deb.debian.org/debian/'" +debian_mirror = 'http://deb.debian.org/debian/' boot_timeout = 1200 apt_package_cache = True copy_caches_from_host = True From 8d9f885b1c393331bc06a136359adfea00104522 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 19 Feb 2019 15:43:35 +0100 Subject: [PATCH 0014/2775] makebuildserver: add ndk r19b --- buildserver/provision-android-ndk | 2 +- makebuildserver | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index ce5608a0..fd8659b7 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17b r18b r19; do +for version in r11c r12b r13b r14b r15c r16b r17b r18b r19b; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/makebuildserver b/makebuildserver index 508601ff..a5352d67 100755 --- a/makebuildserver +++ b/makebuildserver @@ -388,8 +388,8 @@ cachefiles = [ '5dfbbdc2d3ba859fed90d0e978af87c71a91a5be1f6e1c40ba697503d48ccecd'), ('https://dl.google.com/android/repository/android-ndk-r18b-linux-x86_64.zip', '4f61cbe4bbf6406aa5ef2ae871def78010eed6271af72de83f8bd0b07a9fd3fd'), - ('https://dl.google.com/android/repository/android-ndk-r19-linux-x86_64.zip', - 'c0a2425206191252197b97ea5fcc7eab9f693a576e69ef4773a9ed1690feed53'), + ('https://dl.google.com/android/repository/android-ndk-r19b-linux-x86_64.zip', + '0fbb1645d0f1de4dde90a4ff79ca5ec4899c835e729d692f433fda501623257a'), ] From daff6658c028e0dee5b6ab5a490d5320235395dd Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 20 Feb 2019 13:18:24 +0100 Subject: [PATCH 0015/2775] ndk r19b: missed a few places --- buildserver/config.buildserver.py | 2 +- examples/config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index aeeaa0e8..2d4ba76d 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -9,7 +9,7 @@ ndk_paths = { 'r16b': "/home/vagrant/android-ndk/r16b", 'r17b': "/home/vagrant/android-ndk/r17b", 'r18b': "/home/vagrant/android-ndk/r18b", - 'r19': "/home/vagrant/android-ndk/r19", + 'r19b': "/home/vagrant/android-ndk/r19b", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/examples/config.py b/examples/config.py index 5f0be273..a064fc8f 100644 --- a/examples/config.py +++ b/examples/config.py @@ -20,7 +20,7 @@ # 'r16b': None, # 'r17b': None, # 'r18b': None, -# 'r19': None, +# 'r19b': None, # } # Directory to store downloaded tools in (i.e. gradle versions) From 548f73d98877c3d69323daa9d3e3b8d5defc68bf Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 22 Feb 2019 21:32:33 +0100 Subject: [PATCH 0016/2775] nightly: search subdirs called 'fdroid' for APKs @MTRNord tracked down this bug while working on his app https://gitlab.com/Nordgedanken/simplematrix --- fdroidserver/nightly.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 9579ae50..e6f766c0 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -249,8 +249,8 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, common.assert_config_keystore(config) for root, dirs, files in os.walk(cibase): - for d in ('fdroid', '.git', '.gradle'): - if d in dirs: + for d in dirs: + if d == '.git' or d == '.gradle' or (d == 'fdroid' and root == cibase): dirs.remove(d) for f in files: if f.endswith('-debug.apk'): From 7798dcf9dd7c6a5f04bf82ded82661087d77a5e0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 22 Feb 2019 21:38:20 +0100 Subject: [PATCH 0017/2775] index: keep mirrors in the order specified in config.py The mirrors are displayed in fdroidclient in the order they are received, and there might be some reason why a repo maintainer wants them in a specific order. The danger is that if the mirrors are set in config.py using "mirrors = {'foo', bar'}" they will have a randomized order since it will be in a set. They should be set using [] or () to have a fixed order. --- fdroidserver/index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index d8477dc5..29027a38 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -88,7 +88,7 @@ def make(apps, sortedids, apks, repodir, archive): mirrorcheckfailed = False mirrors = [] - for mirror in sorted(common.config.get('mirrors', [])): + for mirror in common.config.get('mirrors', []): base = os.path.basename(urllib.parse.urlparse(mirror).path.rstrip('/')) if common.config.get('nonstandardwebroot') is not True and base != 'fdroid': logging.error(_("mirror '%s' does not end with 'fdroid'!") % mirror) From 67834697e0f2f3f60ffe158fba51009da658374f Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 26 Feb 2019 23:41:52 +0100 Subject: [PATCH 0018/2775] update: get localized text/images from Triple-T Play Publisher 2.x closes #579 closes #567 --- fdroidserver/update.py | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 58890074..d6e6ce35 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -750,14 +750,19 @@ def copy_triple_t_store_metadata(apps): the graphics files that are copied into the fdroid repo get properly indexed. - https://github.com/Triple-T/gradle-play-publisher#upload-images - https://github.com/Triple-T/gradle-play-publisher#play-store-metadata + https://github.com/Triple-T/gradle-play-publisher/blob/1.2.2/README.md#uploading-images + https://github.com/Triple-T/gradle-play-publisher/blob/1.2.2/README.md#play-store-metadata + https://github.com/Triple-T/gradle-play-publisher/blob/2.1.0/README.md#publishing-listings """ if not os.path.isdir('build'): return # nothing to do + tt_graphic_names = ('feature-graphic', 'icon', 'promo-graphic', 'tv-banner') + tt_screenshot_dirs = ('phone-screenshots', 'tablet-screenshots', + 'large-tablet-screenshots', 'tv-screenshots', 'wear-screenshots') + for packageName, app in apps.items(): for d in glob.glob(os.path.join('build', packageName, '*', 'src', '*', 'play')): logging.debug('Triple-T Gradle Play Publisher: ' + d) @@ -765,19 +770,19 @@ def copy_triple_t_store_metadata(apps): segments = root.split('/') locale = segments[-2] for f in files: - if f == 'fulldescription': + if f == 'fulldescription' or f == 'full-description.txt': _set_localized_text_entry(app, locale, 'description', os.path.join(root, f)) continue - elif f == 'shortdescription': + elif f == 'shortdescription' or f == 'short-description.txt': _set_localized_text_entry(app, locale, 'summary', os.path.join(root, f)) continue - elif f == 'title': + elif f == 'title' or f == 'title.txt': _set_localized_text_entry(app, locale, 'name', os.path.join(root, f)) continue - elif f == 'video': + elif f == 'video' or f == 'video-url.txt': _set_localized_text_entry(app, locale, 'video', os.path.join(root, f)) continue @@ -785,28 +790,38 @@ def copy_triple_t_store_metadata(apps): _set_localized_text_entry(app, segments[-1], 'whatsNew', os.path.join(root, f)) continue - elif f == 'contactEmail': + elif f == 'contactEmail' or f == 'contact-email.txt': _set_author_entry(app, 'authorEmail', os.path.join(root, f)) continue - elif f == 'contactPhone': + elif f == 'contactPhone' or f == 'contact-phone.txt': _set_author_entry(app, 'authorPhone', os.path.join(root, f)) continue - elif f == 'contactWebsite': + elif f == 'contactWebsite' or f == 'contact-website.txt': _set_author_entry(app, 'authorWebSite', os.path.join(root, f)) continue base, extension = common.get_extension(f) dirname = os.path.basename(root) if extension in ALLOWED_EXTENSIONS \ - and (dirname in GRAPHIC_NAMES or dirname in SCREENSHOT_DIRS): + and (dirname in GRAPHIC_NAMES or dirname in tt_graphic_names + or dirname in SCREENSHOT_DIRS or dirname in tt_screenshot_dirs): + repofilename = os.path.basename(f) if segments[-2] == 'listing': locale = segments[-3] + elif segments[-4] == 'listings': # v2.x + locale = segments[-3] + if dirname in tt_graphic_names: + repofilename = GRAPHIC_NAMES[tt_graphic_names.index(dirname)] + repofilename += '.' + extension + dirname = '' + else: + dirname = SCREENSHOT_DIRS[tt_screenshot_dirs.index(dirname)] else: locale = segments[-2] destdir = os.path.join('repo', packageName, locale, dirname) os.makedirs(destdir, mode=0o755, exist_ok=True) sourcefile = os.path.join(root, f) - destfile = os.path.join(destdir, os.path.basename(f)) + destfile = os.path.join(destdir, repofilename) logging.debug('copying ' + sourcefile + ' ' + destfile) _strip_and_copy_image(sourcefile, destfile) From c4a3354c7537b61b3cca65932b5af3db79fe8cec Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 27 Feb 2019 16:40:47 +0100 Subject: [PATCH 0019/2775] update: support flavors and alternate project dirs for Triple-T closes #542 --- fdroidserver/update.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index d6e6ce35..0b41c44e 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -762,9 +762,32 @@ def copy_triple_t_store_metadata(apps): tt_graphic_names = ('feature-graphic', 'icon', 'promo-graphic', 'tv-banner') tt_screenshot_dirs = ('phone-screenshots', 'tablet-screenshots', 'large-tablet-screenshots', 'tv-screenshots', 'wear-screenshots') + setting_gradle_pattern = re.compile(r"""\s*include\s+["']:([^"']+)["'](?:,[\n\s]*["']:([^"']+)["'])*""") for packageName, app in apps.items(): - for d in glob.glob(os.path.join('build', packageName, '*', 'src', '*', 'play')): + settings_gradle = os.path.join('build', packageName, 'settings.gradle') + gradle_subdirs = set() + if os.path.exists(settings_gradle): + with open(settings_gradle) as fp: + data = fp.read() + for matches in setting_gradle_pattern.findall(data): + for m in matches: + if m: + gradle_path = m.replace(':', '/') + p = os.path.join('build', packageName, gradle_path, 'src', 'main', 'play') + if os.path.exists(p): + gradle_subdirs.add(p) + flavors = set() + if app.builds: + flavors = app.builds[0].gradle + for flavor in flavors: + if flavor not in ('yes', 'no'): + p = os.path.join('build', packageName, gradle_path, 'src', flavor, 'play') + gradle_subdirs.add(p) + if not gradle_subdirs: + gradle_subdirs.update(glob.glob(os.path.join('build', packageName, '*', 'src', '*', 'play'))) + + for d in gradle_subdirs: logging.debug('Triple-T Gradle Play Publisher: ' + d) for root, dirs, files in os.walk(d): segments = root.split('/') From 102340ec5abf65aff3650299401a42b6cbb1fd00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 18 Mar 2019 16:01:34 +0100 Subject: [PATCH 0020/2775] fix fedora ci tests: install @development-tools Sometime pip dependencies required a C compiler because they need to compile something during installation. --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9828dbc4..98ffea9e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -161,7 +161,8 @@ fedora_latest: - echo "keepcache=True" >> /etc/dnf/dnf.conf - dnf -y update || dnf -y update - - dnf -y install findutils + - dnf -y install @development-tools + findutils git gnupg java-1.8.0-openjdk-devel From d4e5fdd95b5bda12aa0ba150827617a5dc7974cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 20 Feb 2019 15:54:32 +0100 Subject: [PATCH 0021/2775] use same logging setup as in all other fdroid scripts --- makebuildserver | 174 ++++++++++++++++++++++++------------------------ 1 file changed, 86 insertions(+), 88 deletions(-) diff --git a/makebuildserver b/makebuildserver index a5352d67..acc21411 100755 --- a/makebuildserver +++ b/makebuildserver @@ -32,27 +32,25 @@ parser.add_option('--keep-box-file', action="store_true", default=False, """ (KVM-only).""") options, args = parser.parse_args() -logger = logging.getLogger('fdroidserver-makebuildserver') -if options.verbosity >= 2: - logging.basicConfig(format='%(message)s', level=logging.DEBUG) - logger.setLevel(logging.DEBUG) -elif options.verbosity == 1: - logging.basicConfig(format='%(message)s', level=logging.INFO) - logger.setLevel(logging.INFO) + +logformat = '%(levelname)s: %(message)s' +loglevel = logging.DEBUG +if options.verbosity == 1: + loglevel = logging.INFO elif options.verbosity <= 0: - logging.basicConfig(format='%(message)s', level=logging.WARNING) - logger.setLevel(logging.WARNING) + loglevel = logging.WARNING +logging.basicConfig(format=logformat, level=loglevel) if not os.path.exists('makebuildserver') and not os.path.exists('buildserver'): - logger.critical('This must be run as ./makebuildserver in fdroidserver.git!') + logging.critical('This must be run as ./makebuildserver in fdroidserver.git!') sys.exit(1) tail = None # set up default config cachedir = os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver') -logger.debug('cachedir set to: %s', cachedir) +logging.debug('cachedir set to: %s', cachedir) BASEBOX_DEFAULT = 'fdroid/basebox-stretch64' BASEBOX_VERSION_DEFAULT = '0.5.1' @@ -117,11 +115,11 @@ if os.path.isfile('/usr/bin/systemd-detect-virt'): except subprocess.CalledProcessError: virt = 'none' if virt == 'qemu' or virt == 'kvm' or virt == 'bochs': - logger.info('Running in a VM guest, defaulting to QEMU/KVM via libvirt') + logging.info('Running in a VM guest, defaulting to QEMU/KVM via libvirt') config['vm_provider'] = 'libvirt' elif virt != 'none': - logger.info('Running in an unsupported VM guest (%s)!', virt) - logger.debug('detected virt: %s', virt) + logging.info('Running in an unsupported VM guest (%s)!', virt) + logging.debug('detected virt: %s', virt) # load config file, if present if os.path.exists('makebuildserver.config.py'): @@ -131,43 +129,43 @@ elif os.path.exists('makebs.config.py'): exec(compile(open('makebs.config.py').read(), 'makebs.config.py', 'exec'), config) if '__builtins__' in config: del(config['__builtins__']) # added by compile/exec -logger.debug("makebuildserver.config.py parsed -> %s", json.dumps(config, indent=4, sort_keys=True)) +logging.debug("makebuildserver.config.py parsed -> %s", json.dumps(config, indent=4, sort_keys=True)) if config['basebox'] == BASEBOX_DEFAULT and 'basebox_version' not in config: config['basebox_version'] = BASEBOX_VERSION_DEFAULT # note: vagrant allows putting '/' into the name of a local box, # so this check is not completely relyable, but better than nothing if 'basebox_version' in config and 'basebox' in config and '/' not in config['basebox']: - logger.critical("Can not get version '{version}' for basebox '{box}', " - "vagrant does not support versioning for locally added boxes." - .format(box=config['basebox'], version=config['basebox_version'])) + logging.critical("Can not get version '{version}' for basebox '{box}', " + "vagrant does not support versioning for locally added boxes." + .format(box=config['basebox'], version=config['basebox_version'])) # Update cached files. cachedir = config['cachedir'] if not os.path.exists(cachedir): os.makedirs(cachedir, 0o755) - logger.debug('created cachedir %s because it did not exists.', cachedir) + logging.debug('created cachedir %s because it did not exists.', cachedir) if config['vm_provider'] == 'libvirt': tmp = cachedir while tmp != '/': mode = os.stat(tmp).st_mode if not (stat.S_IXUSR & mode and stat.S_IXGRP & mode and stat.S_IXOTH & mode): - logger.critical('ERROR: %s will not be accessible to the VM! To fix, run:', tmp) - logger.critical(' chmod a+X %s', tmp) + logging.critical('ERROR: %s will not be accessible to the VM! To fix, run:', tmp) + logging.critical(' chmod a+X %s', tmp) sys.exit(1) tmp = os.path.dirname(tmp) - logger.debug('cache dir %s is accessible for libvirt vm.', cachedir) + logging.debug('cache dir %s is accessible for libvirt vm.', cachedir) if config['apt_package_cache']: config['aptcachedir'] = cachedir + '/apt/archives' - logger.debug('aptcachedir is set to %s', config['aptcachedir']) + logging.debug('aptcachedir is set to %s', config['aptcachedir']) aptcachelock = os.path.join(config['aptcachedir'], 'lock') if os.path.isfile(aptcachelock): - logger.info('apt cache dir is locked, removing lock') + logging.info('apt cache dir is locked, removing lock') os.remove(aptcachelock) aptcachepartial = os.path.join(config['aptcachedir'], 'partial') if os.path.isdir(aptcachepartial): - logger.info('removing partial downloads from apt cache dir') + logging.info('removing partial downloads from apt cache dir') shutil.rmtree(aptcachepartial) cachefiles = [ @@ -406,14 +404,14 @@ def sha256_for_file(path): def verify_file_sha256(path, sha256): if sha256_for_file(path) != sha256: - logger.critical("File verification for '{path}' failed! " - "expected sha256 checksum: {checksum}" - .format(path=path, checksum=sha256)) + logging.critical("File verification for '{path}' failed! " + "expected sha256 checksum: {checksum}" + .format(path=path, checksum=sha256)) sys.exit(1) else: - logger.debug("sucessfully verifyed file '{path}' " - "('{checksum}')".format(path=path, - checksum=sha256)) + logging.debug("sucessfully verifyed file '{path}' " + "('{checksum}')".format(path=path, + checksum=sha256)) def get_vagrant_home(): @@ -437,7 +435,7 @@ def update_cache(cachedir, cachefiles): if os.path.exists(local_filename): if sha256_for_file(local_filename) == shasum: - logger.info("\t...shasum verified for %s", local_filename) + logging.info("\t...shasum verified for %s", local_filename) continue local_length = os.path.getsize(local_filename) else: @@ -454,19 +452,19 @@ def update_cache(cachedir, cachefiles): content_length = local_length # skip the download except requests.exceptions.RequestException as e: content_length = local_length # skip the download - logger.warn('%s', e) + logging.warn('%s', e) if local_length == content_length: download = False elif local_length > content_length: - logger.info('deleting corrupt file from cache: %s', local_filename) + logging.info('deleting corrupt file from cache: %s', local_filename) os.remove(local_filename) - logger.info("Downloading %s to cache", filename) + logging.info("Downloading %s to cache", filename) elif local_length > -1 and local_length < content_length: - logger.info("Resuming download of %s", local_filename) + logging.info("Resuming download of %s", local_filename) resume_header = {'Range': 'bytes=%d-%d' % (local_length, content_length)} else: - logger.info("Downloading %s to cache", filename) + logging.info("Downloading %s to cache", filename) if download: r = requests.get(srcurl, headers=resume_header, @@ -480,9 +478,9 @@ def update_cache(cachedir, cachefiles): v = sha256_for_file(local_filename) if v == shasum: - logger.info("\t...shasum verified for %s", local_filename) + logging.info("\t...shasum verified for %s", local_filename) else: - logger.critical("Invalid shasum of '%s' detected for %s", v, local_filename) + logging.critical("Invalid shasum of '%s' detected for %s", v, local_filename) os.remove(local_filename) sys.exit(1) @@ -490,16 +488,16 @@ def update_cache(cachedir, cachefiles): def debug_log_vagrant_vm(vm_dir, config): if options.verbosity >= 3: _vagrant_dir = os.path.join(vm_dir, '.vagrant') - logger.debug('check %s dir exists? -> %r', _vagrant_dir, os.path.isdir(_vagrant_dir)) - logger.debug('> vagrant status') + logging.debug('check %s dir exists? -> %r', _vagrant_dir, os.path.isdir(_vagrant_dir)) + logging.debug('> vagrant status') subprocess.call(['vagrant', 'status'], cwd=vm_dir) - logger.debug('> vagrant box list') + logging.debug('> vagrant box list') subprocess.call(['vagrant', 'box', 'list']) if config['vm_provider'] == 'libvirt': - logger.debug('> virsh -c qmeu:///system list --all') + logging.debug('> virsh -c qmeu:///system list --all') subprocess.call(['virsh', '-c', 'qemu:///system', 'list', '--all']) domain = 'buildserver_default' - logger.debug('> virsh -c qemu:///system snapshot-list %s', domain) + logging.debug('> virsh -c qemu:///system snapshot-list %s', domain) subprocess.call(['virsh', '-c', 'qemu:///system', 'snapshot-list', domain]) @@ -507,7 +505,7 @@ def main(): global cachedir, cachefiles, config, tail if options.skip_cache_update: - logger.info('skipping cache update and verification...') + logging.info('skipping cache update and verification...') else: update_cache(cachedir, cachefiles) @@ -518,13 +516,13 @@ def main(): # all < 10 year old Macs work, and OSX servers as VM host are very # rare, but this could also be auto-detected if someone codes it config['hwvirtex'] = 'on' - logger.info('platform is darwnin -> hwvirtex = \'on\'') + logging.info('platform is darwnin -> hwvirtex = \'on\'') elif os.path.exists('/proc/cpuinfo'): with open('/proc/cpuinfo') as f: contents = f.read() if 'vmx' in contents or 'svm' in contents: config['hwvirtex'] = 'on' - logger.info('found \'vmx\' or \'svm\' in /proc/cpuinfo -> hwvirtex = \'on\'') + logging.info('found \'vmx\' or \'svm\' in /proc/cpuinfo -> hwvirtex = \'on\'') serverdir = os.path.join(os.getcwd(), 'buildserver') logfilename = os.path.join(serverdir, 'up.log') @@ -546,40 +544,40 @@ def main(): vf = os.path.join(serverdir, 'Vagrantfile.yaml') writevf = True if os.path.exists(vf): - logger.info('Halting %s', serverdir) + logging.info('Halting %s', serverdir) v.halt() with open(vf, 'r', encoding='utf-8') as f: oldconfig = yaml.load(f) if config != oldconfig: - logger.info("Server configuration has changed, rebuild from scratch is required") + logging.info("Server configuration has changed, rebuild from scratch is required") vm.destroy() else: - logger.info("Re-provisioning existing server") + logging.info("Re-provisioning existing server") writevf = False else: - logger.info("No existing server - building from scratch") + logging.info("No existing server - building from scratch") if writevf: with open(vf, 'w', encoding='utf-8') as f: yaml.dump(config, f) # Check if selected provider is supported if config['vm_provider'] not in ['libvirt', 'virtualbox']: - logger.critical("Currently selected VM provider '{vm_provider}' " - "is not supported. (please choose from: " - "virtualbox, libvirt)" - .format(vm_provider=config['cm_provider'])) + logging.critical("Currently selected VM provider '{vm_provider}' " + "is not supported. (please choose from: " + "virtualbox, libvirt)" + .format(vm_provider=config['cm_provider'])) sys.exit(1) # Check if selected basebox is available available_boxes_by_provider = [x.name for x in v.box_list() if x.provider == config['vm_provider']] if '/' not in config['basebox'] and config['basebox'] not in available_boxes_by_provider: - logger.critical("Vagrant box '{basebox}' not available " - "for '{vm_provider}' VM provider. " - "Please make sure it's added to vagrant. " - "(If you need a basebox to begin with, " - "here is how we're bootstrapping it: " - "https://gitlab.com/fdroid/basebox)" - .format(vm_provider=config['vm_provider'], - basebox=config['basebox'])) + logging.critical("Vagrant box '{basebox}' not available " + "for '{vm_provider}' VM provider. " + "Please make sure it's added to vagrant. " + "(If you need a basebox to begin with, " + "here is how we're bootstrapping it: " + "https://gitlab.com/fdroid/basebox)" + .format(vm_provider=config['vm_provider'], + basebox=config['basebox'])) sys.exit(1) # download and verfiy fdroid pre-built basebox @@ -594,18 +592,18 @@ def main(): '--provider=' + config['vm_provider']] ret_val = subprocess.call(cmd) if ret_val != 0: - logger.critical("downloading basebox '{box}' " - "({provider}, version {version}) failed." - .format(box=config['basebox'], - provider=config['vm_provider'], - version=config['basebox_version'])) + logging.critical("downloading basebox '{box}' " + "({provider}, version {version}) failed." + .format(box=config['basebox'], + provider=config['vm_provider'], + version=config['basebox_version'])) sys.exit(1) # verify box if config['basebox_version'] not in BASEBOX_CHECKSUMS.keys(): - logger.critical("can not verify '{box}', " - "unknown basebox version '{version}'" - .format(box=config['basebox'], - version=config['basebox_version'])) + logging.critical("can not verify '{box}', " + "unknown basebox version '{version}'" + .format(box=config['basebox'], + version=config['basebox_version'])) sys.exit(1) for filename, sha256 in BASEBOX_CHECKSUMS[config['basebox_version']][config['vm_provider']].items(): verify_file_sha256(os.path.join(get_vagrant_home(), @@ -615,23 +613,23 @@ def main(): config['vm_provider'], filename), sha256) - logger.info("successfully verified: '{box}' " - "({provider}, version {version})" - .format(box=config['basebox'], - provider=config['vm_provider'], - version=config['basebox_version'])) + logging.info("successfully verified: '{box}' " + "({provider}, version {version})" + .format(box=config['basebox'], + provider=config['vm_provider'], + version=config['basebox_version'])) else: - logger.debug('not updating basebox ...') + logging.debug('not updating basebox ...') else: - logger.debug('using unverified basebox ...') + logging.debug('using unverified basebox ...') - logger.info("Configuring build server VM") + logging.info("Configuring build server VM") debug_log_vagrant_vm(serverdir, config) try: v.up(provision=True) except subprocess.CalledProcessError: debug_log_vagrant_vm(serverdir, config) - logger.error("'vagrant up' failed.") + logging.error("'vagrant up' failed.") sys.exit(1) if config['copy_caches_from_host']: @@ -664,29 +662,29 @@ def main(): p = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE, universal_newlines=True) buildserverid = p.communicate()[0].strip() - logger.info("Writing buildserver ID ...ID is %s", buildserverid) + logging.info("Writing buildserver ID ...ID is %s", buildserverid) run_via_vagrant_ssh(v, 'sh -c "echo %s >/home/vagrant/buildserverid"' % buildserverid) - logger.info("Stopping build server VM") + logging.info("Stopping build server VM") v.halt() - logger.info("Packaging") + logging.info("Packaging") boxfile = os.path.join(os.getcwd(), 'buildserver.box') if os.path.exists(boxfile): os.remove(boxfile) vm.package(output=boxfile) - logger.info("Adding box") + logging.info("Adding box") vm.box_add('buildserver', boxfile, force=True) if 'buildserver' not in subprocess.check_output(['vagrant', 'box', 'list']).decode('utf-8'): - logger.critical('could not add box \'%s\' as \'buildserver\', terminating', boxfile) + logging.critical('could not add box \'%s\' as \'buildserver\', terminating', boxfile) sys.exit(1) if not options.keep_box_file: - logger.debug("""box added to vagrant, removing generated box file '%s'""", - boxfile) + logging.debug("""box added to vagrant, removing generated box file '%s'""", + boxfile) os.remove(boxfile) From bb067055d4124d8dc71a5774b766f6cc46190741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 23 Oct 2018 16:34:32 +0200 Subject: [PATCH 0022/2775] move location check to main blok --- makebuildserver | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/makebuildserver b/makebuildserver index acc21411..0a53b89c 100755 --- a/makebuildserver +++ b/makebuildserver @@ -41,11 +41,6 @@ elif options.verbosity <= 0: loglevel = logging.WARNING logging.basicConfig(format=logformat, level=loglevel) - -if not os.path.exists('makebuildserver') and not os.path.exists('buildserver'): - logging.critical('This must be run as ./makebuildserver in fdroidserver.git!') - sys.exit(1) - tail = None # set up default config @@ -689,6 +684,11 @@ def main(): if __name__ == '__main__': + + if not os.path.exists('makebuildserver') and not os.path.exists('buildserver'): + logging.critical('This must be run as ./makebuildserver in fdroidserver.git!') + sys.exit(1) + try: main() finally: From 1d4e5952c9dbce338f744521ec7776f1df1f447a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 23 Oct 2018 16:38:34 +0200 Subject: [PATCH 0023/2775] move host vm warning to main block --- makebuildserver | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/makebuildserver b/makebuildserver index 0a53b89c..2015fa4f 100755 --- a/makebuildserver +++ b/makebuildserver @@ -104,18 +104,6 @@ config = { 'vm_provider': 'virtualbox', } -if os.path.isfile('/usr/bin/systemd-detect-virt'): - try: - virt = subprocess.check_output('/usr/bin/systemd-detect-virt').strip().decode('utf-8') - except subprocess.CalledProcessError: - virt = 'none' - if virt == 'qemu' or virt == 'kvm' or virt == 'bochs': - logging.info('Running in a VM guest, defaulting to QEMU/KVM via libvirt') - config['vm_provider'] = 'libvirt' - elif virt != 'none': - logging.info('Running in an unsupported VM guest (%s)!', virt) - logging.debug('detected virt: %s', virt) - # load config file, if present if os.path.exists('makebuildserver.config.py'): exec(compile(open('makebuildserver.config.py').read(), 'makebuildserver.config.py', 'exec'), config) @@ -689,6 +677,18 @@ if __name__ == '__main__': logging.critical('This must be run as ./makebuildserver in fdroidserver.git!') sys.exit(1) + if os.path.isfile('/usr/bin/systemd-detect-virt'): + try: + virt = subprocess.check_output('/usr/bin/systemd-detect-virt').strip().decode('utf-8') + except subprocess.CalledProcessError: + virt = 'none' + if virt == 'qemu' or virt == 'kvm' or virt == 'bochs': + logging.info('Running in a VM guest, defaulting to QEMU/KVM via libvirt') + config['vm_provider'] = 'libvirt' + elif virt != 'none': + logging.info('Running in an unsupported VM guest (%s)!', virt) + logging.debug('detected virt: %s', virt) + try: main() finally: From b6e45753da0e84ad8eaf57e96b591d89d750cacb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 20 Feb 2019 15:47:43 +0100 Subject: [PATCH 0024/2775] makebuildserver: cachefile now static variable rename cachefile to CACHE_FILE to make clear that it is a static variable. Also stopped passing it as an argument when it is already globally visible. --- makebuildserver | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/makebuildserver b/makebuildserver index 2015fa4f..f22a7b97 100755 --- a/makebuildserver +++ b/makebuildserver @@ -151,7 +151,7 @@ if config['apt_package_cache']: logging.info('removing partial downloads from apt cache dir') shutil.rmtree(aptcachepartial) -cachefiles = [ +CACHE_FILES = [ # Don't update sdk tools beyond 25.2.5. # Support for android update project has been removed and there is no replacement. # Until we find a solution for that we need to stay at this revision. @@ -411,8 +411,8 @@ def run_via_vagrant_ssh(v, cmdlist): v._run_vagrant_command(['ssh', '-c', cmd]) -def update_cache(cachedir, cachefiles): - for srcurl, shasum in cachefiles: +def update_cache(cachedir): + for srcurl, shasum in CACHE_FILES: filename = os.path.basename(srcurl) local_filename = os.path.join(cachedir, filename) @@ -485,12 +485,12 @@ def debug_log_vagrant_vm(vm_dir, config): def main(): - global cachedir, cachefiles, config, tail + global cachedir, config, tail if options.skip_cache_update: logging.info('skipping cache update and verification...') else: - update_cache(cachedir, cachefiles) + update_cache(cachedir) # use VirtualBox software virtualization if hardware is not available, # like if this is being run in kvm or some other VM platform, like From 7662520b5445496a20e7a5918324479a3249925e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 20 Feb 2019 16:26:57 +0100 Subject: [PATCH 0025/2775] makebuildserver: refactored cachedir variable away --- makebuildserver | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/makebuildserver b/makebuildserver index f22a7b97..ccb970ca 100755 --- a/makebuildserver +++ b/makebuildserver @@ -43,10 +43,6 @@ logging.basicConfig(format=logformat, level=loglevel) tail = None -# set up default config -cachedir = os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver') -logging.debug('cachedir set to: %s', cachedir) - BASEBOX_DEFAULT = 'fdroid/basebox-stretch64' BASEBOX_VERSION_DEFAULT = '0.5.1' BASEBOX_CHECKSUMS = { @@ -97,7 +93,7 @@ config = { 'apt_package_cache': False, 'copy_caches_from_host': False, 'boot_timeout': 600, - 'cachedir': cachedir, + 'cachedir': os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), 'cpus': 1, 'memory': 2048, 'hwvirtex': 'off', @@ -123,13 +119,12 @@ if 'basebox_version' in config and 'basebox' in config and '/' not in config['ba .format(box=config['basebox'], version=config['basebox_version'])) # Update cached files. -cachedir = config['cachedir'] -if not os.path.exists(cachedir): - os.makedirs(cachedir, 0o755) - logging.debug('created cachedir %s because it did not exists.', cachedir) +if not os.path.exists(config['cachedir']): + os.makedirs(config['cachedir'], 0o755) + logging.debug('created cachedir {} because it did not exists.'.format(config['cachedir'])) if config['vm_provider'] == 'libvirt': - tmp = cachedir + tmp = config['cachedir'] while tmp != '/': mode = os.stat(tmp).st_mode if not (stat.S_IXUSR & mode and stat.S_IXGRP & mode and stat.S_IXOTH & mode): @@ -137,10 +132,10 @@ if config['vm_provider'] == 'libvirt': logging.critical(' chmod a+X %s', tmp) sys.exit(1) tmp = os.path.dirname(tmp) - logging.debug('cache dir %s is accessible for libvirt vm.', cachedir) + logging.debug('cache dir %s is accessible for libvirt vm.', config['cachedir']) if config['apt_package_cache']: - config['aptcachedir'] = cachedir + '/apt/archives' + config['aptcachedir'] = config['cachedir'] + '/apt/archives' logging.debug('aptcachedir is set to %s', config['aptcachedir']) aptcachelock = os.path.join(config['aptcachedir'], 'lock') if os.path.isfile(aptcachelock): @@ -485,12 +480,12 @@ def debug_log_vagrant_vm(vm_dir, config): def main(): - global cachedir, config, tail + global config, tail if options.skip_cache_update: logging.info('skipping cache update and verification...') else: - update_cache(cachedir) + update_cache(config['cachedir']) # use VirtualBox software virtualization if hardware is not available, # like if this is being run in kvm or some other VM platform, like From 63afc0acb56e26d48f307eee659266ab802c2e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 6 Mar 2019 08:42:17 +0100 Subject: [PATCH 0026/2775] use pyyaml for writing metadata instead of ruamel --- buildserver/provision-apt-get-install | 1 - fdroidserver/metadata.py | 211 ++++++++++-------- setup.py | 1 - .../org.fdroid.fdroid.yml | 130 +++++------ tests/metadata.TestCase | 93 ++++++++ 5 files changed, 270 insertions(+), 166 deletions(-) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index a99b6871..9d90d8e7 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -103,7 +103,6 @@ packages=" python3-setuptools python3-smmap python3-yaml - python3-ruamel.yaml quilt rsync scons diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index bbf8d70b..51848e23 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -248,6 +248,13 @@ def fieldtype(name): return TYPE_STRING +def yml_fieldtype(name): + if name == 'CurrentVersionCode': + return TYPE_INT + else: + return fieldtype(name) + + # In the order in which they are laid out on files build_flags_order = [ 'disable', @@ -1115,117 +1122,123 @@ def write_yaml(mf, app): :param app: app metadata to written to the yaml file """ - # import rumael.yaml and check version - try: - import ruamel.yaml - except ImportError as e: - raise FDroidException('ruamel.yaml not instlled, can not write metadata.') from e - if not ruamel.yaml.__version__: - raise FDroidException('ruamel.yaml.__version__ not accessible. Please make sure a ruamel.yaml >= 0.13 is installed..') - m = re.match(r'(?P[0-9]+)\.(?P[0-9]+)\.(?P[0-9]+)(-.+)?', - ruamel.yaml.__version__) - if not m: - raise FDroidException('ruamel.yaml version malfored, please install an upstream version of ruamel.yaml') - if int(m.group('major')) < 0 or int(m.group('minor')) < 13: - raise FDroidException('currently installed version of ruamel.yaml ({}) is too old, >= 1.13 required.'.format(ruamel.yaml.__version__)) - # suiteable version ruamel.yaml imported successfully + def format_yml_field(field, value, typ, width=80, offset=0): + # TODO: use CSafeDumper if available - _yaml_bools_true = ('y', 'Y', 'yes', 'Yes', 'YES', - 'true', 'True', 'TRUE', - 'on', 'On', 'ON') - _yaml_bools_false = ('n', 'N', 'no', 'No', 'NO', - 'false', 'False', 'FALSE', - 'off', 'Off', 'OFF') - _yaml_bools_plus_lists = [] - _yaml_bools_plus_lists.extend(_yaml_bools_true) - _yaml_bools_plus_lists.extend([[x] for x in _yaml_bools_true]) - _yaml_bools_plus_lists.extend(_yaml_bools_false) - _yaml_bools_plus_lists.extend([[x] for x in _yaml_bools_false]) + bool_list_hack = ['gradle'] - def _class_as_dict_representer(dumper, data): - '''Creates a YAML representation of a App/Build instance''' - return dumper.represent_dict(data) + data = {} + default_style = None - def _field_to_yaml(typ, value): - if typ is TYPE_STRING: - if value in _yaml_bools_plus_lists: - return ruamel.yaml.scalarstring.SingleQuotedScalarString(str(value)) - return str(value) - elif typ is TYPE_INT: - return int(value) - elif typ is TYPE_MULTILINE: - if '\n' in value: - return ruamel.yaml.scalarstring.preserve_literal(str(value)) + if typ == TYPE_INT: + data[field] = int(value) + elif typ == TYPE_BOOL: + data[field] = bool(value) + elif typ == TYPE_SCRIPT: + if type(value) != list: + value = value.split(' && ') + if len(value) > 1: + data[field] = value else: - return str(value) - elif typ is TYPE_SCRIPT: - if type(value) == list: - if len(value) == 1: - return value[0] - else: - return value - else: - script_lines = value.split(' && ') - if len(script_lines) > 1: - return script_lines - else: - return value + data[field] = value[0] + elif typ == TYPE_LIST: + if field in bool_list_hack: + if value in [True, 'yes', ['yes']]: + value = [True] + data[field] = value + elif typ == TYPE_MULTILINE: + default_style = '|' + data[field] = value.strip() else: - return value + data[field] = value - def _app_to_yaml(app): - cm = ruamel.yaml.comments.CommentedMap() - insert_newline = False - for field in yaml_app_field_order: - if field == '\n': - # next iteration will need to insert a newline - insert_newline = True - else: - if app.get(field) or field == 'Builds': - # .txt calls it 'builds' internally, everywhere else its 'Builds' - if field == 'Builds': - if app.get('builds'): - cm.update({field: _builds_to_yaml(app)}) - elif field == 'CurrentVersionCode': - cm.update({field: _field_to_yaml(TYPE_INT, getattr(app, field))}) + raw_yml = yaml.dump(data, Dumper=yaml.SafeDumper, + default_flow_style=False, width=width, + default_style=default_style, indent=4) + + # this is just for debugging purposes remove in production code + # debug_print_yaml_item(typ, data, default_style, offset, raw_yml) + + if raw_yml: + + # remove all encapsulation newlines + raw_yml = re.sub('\n+$', '', raw_yml) + raw_yml = re.sub('^\n+', '', raw_yml) + + if offset > 0: + lines = raw_yml.split('\n') + for i in range(len(lines)): + if lines[i] != '': + lines[i] = ' ' * offset + lines[i] + raw_yml = '\n'.join(lines) + + if typ == TYPE_LIST or typ == TYPE_SCRIPT: + # indent sequence items by 2 spaces + new_raw_yml = [] + for line in raw_yml.split('\n'): + if re.match(r'^\s*$', line): + new_raw_yml.append('') + elif len(new_raw_yml) > 0: + new_raw_yml.append(' ' + line) else: - cm.update({field: _field_to_yaml(fieldtype(field), getattr(app, field))}) + new_raw_yml.append(line) + raw_yml = '\n'.join(new_raw_yml) + elif typ == TYPE_MULTILINE: + # remove quotes from mulit line keys + raw_yml = re.sub(r'^(\s*)"([a-zA-Z0-9]+)":(\s*\|-)$', '\\1\\2:\\3', raw_yml, flags=re.MULTILINE) - if insert_newline: - # we need to prepend a newline in front of this field - insert_newline = False - # inserting empty lines is not supported so we add a - # bogus comment and over-write its value - cm.yaml_set_comment_before_after_key(field, 'bogus') - cm.ca.items[field][1][-1].value = '\n' - return cm + return raw_yml - def _builds_to_yaml(app): - builds = ruamel.yaml.comments.CommentedSeq() - for build in app.builds: - b = ruamel.yaml.comments.CommentedMap() - for field in build_flags: - value = getattr(build, field) - if hasattr(build, field) and value: - if field == 'gradle' and value == ['off']: - value = [ruamel.yaml.scalarstring.SingleQuotedScalarString('off')] - if field in ('maven', 'buildozer'): - if value == 'no': - continue - elif value == 'yes': - value = 'yes' - b.update({field: _field_to_yaml(flagtype(field), value)}) - builds.append(b) + def format_yml_build_entry(build): + result = [] + for field in build_flags: + value = getattr(build, field, None) + if value: + typ = flagtype(field) + line = format_yml_field(field, value, typ, width=0xffffffff, offset=4) + if re.match(r'^\s+$', line): + result.append('') + else: + result.append(line) + result[0] = ' - ' + result[0][4:] + return '\n'.join(result) - # insert extra empty lines between build entries - for i in range(1, len(builds)): - builds.yaml_set_comment_before_after_key(i, 'bogus') - builds.ca.items[i][1][-1].value = '\n' + result = [] + for field in yaml_app_field_order: + if field == '\n': + if result[-1] != '': + result.append('') + continue + else: + value = app.get(field) + if field == 'Builds' and app.builds: + result.append('Builds:') + first_build_entry = True + for build in app.builds: + if first_build_entry: + first_build_entry = False + else: + result.append('') + result.append(format_yml_build_entry(build)) + if value: + result.append(format_yml_field(field, value, yml_fieldtype(field))) + mf.write('\n'.join(result)) - return builds - yaml_app = _app_to_yaml(app) - ruamel.yaml.round_trip_dump(yaml_app, mf, indent=4, block_seq_indent=2) +def debug_print_yaml_item(typ, data, default_style, offset, raw_yml): + """function debugging indiviudal lines during yaml writing""" + typTable = {0: 'TYPE_UNKNOWN', + 1: 'TYPE_OBSOLETE', + 2: 'TYPE_STRING', + 3: 'TYPE_BOOL', + 4: 'TYPE_LIST', + 5: 'TYPE_SCRIPT', + 6: 'TYPE_MULTILINE', + 7: 'TYPE_BUILD', + 8: 'TYPE_INT'} + print('###', '(' + typTable[typ] + ', default_style=' + + str(default_style) + ', offset=' + str(offset) + ')\n', + data, '->', raw_yml if raw_yml else '') build_line_sep = re.compile(r'(?= 0.13', 'requests >= 2.5.2, != 2.11.0, != 2.12.2, != 2.18.0', 'docker-py >= 1.9, < 2.0', ], diff --git a/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml b/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml index 9471f9a6..322738df 100644 --- a/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml +++ b/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml @@ -199,14 +199,14 @@ Builds: commit: 0.53-test submodules: true scandelete: - - yes + - 'yes' - versionName: '0.54' versionCode: 540 commit: '0.54' submodules: true scandelete: - - yes + - 'yes' - versionName: '0.55' versionCode: 550 @@ -498,7 +498,7 @@ Builds: subdir: F-Droid submodules: true gradle: - - yes + - true - versionName: 0.95-alpha1 versionCode: 95001 @@ -506,7 +506,7 @@ Builds: subdir: F-Droid submodules: true gradle: - - yes + - true - versionName: 0.95-alpha2 versionCode: 95002 @@ -514,7 +514,7 @@ Builds: subdir: F-Droid submodules: true gradle: - - yes + - true - versionName: '0.95' versionCode: 95050 @@ -522,7 +522,7 @@ Builds: subdir: F-Droid submodules: true gradle: - - yes + - true - versionName: 0.95.1 versionCode: 95150 @@ -530,56 +530,56 @@ Builds: subdir: F-Droid submodules: true gradle: - - yes + - true - versionName: 0.96-alpha1 versionCode: 96001 commit: v0.96-alpha1 subdir: F-Droid gradle: - - yes + - true - versionName: 0.96-alpha2 versionCode: 96002 commit: v0.96-alpha2 subdir: F-Droid gradle: - - yes + - true - versionName: 0.96-alpha3 versionCode: 96003 commit: v0.96-alpha3 subdir: F-Droid gradle: - - yes + - true - versionName: 0.96-alpha4 versionCode: 96004 commit: v0.96-alpha4 subdir: F-Droid gradle: - - yes + - true - versionName: 0.96-alpha5 versionCode: 96005 commit: v0.96-alpha5 subdir: F-Droid gradle: - - yes + - true - versionName: 0.96-alpha6 versionCode: 96006 commit: v0.96-alpha6 subdir: F-Droid gradle: - - yes + - true - versionName: '0.96' versionCode: 96050 commit: v0.96 subdir: F-Droid gradle: - - yes + - true scanignore: - extern/AndroidPinning/res/raw/cacerts @@ -588,7 +588,7 @@ Builds: commit: v0.96.1 subdir: F-Droid gradle: - - yes + - true scanignore: - extern/AndroidPinning/res/raw/cacerts @@ -597,7 +597,7 @@ Builds: commit: v0.97-alpha1 subdir: F-Droid gradle: - - yes + - true scanignore: - extern/AndroidPinning/res/raw/cacerts @@ -606,343 +606,343 @@ Builds: commit: v0.97-alpha2 subdir: F-Droid gradle: - - yes + - true - versionName: 0.97-alpha3 versionCode: 97003 commit: v0.97-alpha3 subdir: F-Droid gradle: - - yes + - true - versionName: 0.97-alpha4 versionCode: 97004 commit: v0.97-alpha4 subdir: F-Droid gradle: - - yes + - true - versionName: 0.97-alpha5 versionCode: 97005 commit: v0.97-alpha5 subdir: F-Droid gradle: - - yes + - true - versionName: 0.97-alpha6 versionCode: 97006 commit: v0.97-alpha6 subdir: F-Droid gradle: - - yes + - true - versionName: 0.97-alpha7 versionCode: 97007 commit: v0.97-alpha7 subdir: F-Droid gradle: - - yes + - true - versionName: 0.97-alpha8 versionCode: 97008 commit: v0.97-alpha8 subdir: F-Droid gradle: - - yes + - true - versionName: '0.97' versionCode: 97050 commit: v0.97 subdir: F-Droid gradle: - - yes + - true - versionName: 0.98-alpha1 versionCode: 98001 commit: v0.98-alpha1 subdir: F-Droid gradle: - - yes + - true - versionName: 0.98-alpha2 versionCode: 98002 commit: v0.98-alpha2 subdir: F-Droid gradle: - - yes + - true - versionName: 0.98-alpha3 versionCode: 98003 commit: v0.98-alpha3 subdir: F-Droid gradle: - - yes + - true - versionName: 0.98-alpha4 versionCode: 98004 commit: v0.98-alpha4 subdir: F-Droid gradle: - - yes + - true - versionName: 0.98-alpha5 versionCode: 98005 commit: v0.98-alpha5 subdir: F-Droid gradle: - - yes + - true - versionName: 0.98-alpha6 versionCode: 98006 commit: v0.98-alpha6 subdir: F-Droid gradle: - - yes + - true - versionName: 0.98-alpha7 versionCode: 98007 commit: v0.98-alpha7 subdir: F-Droid gradle: - - yes + - true - versionName: '0.98' versionCode: 98050 commit: v0.98 subdir: F-Droid gradle: - - yes + - true - versionName: 0.98.1 versionCode: 98150 commit: v0.98.1 subdir: F-Droid gradle: - - yes + - true - versionName: 0.99-alpha1 versionCode: 99001 commit: v0.99-alpha1 subdir: F-Droid gradle: - - yes + - true - versionName: 0.99-alpha2 versionCode: 99002 commit: v0.99-alpha2 subdir: F-Droid gradle: - - yes + - true - versionName: '0.99' versionCode: 99050 commit: v0.99 subdir: F-Droid gradle: - - yes + - true - versionName: 0.99.1 versionCode: 99150 commit: v0.99.1 subdir: F-Droid gradle: - - yes + - true - versionName: 0.99.2 versionCode: 99250 commit: v0.99.2 subdir: F-Droid gradle: - - yes + - true - versionName: 0.100-alpha1 versionCode: 100001 commit: v0.100-alpha1 subdir: F-Droid gradle: - - yes + - true - versionName: 0.100-alpha2 versionCode: 100002 commit: v0.100-alpha2 subdir: F-Droid gradle: - - yes + - true - versionName: 0.100-alpha3 versionCode: 100003 commit: v0.100-alpha3 subdir: app gradle: - - yes + - true - versionName: 0.100-alpha4 versionCode: 100004 commit: v0.100-alpha4 subdir: app gradle: - - yes + - true - versionName: 0.100-alpha5 versionCode: 100005 commit: v0.100-alpha5 subdir: app gradle: - - yes + - true - versionName: 0.100-alpha6 versionCode: 100006 commit: v0.100-alpha6 subdir: app gradle: - - yes + - true - versionName: 0.100-alpha7 versionCode: 100007 commit: v0.100-alpha7 subdir: app gradle: - - yes + - true - versionName: 0.100-alpha8 versionCode: 100008 commit: v0.100-alpha8 subdir: app gradle: - - yes + - true - versionName: '0.100' versionCode: 100050 commit: v0.100 subdir: app gradle: - - yes + - true - versionName: 0.100.1 versionCode: 100150 commit: v0.100.1 subdir: app gradle: - - yes + - true - versionName: 0.101-alpha1 versionCode: 101001 commit: v0.101-alpha1 subdir: app gradle: - - yes + - true - versionName: 0.101-alpha2 versionCode: 101002 commit: v0.101-alpha2 subdir: app gradle: - - yes + - true - versionName: 0.101-alpha3 versionCode: 101003 commit: v0.101-alpha3 subdir: app gradle: - - yes + - true - versionName: 0.101-alpha4 versionCode: 101004 commit: v0.101-alpha4 subdir: app gradle: - - yes + - true - versionName: 0.101-alpha5 versionCode: 101005 commit: v0.101-alpha5 subdir: app gradle: - - yes + - true - versionName: 0.101-alpha6 versionCode: 101006 commit: v0.101-alpha6 subdir: app gradle: - - yes + - true - versionName: '0.101' versionCode: 101050 commit: v0.101 subdir: app gradle: - - yes + - true - versionName: 0.102-alpha1 versionCode: 102001 commit: v0.102-alpha1 subdir: app gradle: - - yes + - true - versionName: 0.102-alpha2 versionCode: 102002 commit: v0.102-alpha2 subdir: app gradle: - - yes + - true - versionName: 0.102-alpha3 versionCode: 102003 commit: v0.102-alpha3 subdir: app gradle: - - yes + - true - versionName: '0.102' versionCode: 102050 commit: v0.102 subdir: app gradle: - - yes + - true - versionName: 0.102.1 versionCode: 102150 commit: v0.102.1 subdir: app gradle: - - yes + - true - versionName: 0.102.2 versionCode: 102250 commit: v0.102.2 subdir: app gradle: - - yes + - true - versionName: 0.102.3 versionCode: 102350 commit: v0.102.3 subdir: app gradle: - - yes + - true - versionName: 0.103-alpha1 versionCode: 103001 commit: v0.103-alpha1 subdir: app gradle: - - yes + - true - versionName: 0.103-alpha2 versionCode: 103002 commit: v0.103-alpha2 subdir: app gradle: - - yes + - true - versionName: 0.103-alpha3 versionCode: 103003 commit: v0.103-alpha3 subdir: app gradle: - - yes + - true ArchivePolicy: 12 versions AutoUpdateMode: None diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 486dca09..86e8e80a 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -307,6 +307,68 @@ class MetadataTest(unittest.TestCase): 'prebuild': "a && b && " "sed -i 's,a,b,'"}]}) + def test_write_yaml_description_with_trailing_whitespace(self): + mf = io.StringIO() + app = fdroidserver.metadata.App() + app.Categories = ['None'] + app.Description = "this evil description has a trailing whitespace " + app.builds = [] + build = fdroidserver.metadata.Build() + build.versionCode = 102030 + build.versionName = 'v1.2.3' + build.build = "./gradlew compile" + app.builds.append(build) + fdroidserver.metadata.write_yaml(mf, app) + mf.seek(0) + self.maxDiff = None + self.assertEqual(mf.read(), textwrap.dedent("""\ + Categories: + - None + License: Unknown + + Description: |- + this evil description has a trailing whitespace + + Builds: + - versionName: v1.2.3 + versionCode: 102030 + build: ./gradlew compile + + AutoUpdateMode: None + UpdateCheckMode: None + """)) + + def test_write_yaml_long_description(self): + mf = io.StringIO() + app = fdroidserver.metadata.App() + app.Categories = ['None'] + app.Description = "long description is long; " * 20 + app.builds = [] + build = fdroidserver.metadata.Build() + build.versionCode = 102030 + build.versionName = 'v1.2.3' + build.build = "./gradlew compile" + app.builds.append(build) + fdroidserver.metadata.write_yaml(mf, app) + mf.seek(0) + self.maxDiff = None + self.assertEqual(mf.read(), textwrap.dedent("""\ + Categories: + - None + License: Unknown + + Description: |- + long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; + + Builds: + - versionName: v1.2.3 + versionCode: 102030 + build: ./gradlew compile + + AutoUpdateMode: None + UpdateCheckMode: None + """)) + def test_write_yaml_1_line_scripts_as_string(self): mf = io.StringIO() app = fdroidserver.metadata.App() @@ -461,6 +523,37 @@ class MetadataTest(unittest.TestCase): UpdateCheckMode: None """)) + def test_write_yaml_very_long_script(self): + mf = io.StringIO() + app = fdroidserver.metadata.App() + app.Categories = ['None'] + app.builds = [] + build = fdroidserver.metadata.Build() + build.versionCode = 102030 + build.versionName = 'v1.2.3' + build.build = "./gradlew someSpecialTask && sed -i 'd/that wrong config/' gradle.properties && ./gradlew compile && long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long;" + app.builds.append(build) + fdroidserver.metadata.write_yaml(mf, app) + mf.seek(0) + self.maxDiff = None + self.assertEqual(mf.read(), textwrap.dedent("""\ + Categories: + - None + License: Unknown + + Builds: + - versionName: v1.2.3 + versionCode: 102030 + build: + - ./gradlew someSpecialTask + - sed -i 'd/that wrong config/' gradle.properties + - ./gradlew compile + - long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; + + AutoUpdateMode: None + UpdateCheckMode: None + """)) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 881a79fa84a3889f511ad2c090abe2823b632d8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 12 Mar 2019 23:25:16 +0100 Subject: [PATCH 0027/2775] test writing all yaml fields --- tests/metadata.TestCase | 189 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 86e8e80a..1e4a21b4 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -70,6 +70,195 @@ class MetadataTest(unittest.TestCase): # yaml.add_representer(fdroidserver.metadata.Build, _build_yaml_representer) # yaml.dump(frommeta, f, default_flow_style=False) + def test_write_yaml_allfields(self): + + mf = io.StringIO() + + app = fdroidserver.metadata.App() + app.Disabled = True + app.AntiFeatures = ['Karl', 'Bert'] + app.Provides = "org.fdroid.fdroid" + app.Categories = ['Secret', 'Stuff'] + app.License = 'GPL-3.0-or-later' + app.AuthorName = 'He who must not be named.' + app.AuthorEmail = 'tom@f-droid.org' + app.AuthorWebSite = 'https://f-droid.org/~theDarkLord' + app.WebSite = 'https://f-droid.org' + app.SourceCode = 'https://gitlab.com/fdroid/fdroidclient.git' + app.IssueTracker = "https://gitlab.com/fdroid/fdroidclient/issues" + app.Translation = 'https://hosted.weblate.org/projects/f-droid/f-droid' + app.Changelog = 'https://example.com/fdroidclient/raw/master/CHANGELOG.md' + app.Donate = 'https://f-droid.org/about' + app.FlattrID = '343053' + app.LiberapayID = '27859' + app.Bitcoin = '15u8aAPK4jJ5N8wpWJ5gutAyyeHtKX5i18' + app.Litecoin = '000000000000000000000000000000000' + app.Name = 'F-Droid' + app.AutoName = 'F-Droid' + app.Summary = 'The app store that respects freedom and privacy' + app.Description = 'The app store that respects freedom and privacy' + app.RequiresRoot = True + app.RepoType = 'git' + app.Repo = 'https://gitlab.com/fdroid/fdroidclient.git' + app.Binaries = 'https://f-droid.org/fdroid-%v.apk' + app.builds = [] + + build = fdroidserver.metadata.Build() + build.versionName = '1.0.1' + build.versionCode = 101 + build.disable = 'for this reason' + build.commit = '1.0.1' + build.timeout = 12345 + build.subdir = 'app' + build.submodules = True + build.sudo = 'apt-get update -y && apt-get upgrade -y' + build.init = 'sed -i -e "/replace this/with that/" build.gradle' + build.patch = ['remove-play-services.patch', 'add-other-service.patch'] + build.gradle = 'flavor' + build.maven = True + build.buildozer = True + build.output = 'app/build/fdroid-$$VERSION$$.zip' + build.scrlibs = ['DragSort@0.6.1,3', 'SlidingMenu@7ebe32772'] + build.oldsdkloc = True + build.encoding = 'utf-8' + build.forceversion = True + build.forcevercode = True + build.rm = ['app/file1', 'app/file2', 'app/other*'] + build.extlibs = ['android/android-support-v4.jar', 'android/android-support-v13.jar'] + build.prebuild = 'sed -i -e "/replace this/with that/" build.gradle' + build.androidupdate = [False] + build.target = 'android-99' + build.scanignore = ['libs/a.so', 'libs/b.so'] + build.scandelete = ['bin/exec', 'bin/run'] + build.build = 'export NDK_DIR=$$NDK$$' + build.buildjni = True + build.ndk = 'r99b' + build.preassemble = ':gradleTask' + build.gradleprops = 'prop4gradle' + build.antcommands = 'package' + build.novcheck = True + build.antifeatures = ['Karl', 'Hank'] + app.builds.append(build) + + app.MaintainerNotes = 'Great app, highly recommended.' + app.ArchivePolicy = '3 versions' + app.AutoUpdateMode = 'None' + app.UpdateCheckMode = 'Tags' + app.UpdateCheckIgnore = '(alpha|beta|rc|RC|dev)' + app.VercodeOperation = '%c + 2' + app.UpdateCheckName = 'org.fdroid.fdroid' + app.UpdateCheckData = 'https://raw.githubusercontent.com/proj/app/master/AndroidManifest.xml|android:versionCode="([0-9]*)"|.|android:versionCode="([0-9]*)"' + app.CurrentVersion = '1.0.1' + app.CurrentVersionCode = 101 + app.NoSourceSince = '1.0.1' + + fdroidserver.metadata.write_yaml(mf, app) + mf.seek(0) + + self.maxDiff = None + self.assertEqual(mf.read(), textwrap.dedent("""\ + Disabled: true + AntiFeatures: + - Karl + - Bert + Provides: org.fdroid.fdroid + Categories: + - Secret + - Stuff + License: GPL-3.0-or-later + AuthorName: He who must not be named. + AuthorEmail: tom@f-droid.org + AuthorWebSite: https://f-droid.org/~theDarkLord + WebSite: https://f-droid.org + SourceCode: https://gitlab.com/fdroid/fdroidclient.git + IssueTracker: https://gitlab.com/fdroid/fdroidclient/issues + Translation: https://hosted.weblate.org/projects/f-droid/f-droid + Changelog: https://example.com/fdroidclient/raw/master/CHANGELOG.md + Donate: https://f-droid.org/about + FlattrID: '343053' + LiberapayID: '27859' + Bitcoin: 15u8aAPK4jJ5N8wpWJ5gutAyyeHtKX5i18 + Litecoin: '000000000000000000000000000000000' + + Name: F-Droid + AutoName: F-Droid + Summary: The app store that respects freedom and privacy + Description: |- + The app store that respects freedom and privacy + + RequiresRoot: true + + RepoType: git + Repo: https://gitlab.com/fdroid/fdroidclient.git + Binaries: https://f-droid.org/fdroid-%v.apk + + Builds: + - versionName: 1.0.1 + versionCode: 101 + disable: for this reason + commit: 1.0.1 + timeout: 12345 + subdir: app + submodules: true + sudo: + - apt-get update -y + - apt-get upgrade -y + init: sed -i -e "/replace this/with that/" build.gradle + patch: + - remove-play-services.patch + - add-other-service.patch + gradle: flavor + maven: true + buildozer: true + output: app/build/fdroid-$$VERSION$$.zip + oldsdkloc: true + encoding: utf-8 + forceversion: true + forcevercode: true + rm: + - app/file1 + - app/file2 + - app/other* + extlibs: + - android/android-support-v4.jar + - android/android-support-v13.jar + prebuild: sed -i -e "/replace this/with that/" build.gradle + androidupdate: + - false + target: android-99 + scanignore: + - libs/a.so + - libs/b.so + scandelete: + - bin/exec + - bin/run + build: export NDK_DIR=$$NDK$$ + buildjni: true + ndk: r99b + preassemble: :gradleTask + gradleprops: prop4gradle + antcommands: package + novcheck: true + antifeatures: + - Karl + - Hank + + MaintainerNotes: |- + Great app, highly recommended. + + ArchivePolicy: 3 versions + AutoUpdateMode: None + UpdateCheckMode: Tags + UpdateCheckIgnore: (alpha|beta|rc|RC|dev) + VercodeOperation: '%c + 2' + UpdateCheckName: org.fdroid.fdroid + UpdateCheckData: https://raw.githubusercontent.com/proj/app/master/AndroidManifest.xml|android:versionCode="([0-9]*)"|.|android:versionCode="([0-9]*)" + CurrentVersion: 1.0.1 + CurrentVersionCode: 101 + + NoSourceSince: 1.0.1""")) + + def test_rewrite_yaml_fakeotaupdate(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']} From 2683b37044d09094774abb1afc411a1a607e616b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 19 Mar 2019 01:01:18 +0100 Subject: [PATCH 0028/2775] yml metadata write: do not use local functions --- fdroidserver/metadata.py | 167 ++++++++++++++++++++------------------- tests/metadata.TestCase | 3 +- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 51848e23..dbc32edc 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -1115,6 +1115,88 @@ def post_parse_yaml_metadata(yamldata): build[flag] = ' && '.join(build[flag]) +def _format_yml_field(field, value, typ, width=80, offset=0): + + bool_list_hack = ['gradle'] + + data = {} + default_style = None + + if typ == TYPE_INT: + data[field] = int(value) + elif typ == TYPE_BOOL: + data[field] = bool(value) + elif typ == TYPE_SCRIPT: + if type(value) != list: + value = value.split(' && ') + if len(value) > 1: + data[field] = value + else: + data[field] = value[0] + elif typ == TYPE_LIST: + if field in bool_list_hack: + if value in [True, 'yes', ['yes']]: + value = [True] + data[field] = value + elif typ == TYPE_MULTILINE: + default_style = '|' + data[field] = value.strip() + else: + data[field] = value + + raw_yml = yaml.dump(data, Dumper=yaml.SafeDumper, + default_flow_style=False, width=width, + default_style=default_style, indent=4) + + # this is just for debugging purposes remove in production code + # debug_print_yaml_item(typ, data, default_style, offset, raw_yml) + + if raw_yml: + + # remove all encapsulation newlines + raw_yml = re.sub('\n+$', '', raw_yml) + raw_yml = re.sub('^\n+', '', raw_yml) + + if offset > 0: + lines = raw_yml.split('\n') + for i in range(len(lines)): + if lines[i] != '': + lines[i] = ' ' * offset + lines[i] + raw_yml = '\n'.join(lines) + + if typ == TYPE_LIST or typ == TYPE_SCRIPT: + # indent sequence items by 2 spaces + new_raw_yml = [] + for line in raw_yml.split('\n'): + if re.match(r'^\s*$', line): + new_raw_yml.append('') + elif len(new_raw_yml) > 0: + new_raw_yml.append(' ' + line) + else: + new_raw_yml.append(line) + raw_yml = '\n'.join(new_raw_yml) + elif typ == TYPE_MULTILINE: + # remove quotes from mulit line keys + raw_yml = re.sub(r'^(\s*)"([a-zA-Z0-9]+)":(\s*\|-)$', '\\1\\2:\\3', raw_yml, flags=re.MULTILINE) + + return raw_yml + + +def _format_yml_build_entry(build): + result = [] + for field in build_flags: + value = getattr(build, field, None) + if value: + typ = flagtype(field) + line = _format_yml_field(field, value, typ, width=0xffffffff, offset=4) + if re.match(r'^\s+$', line): + result.append('') + else: + result.append(line) + result[0] = ' - ' + result[0][4:] + return '\n'.join(result) + + def write_yaml(mf, app): """Write metadata in yaml format. @@ -1122,87 +1204,6 @@ def write_yaml(mf, app): :param app: app metadata to written to the yaml file """ - def format_yml_field(field, value, typ, width=80, offset=0): - # TODO: use CSafeDumper if available - - bool_list_hack = ['gradle'] - - data = {} - default_style = None - - if typ == TYPE_INT: - data[field] = int(value) - elif typ == TYPE_BOOL: - data[field] = bool(value) - elif typ == TYPE_SCRIPT: - if type(value) != list: - value = value.split(' && ') - if len(value) > 1: - data[field] = value - else: - data[field] = value[0] - elif typ == TYPE_LIST: - if field in bool_list_hack: - if value in [True, 'yes', ['yes']]: - value = [True] - data[field] = value - elif typ == TYPE_MULTILINE: - default_style = '|' - data[field] = value.strip() - else: - data[field] = value - - raw_yml = yaml.dump(data, Dumper=yaml.SafeDumper, - default_flow_style=False, width=width, - default_style=default_style, indent=4) - - # this is just for debugging purposes remove in production code - # debug_print_yaml_item(typ, data, default_style, offset, raw_yml) - - if raw_yml: - - # remove all encapsulation newlines - raw_yml = re.sub('\n+$', '', raw_yml) - raw_yml = re.sub('^\n+', '', raw_yml) - - if offset > 0: - lines = raw_yml.split('\n') - for i in range(len(lines)): - if lines[i] != '': - lines[i] = ' ' * offset + lines[i] - raw_yml = '\n'.join(lines) - - if typ == TYPE_LIST or typ == TYPE_SCRIPT: - # indent sequence items by 2 spaces - new_raw_yml = [] - for line in raw_yml.split('\n'): - if re.match(r'^\s*$', line): - new_raw_yml.append('') - elif len(new_raw_yml) > 0: - new_raw_yml.append(' ' + line) - else: - new_raw_yml.append(line) - raw_yml = '\n'.join(new_raw_yml) - elif typ == TYPE_MULTILINE: - # remove quotes from mulit line keys - raw_yml = re.sub(r'^(\s*)"([a-zA-Z0-9]+)":(\s*\|-)$', '\\1\\2:\\3', raw_yml, flags=re.MULTILINE) - - return raw_yml - - def format_yml_build_entry(build): - result = [] - for field in build_flags: - value = getattr(build, field, None) - if value: - typ = flagtype(field) - line = format_yml_field(field, value, typ, width=0xffffffff, offset=4) - if re.match(r'^\s+$', line): - result.append('') - else: - result.append(line) - result[0] = ' - ' + result[0][4:] - return '\n'.join(result) - result = [] for field in yaml_app_field_order: if field == '\n': @@ -1219,9 +1220,9 @@ def write_yaml(mf, app): first_build_entry = False else: result.append('') - result.append(format_yml_build_entry(build)) + result.append(_format_yml_build_entry(build)) if value: - result.append(format_yml_field(field, value, yml_fieldtype(field))) + result.append(_format_yml_field(field, value, yml_fieldtype(field))) mf.write('\n'.join(result)) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 1e4a21b4..d23271f7 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -255,9 +255,8 @@ class MetadataTest(unittest.TestCase): UpdateCheckData: https://raw.githubusercontent.com/proj/app/master/AndroidManifest.xml|android:versionCode="([0-9]*)"|.|android:versionCode="([0-9]*)" CurrentVersion: 1.0.1 CurrentVersionCode: 101 - - NoSourceSince: 1.0.1""")) + NoSourceSince: 1.0.1""")) def test_rewrite_yaml_fakeotaupdate(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) From 06ef99be6a504486b4c982466c15e89bf7b6f5fa Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 22 Mar 2019 10:54:28 +0100 Subject: [PATCH 0029/2775] deploy: show HTTP errors when virustotal error fails. Otherwise, this was posting mystery JSON parsing errors because it was trying to parse the HTTP error page as JSON. This also moves the virustotal API key to post data so it is not printed out in the stacktrace. --- fdroidserver/server.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index ac9cba03..ca4b2d6b 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -501,14 +501,14 @@ def upload_to_virustotal(repo_section, vt_apikey): headers = { "User-Agent": "F-Droid" } - params = { + data = { 'apikey': vt_apikey, 'resource': package['hash'], } needs_file_upload = False while True: r = requests.post('https://www.virustotal.com/vtapi/v2/file/report', - params=params, headers=headers) + data=data, headers=headers) if r.status_code == 200: response = r.json() if response['response_code'] == 0: @@ -535,7 +535,10 @@ def upload_to_virustotal(repo_section, vt_apikey): 'file': (filename, open(repofilename, 'rb')) } r = requests.post('https://www.virustotal.com/vtapi/v2/file/scan', - params=params, headers=headers, files=files) + data=data, headers=headers, files=files) + logging.debug('If this upload fails, try manually uploading here:\n' + + 'https://www.virustotal.com/') + r.raise_for_status() response = r.json() logging.info(response['verbose_msg'] + " " + response['permalink']) From 3798a884a6b963b178b113ba17326125189eed6a Mon Sep 17 00:00:00 2001 From: Nico Alt Date: Fri, 22 Mar 2019 17:15:58 +0100 Subject: [PATCH 0030/2775] Flush file before passing it to next function When downloading a repo index, the downloaded index got written to a file with `.write()` in a `with` clause. Before the file got actually written to the disk, it got already passed into the next function, resulting in a `VerificationException`: ``` JAR signature failed to verify: /tmp/tmppq2r51r0 jarsigner: java.util.zip.ZipException: zip file is empty ``` This behavior got introduced in 869cc114a3926fe6ffbfb55c3e8329f773c532cf. I've found this bug with help of Repomaker's tests: https://gitlab.com/fdroid/repomaker/merge_requests/215#note_148994053 --- fdroidserver/index.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 29027a38..95f7f256 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -717,6 +717,7 @@ def download_repo_index(url_str, etag=None, verify_fingerprint=True, timeout=600 with tempfile.NamedTemporaryFile() as fp: fp.write(download) + fp.flush() index, public_key, public_key_fingerprint = get_index_from_jar(fp.name, fingerprint) index["repo"]["pubkey"] = hexlify(public_key).decode() index["repo"]["fingerprint"] = public_key_fingerprint From a5851c083da68379d3c47d1d1df988e7966cac65 Mon Sep 17 00:00:00 2001 From: Nico Alt Date: Fri, 22 Mar 2019 17:15:58 +0100 Subject: [PATCH 0031/2775] Flush file before passing it to next function When downloading a repo index, the downloaded index got written to a file with `.write()` in a `with` clause. Before the file got actually written to the disk, it got already passed into the next function, resulting in a `VerificationException`: ``` JAR signature failed to verify: /tmp/tmppq2r51r0 jarsigner: java.util.zip.ZipException: zip file is empty ``` This behavior got introduced in 869cc114a3926fe6ffbfb55c3e8329f773c532cf. I've found this bug with help of Repomaker's tests: https://gitlab.com/fdroid/repomaker/merge_requests/215#note_148994053 --- fdroidserver/index.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index d8477dc5..7fbbea44 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -717,6 +717,7 @@ def download_repo_index(url_str, etag=None, verify_fingerprint=True, timeout=600 with tempfile.NamedTemporaryFile() as fp: fp.write(download) + fp.flush() index, public_key, public_key_fingerprint = get_index_from_jar(fp.name, fingerprint) index["repo"]["pubkey"] = hexlify(public_key).decode() index["repo"]["fingerprint"] = public_key_fingerprint From bb80c729f53beffe8a6f36432022803fcf700c61 Mon Sep 17 00:00:00 2001 From: Nico Alt Date: Fri, 29 Mar 2019 08:42:49 +0100 Subject: [PATCH 0032/2775] Version 1.1.2, including changelog --- CHANGELOG.md | 4 ++++ setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a76b7013..e78ed677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ +### 1.1.2 (2019-03-29) + +* fix bug while downloading repo index ([!636](https://gitlab.com/fdroid/fdroidserver/merge_requests/636)) + ### 1.1.1 (2019-02-03) * support APK Signature v2 and v3 diff --git a/setup.py b/setup.py index 6a4aac60..c32f4449 100755 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ def get_data_files(): setup(name='fdroidserver', - version='1.1.1', + version='1.1.2', description='F-Droid Server Tools', long_description='README.md', long_description_content_type='text/markdown', From 457cf22361060b736145b8bb9a3d0cfa2f81dfea Mon Sep 17 00:00:00 2001 From: Taco Date: Sat, 30 Mar 2019 17:10:21 -0400 Subject: [PATCH 0033/2775] Added newer ndks, gradles, latest sdk-license, and update java 1.8 version --- .gitlab-ci.yml | 4 ++-- .travis.yml | 9 +++++++-- buildserver/config.buildserver.py | 4 ++-- buildserver/provision-android-ndk | 2 +- buildserver/provision-android-sdk | 3 +++ examples/config.py | 6 +++--- gradlew-fdroid | 4 +++- makebuildserver | 10 ++++++---- tests/common.TestCase | 6 +++--- 9 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 98ffea9e..6c5f7ebc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -177,7 +177,7 @@ fedora_latest: - useradd -m -c "test account" --password "fakepassword" testuser - su testuser --login --command "cd `pwd`; pip3 install --user dist/fdroidserver-*.tar.gz" - test -e ~testuser/.local/share/locale/de/LC_MESSAGES/fdroidserver.mo - - wget --no-verbose -O tools.zip https://dl.google.com/android/repository/tools_r25.2.4-linux.zip + - wget --no-verbose -O tools.zip https://dl.google.com/android/repository/tools_r25.2.5-linux.zip - unzip -q tools.zip - rm tools.zip - export AAPT_VERSION=`sed -n "s,^MINIMUM_AAPT_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py` @@ -186,7 +186,7 @@ fedora_latest: - mkdir $ANDROID_HOME - mv tools $ANDROID_HOME/ - mkdir -p $ANDROID_HOME/licenses/ - - printf "\n8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e" > $ANDROID_HOME/licenses/android-sdk-license + - printf "\n8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e\n24333f8a63b6825ea9c5514f83c2829b004d1fee" > $ANDROID_HOME/licenses/android-sdk-license - printf "\n84831b9409646a918e30573bab4c9c91346d8abd" > $ANDROID_HOME/licenses/android-sdk-preview-license - printf "\n79120722343a6f314e0719f863036c702b0e6b2a\n84831b9409646a918e30573bab4c9c91346d8abd" > $ANDROID_HOME/licenses/android-sdk-preview-license-old - mkdir ~/.android diff --git a/.travis.yml b/.travis.yml index 97288607..864345ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,10 @@ matrix: include: - os: linux language: android + - os: osx + osx_image: xcode10.2 + env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk + env: ANDROID_HOME=/usr/local/share/android-sdk - os: osx osx_image: xcode9.3 env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk @@ -36,7 +40,7 @@ addons: android: components: - android-23 # required for `fdroid build` test - - build-tools-27.0.3 # required for `fdroid build` test + - build-tools-28.0.3 # required for `fdroid build` test licenses: - 'android-sdk-preview-.+' - 'android-sdk-license-.+' @@ -60,7 +64,7 @@ install: fi; brew install dash bash gnu-sed gradle jenv; export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"; - if ! ruby -e 'v = `javac -version 2>&1`.split()[1].gsub("_", "."); exit Gem::Dependency.new("", "~> 1.8.0.131").match?("", v)'; then + if ! ruby -e 'v = `javac -version 2>&1`.split()[1].gsub("_", "."); exit Gem::Dependency.new("", "~> 1.8.0.202").match?("", v)'; then brew cask uninstall java --force; brew cask install caskroom/versions/java8; fi; @@ -70,6 +74,7 @@ install: mkdir -p "$ANDROID_HOME/licenses"; echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"; echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> "$ANDROID_HOME/licenses/android-sdk-license"; + echo -e "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" >> "$ANDROID_HOME/licenses/android-sdk-license"; echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"; echo y | $ANDROID_HOME/tools/bin/sdkmanager "platform-tools"; echo y | $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$AAPT_VERSION"; diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index 2d4ba76d..4d04f488 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -7,9 +7,9 @@ ndk_paths = { 'r14b': "/home/vagrant/android-ndk/r14b", 'r15c': "/home/vagrant/android-ndk/r15c", 'r16b': "/home/vagrant/android-ndk/r16b", - 'r17b': "/home/vagrant/android-ndk/r17b", + 'r17c': "/home/vagrant/android-ndk/r17c", 'r18b': "/home/vagrant/android-ndk/r18b", - 'r19b': "/home/vagrant/android-ndk/r19b", + 'r19c': "/home/vagrant/android-ndk/r19c", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index fd8659b7..bb652390 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17b r18b r19b; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/buildserver/provision-android-sdk b/buildserver/provision-android-sdk index b032a45a..d0e73d8a 100644 --- a/buildserver/provision-android-sdk +++ b/buildserver/provision-android-sdk @@ -101,6 +101,8 @@ cat << EOF > $ANDROID_HOME/licenses/android-sdk-license 8933bad161af4178b1185d1a37fbf41ea5269c55 d56f5187479451eabf01fb78af6dfcb131a6481e + +24333f8a63b6825ea9c5514f83c2829b004d1fee EOF cat < $ANDROID_HOME/licenses/android-sdk-preview-license @@ -109,6 +111,7 @@ cat < $ANDROID_HOME/licenses/android-sdk-preview-license EOF cat < $ANDROID_HOME/licenses/android-sdk-preview-license-old + 79120722343a6f314e0719f863036c702b0e6b2a 84831b9409646a918e30573bab4c9c91346d8abd diff --git a/examples/config.py b/examples/config.py index a064fc8f..cc84e18e 100644 --- a/examples/config.py +++ b/examples/config.py @@ -18,9 +18,9 @@ # 'r14b': None, # 'r15c': None, # 'r16b': None, -# 'r17b': None, +# 'r17c': None, # 'r18b': None, -# 'r19b': None, +# 'r19c': None, # } # Directory to store downloaded tools in (i.e. gradle versions) @@ -32,7 +32,7 @@ # } # Build tools version to be used -# build_tools = "25.0.2" +# build_tools = "28.0.3" # Force all build to use the above version of build -tools, good for testing # builds without having all of the possible build-tools installed. diff --git a/gradlew-fdroid b/gradlew-fdroid index ffd71924..300fc4d9 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -116,6 +116,8 @@ get_sha() { ["5.1.1"]="4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798" \ ["5.2"]="ff322863250159595e93b5a4d17a6f0d21c59a1a0497c1e1cf1d53826485503f" \ ["5.2.1"]="748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357" \ + ["5.3"]="bed2bdd3955be5a09ca7e0201e9d131f194f7f6c466e1795a733733ccfb09f25" \ + ["5.3.1"]="1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436" \ ) [ ! ${gradle_hashes[$1]+abc} ] && exit 1 echo "${gradle_hashes["$1"]}" @@ -137,7 +139,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index ccb970ca..cc1d6c2d 100755 --- a/makebuildserver +++ b/makebuildserver @@ -346,6 +346,8 @@ CACHE_FILES = [ '4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798'), ('https://downloads.gradle.org/distributions/gradle-5.2.1-bin.zip', '748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357'), + ('https://downloads.gradle.org/distributions/gradle-5.3.1-bin.zip', + '1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', @@ -360,12 +362,12 @@ CACHE_FILES = [ 'f01788946733bf6294a36727b99366a18369904eb068a599dde8cca2c1d2ba3c'), ('https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip', 'bcdea4f5353773b2ffa85b5a9a2ae35544ce88ec5b507301d8cf6a76b765d901'), - ('https://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip', - '5dfbbdc2d3ba859fed90d0e978af87c71a91a5be1f6e1c40ba697503d48ccecd'), + ('https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip', + '3f541adbd0330a9205ba12697f6d04ec90752c53d6b622101a2a8a856e816589'), ('https://dl.google.com/android/repository/android-ndk-r18b-linux-x86_64.zip', '4f61cbe4bbf6406aa5ef2ae871def78010eed6271af72de83f8bd0b07a9fd3fd'), - ('https://dl.google.com/android/repository/android-ndk-r19b-linux-x86_64.zip', - '0fbb1645d0f1de4dde90a4ff79ca5ec4899c835e729d692f433fda501623257a'), + ('https://dl.google.com/android/repository/android-ndk-r19c-linux-x86_64.zip', + '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), ] diff --git a/tests/common.TestCase b/tests/common.TestCase index b976376f..9b03f4cd 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -107,10 +107,10 @@ class CommonTest(unittest.TestCase): '/usr/lib/jvm/java-1.8.0-openjdk-amd64', ], '/usr/lib/jvm/java-8-openjdk-amd64'), ([ # OSX - '/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk', + '/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk', '/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk', - '/System/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk', - ], '/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk'), + '/System/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk', + ], '/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk'), ] for pathlist, choice in all_pathlists: From 67731470cc3efce1d2b942df26a59c8f2debc5e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 1 Apr 2019 10:24:00 +0000 Subject: [PATCH 0034/2775] Revert "Merge branch 'write-yaml-overhaul' into 'master'" This reverts merge request !630 --- buildserver/provision-apt-get-install | 1 + fdroidserver/metadata.py | 228 +++++++------- setup.py | 1 + .../org.fdroid.fdroid.yml | 130 ++++---- tests/metadata.TestCase | 281 ------------------ 5 files changed, 174 insertions(+), 467 deletions(-) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index 9d90d8e7..a99b6871 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -103,6 +103,7 @@ packages=" python3-setuptools python3-smmap python3-yaml + python3-ruamel.yaml quilt rsync scons diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index dbc32edc..bbf8d70b 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -248,13 +248,6 @@ def fieldtype(name): return TYPE_STRING -def yml_fieldtype(name): - if name == 'CurrentVersionCode': - return TYPE_INT - else: - return fieldtype(name) - - # In the order in which they are laid out on files build_flags_order = [ 'disable', @@ -1115,88 +1108,6 @@ def post_parse_yaml_metadata(yamldata): build[flag] = ' && '.join(build[flag]) -def _format_yml_field(field, value, typ, width=80, offset=0): - - bool_list_hack = ['gradle'] - - data = {} - default_style = None - - if typ == TYPE_INT: - data[field] = int(value) - elif typ == TYPE_BOOL: - data[field] = bool(value) - elif typ == TYPE_SCRIPT: - if type(value) != list: - value = value.split(' && ') - if len(value) > 1: - data[field] = value - else: - data[field] = value[0] - elif typ == TYPE_LIST: - if field in bool_list_hack: - if value in [True, 'yes', ['yes']]: - value = [True] - data[field] = value - elif typ == TYPE_MULTILINE: - default_style = '|' - data[field] = value.strip() - else: - data[field] = value - - raw_yml = yaml.dump(data, Dumper=yaml.SafeDumper, - default_flow_style=False, width=width, - default_style=default_style, indent=4) - - # this is just for debugging purposes remove in production code - # debug_print_yaml_item(typ, data, default_style, offset, raw_yml) - - if raw_yml: - - # remove all encapsulation newlines - raw_yml = re.sub('\n+$', '', raw_yml) - raw_yml = re.sub('^\n+', '', raw_yml) - - if offset > 0: - lines = raw_yml.split('\n') - for i in range(len(lines)): - if lines[i] != '': - lines[i] = ' ' * offset + lines[i] - raw_yml = '\n'.join(lines) - - if typ == TYPE_LIST or typ == TYPE_SCRIPT: - # indent sequence items by 2 spaces - new_raw_yml = [] - for line in raw_yml.split('\n'): - if re.match(r'^\s*$', line): - new_raw_yml.append('') - elif len(new_raw_yml) > 0: - new_raw_yml.append(' ' + line) - else: - new_raw_yml.append(line) - raw_yml = '\n'.join(new_raw_yml) - elif typ == TYPE_MULTILINE: - # remove quotes from mulit line keys - raw_yml = re.sub(r'^(\s*)"([a-zA-Z0-9]+)":(\s*\|-)$', '\\1\\2:\\3', raw_yml, flags=re.MULTILINE) - - return raw_yml - - -def _format_yml_build_entry(build): - result = [] - for field in build_flags: - value = getattr(build, field, None) - if value: - typ = flagtype(field) - line = _format_yml_field(field, value, typ, width=0xffffffff, offset=4) - if re.match(r'^\s+$', line): - result.append('') - else: - result.append(line) - result[0] = ' - ' + result[0][4:] - return '\n'.join(result) - - def write_yaml(mf, app): """Write metadata in yaml format. @@ -1204,42 +1115,117 @@ def write_yaml(mf, app): :param app: app metadata to written to the yaml file """ - result = [] - for field in yaml_app_field_order: - if field == '\n': - if result[-1] != '': - result.append('') - continue + # import rumael.yaml and check version + try: + import ruamel.yaml + except ImportError as e: + raise FDroidException('ruamel.yaml not instlled, can not write metadata.') from e + if not ruamel.yaml.__version__: + raise FDroidException('ruamel.yaml.__version__ not accessible. Please make sure a ruamel.yaml >= 0.13 is installed..') + m = re.match(r'(?P[0-9]+)\.(?P[0-9]+)\.(?P[0-9]+)(-.+)?', + ruamel.yaml.__version__) + if not m: + raise FDroidException('ruamel.yaml version malfored, please install an upstream version of ruamel.yaml') + if int(m.group('major')) < 0 or int(m.group('minor')) < 13: + raise FDroidException('currently installed version of ruamel.yaml ({}) is too old, >= 1.13 required.'.format(ruamel.yaml.__version__)) + # suiteable version ruamel.yaml imported successfully + + _yaml_bools_true = ('y', 'Y', 'yes', 'Yes', 'YES', + 'true', 'True', 'TRUE', + 'on', 'On', 'ON') + _yaml_bools_false = ('n', 'N', 'no', 'No', 'NO', + 'false', 'False', 'FALSE', + 'off', 'Off', 'OFF') + _yaml_bools_plus_lists = [] + _yaml_bools_plus_lists.extend(_yaml_bools_true) + _yaml_bools_plus_lists.extend([[x] for x in _yaml_bools_true]) + _yaml_bools_plus_lists.extend(_yaml_bools_false) + _yaml_bools_plus_lists.extend([[x] for x in _yaml_bools_false]) + + def _class_as_dict_representer(dumper, data): + '''Creates a YAML representation of a App/Build instance''' + return dumper.represent_dict(data) + + def _field_to_yaml(typ, value): + if typ is TYPE_STRING: + if value in _yaml_bools_plus_lists: + return ruamel.yaml.scalarstring.SingleQuotedScalarString(str(value)) + return str(value) + elif typ is TYPE_INT: + return int(value) + elif typ is TYPE_MULTILINE: + if '\n' in value: + return ruamel.yaml.scalarstring.preserve_literal(str(value)) + else: + return str(value) + elif typ is TYPE_SCRIPT: + if type(value) == list: + if len(value) == 1: + return value[0] + else: + return value + else: + script_lines = value.split(' && ') + if len(script_lines) > 1: + return script_lines + else: + return value else: - value = app.get(field) - if field == 'Builds' and app.builds: - result.append('Builds:') - first_build_entry = True - for build in app.builds: - if first_build_entry: - first_build_entry = False + return value + + def _app_to_yaml(app): + cm = ruamel.yaml.comments.CommentedMap() + insert_newline = False + for field in yaml_app_field_order: + if field == '\n': + # next iteration will need to insert a newline + insert_newline = True + else: + if app.get(field) or field == 'Builds': + # .txt calls it 'builds' internally, everywhere else its 'Builds' + if field == 'Builds': + if app.get('builds'): + cm.update({field: _builds_to_yaml(app)}) + elif field == 'CurrentVersionCode': + cm.update({field: _field_to_yaml(TYPE_INT, getattr(app, field))}) else: - result.append('') - result.append(_format_yml_build_entry(build)) - if value: - result.append(_format_yml_field(field, value, yml_fieldtype(field))) - mf.write('\n'.join(result)) + cm.update({field: _field_to_yaml(fieldtype(field), getattr(app, field))}) + if insert_newline: + # we need to prepend a newline in front of this field + insert_newline = False + # inserting empty lines is not supported so we add a + # bogus comment and over-write its value + cm.yaml_set_comment_before_after_key(field, 'bogus') + cm.ca.items[field][1][-1].value = '\n' + return cm -def debug_print_yaml_item(typ, data, default_style, offset, raw_yml): - """function debugging indiviudal lines during yaml writing""" - typTable = {0: 'TYPE_UNKNOWN', - 1: 'TYPE_OBSOLETE', - 2: 'TYPE_STRING', - 3: 'TYPE_BOOL', - 4: 'TYPE_LIST', - 5: 'TYPE_SCRIPT', - 6: 'TYPE_MULTILINE', - 7: 'TYPE_BUILD', - 8: 'TYPE_INT'} - print('###', '(' + typTable[typ] + ', default_style=' - + str(default_style) + ', offset=' + str(offset) + ')\n', - data, '->', raw_yml if raw_yml else '') + def _builds_to_yaml(app): + builds = ruamel.yaml.comments.CommentedSeq() + for build in app.builds: + b = ruamel.yaml.comments.CommentedMap() + for field in build_flags: + value = getattr(build, field) + if hasattr(build, field) and value: + if field == 'gradle' and value == ['off']: + value = [ruamel.yaml.scalarstring.SingleQuotedScalarString('off')] + if field in ('maven', 'buildozer'): + if value == 'no': + continue + elif value == 'yes': + value = 'yes' + b.update({field: _field_to_yaml(flagtype(field), value)}) + builds.append(b) + + # insert extra empty lines between build entries + for i in range(1, len(builds)): + builds.yaml_set_comment_before_after_key(i, 'bogus') + builds.ca.items[i][1][-1].value = '\n' + + return builds + + yaml_app = _app_to_yaml(app) + ruamel.yaml.round_trip_dump(yaml_app, mf, indent=4, block_seq_indent=2) build_line_sep = re.compile(r'(?= 0.13', 'requests >= 2.5.2, != 2.11.0, != 2.12.2, != 2.18.0', 'docker-py >= 1.9, < 2.0', ], diff --git a/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml b/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml index 322738df..9471f9a6 100644 --- a/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml +++ b/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml @@ -199,14 +199,14 @@ Builds: commit: 0.53-test submodules: true scandelete: - - 'yes' + - yes - versionName: '0.54' versionCode: 540 commit: '0.54' submodules: true scandelete: - - 'yes' + - yes - versionName: '0.55' versionCode: 550 @@ -498,7 +498,7 @@ Builds: subdir: F-Droid submodules: true gradle: - - true + - yes - versionName: 0.95-alpha1 versionCode: 95001 @@ -506,7 +506,7 @@ Builds: subdir: F-Droid submodules: true gradle: - - true + - yes - versionName: 0.95-alpha2 versionCode: 95002 @@ -514,7 +514,7 @@ Builds: subdir: F-Droid submodules: true gradle: - - true + - yes - versionName: '0.95' versionCode: 95050 @@ -522,7 +522,7 @@ Builds: subdir: F-Droid submodules: true gradle: - - true + - yes - versionName: 0.95.1 versionCode: 95150 @@ -530,56 +530,56 @@ Builds: subdir: F-Droid submodules: true gradle: - - true + - yes - versionName: 0.96-alpha1 versionCode: 96001 commit: v0.96-alpha1 subdir: F-Droid gradle: - - true + - yes - versionName: 0.96-alpha2 versionCode: 96002 commit: v0.96-alpha2 subdir: F-Droid gradle: - - true + - yes - versionName: 0.96-alpha3 versionCode: 96003 commit: v0.96-alpha3 subdir: F-Droid gradle: - - true + - yes - versionName: 0.96-alpha4 versionCode: 96004 commit: v0.96-alpha4 subdir: F-Droid gradle: - - true + - yes - versionName: 0.96-alpha5 versionCode: 96005 commit: v0.96-alpha5 subdir: F-Droid gradle: - - true + - yes - versionName: 0.96-alpha6 versionCode: 96006 commit: v0.96-alpha6 subdir: F-Droid gradle: - - true + - yes - versionName: '0.96' versionCode: 96050 commit: v0.96 subdir: F-Droid gradle: - - true + - yes scanignore: - extern/AndroidPinning/res/raw/cacerts @@ -588,7 +588,7 @@ Builds: commit: v0.96.1 subdir: F-Droid gradle: - - true + - yes scanignore: - extern/AndroidPinning/res/raw/cacerts @@ -597,7 +597,7 @@ Builds: commit: v0.97-alpha1 subdir: F-Droid gradle: - - true + - yes scanignore: - extern/AndroidPinning/res/raw/cacerts @@ -606,343 +606,343 @@ Builds: commit: v0.97-alpha2 subdir: F-Droid gradle: - - true + - yes - versionName: 0.97-alpha3 versionCode: 97003 commit: v0.97-alpha3 subdir: F-Droid gradle: - - true + - yes - versionName: 0.97-alpha4 versionCode: 97004 commit: v0.97-alpha4 subdir: F-Droid gradle: - - true + - yes - versionName: 0.97-alpha5 versionCode: 97005 commit: v0.97-alpha5 subdir: F-Droid gradle: - - true + - yes - versionName: 0.97-alpha6 versionCode: 97006 commit: v0.97-alpha6 subdir: F-Droid gradle: - - true + - yes - versionName: 0.97-alpha7 versionCode: 97007 commit: v0.97-alpha7 subdir: F-Droid gradle: - - true + - yes - versionName: 0.97-alpha8 versionCode: 97008 commit: v0.97-alpha8 subdir: F-Droid gradle: - - true + - yes - versionName: '0.97' versionCode: 97050 commit: v0.97 subdir: F-Droid gradle: - - true + - yes - versionName: 0.98-alpha1 versionCode: 98001 commit: v0.98-alpha1 subdir: F-Droid gradle: - - true + - yes - versionName: 0.98-alpha2 versionCode: 98002 commit: v0.98-alpha2 subdir: F-Droid gradle: - - true + - yes - versionName: 0.98-alpha3 versionCode: 98003 commit: v0.98-alpha3 subdir: F-Droid gradle: - - true + - yes - versionName: 0.98-alpha4 versionCode: 98004 commit: v0.98-alpha4 subdir: F-Droid gradle: - - true + - yes - versionName: 0.98-alpha5 versionCode: 98005 commit: v0.98-alpha5 subdir: F-Droid gradle: - - true + - yes - versionName: 0.98-alpha6 versionCode: 98006 commit: v0.98-alpha6 subdir: F-Droid gradle: - - true + - yes - versionName: 0.98-alpha7 versionCode: 98007 commit: v0.98-alpha7 subdir: F-Droid gradle: - - true + - yes - versionName: '0.98' versionCode: 98050 commit: v0.98 subdir: F-Droid gradle: - - true + - yes - versionName: 0.98.1 versionCode: 98150 commit: v0.98.1 subdir: F-Droid gradle: - - true + - yes - versionName: 0.99-alpha1 versionCode: 99001 commit: v0.99-alpha1 subdir: F-Droid gradle: - - true + - yes - versionName: 0.99-alpha2 versionCode: 99002 commit: v0.99-alpha2 subdir: F-Droid gradle: - - true + - yes - versionName: '0.99' versionCode: 99050 commit: v0.99 subdir: F-Droid gradle: - - true + - yes - versionName: 0.99.1 versionCode: 99150 commit: v0.99.1 subdir: F-Droid gradle: - - true + - yes - versionName: 0.99.2 versionCode: 99250 commit: v0.99.2 subdir: F-Droid gradle: - - true + - yes - versionName: 0.100-alpha1 versionCode: 100001 commit: v0.100-alpha1 subdir: F-Droid gradle: - - true + - yes - versionName: 0.100-alpha2 versionCode: 100002 commit: v0.100-alpha2 subdir: F-Droid gradle: - - true + - yes - versionName: 0.100-alpha3 versionCode: 100003 commit: v0.100-alpha3 subdir: app gradle: - - true + - yes - versionName: 0.100-alpha4 versionCode: 100004 commit: v0.100-alpha4 subdir: app gradle: - - true + - yes - versionName: 0.100-alpha5 versionCode: 100005 commit: v0.100-alpha5 subdir: app gradle: - - true + - yes - versionName: 0.100-alpha6 versionCode: 100006 commit: v0.100-alpha6 subdir: app gradle: - - true + - yes - versionName: 0.100-alpha7 versionCode: 100007 commit: v0.100-alpha7 subdir: app gradle: - - true + - yes - versionName: 0.100-alpha8 versionCode: 100008 commit: v0.100-alpha8 subdir: app gradle: - - true + - yes - versionName: '0.100' versionCode: 100050 commit: v0.100 subdir: app gradle: - - true + - yes - versionName: 0.100.1 versionCode: 100150 commit: v0.100.1 subdir: app gradle: - - true + - yes - versionName: 0.101-alpha1 versionCode: 101001 commit: v0.101-alpha1 subdir: app gradle: - - true + - yes - versionName: 0.101-alpha2 versionCode: 101002 commit: v0.101-alpha2 subdir: app gradle: - - true + - yes - versionName: 0.101-alpha3 versionCode: 101003 commit: v0.101-alpha3 subdir: app gradle: - - true + - yes - versionName: 0.101-alpha4 versionCode: 101004 commit: v0.101-alpha4 subdir: app gradle: - - true + - yes - versionName: 0.101-alpha5 versionCode: 101005 commit: v0.101-alpha5 subdir: app gradle: - - true + - yes - versionName: 0.101-alpha6 versionCode: 101006 commit: v0.101-alpha6 subdir: app gradle: - - true + - yes - versionName: '0.101' versionCode: 101050 commit: v0.101 subdir: app gradle: - - true + - yes - versionName: 0.102-alpha1 versionCode: 102001 commit: v0.102-alpha1 subdir: app gradle: - - true + - yes - versionName: 0.102-alpha2 versionCode: 102002 commit: v0.102-alpha2 subdir: app gradle: - - true + - yes - versionName: 0.102-alpha3 versionCode: 102003 commit: v0.102-alpha3 subdir: app gradle: - - true + - yes - versionName: '0.102' versionCode: 102050 commit: v0.102 subdir: app gradle: - - true + - yes - versionName: 0.102.1 versionCode: 102150 commit: v0.102.1 subdir: app gradle: - - true + - yes - versionName: 0.102.2 versionCode: 102250 commit: v0.102.2 subdir: app gradle: - - true + - yes - versionName: 0.102.3 versionCode: 102350 commit: v0.102.3 subdir: app gradle: - - true + - yes - versionName: 0.103-alpha1 versionCode: 103001 commit: v0.103-alpha1 subdir: app gradle: - - true + - yes - versionName: 0.103-alpha2 versionCode: 103002 commit: v0.103-alpha2 subdir: app gradle: - - true + - yes - versionName: 0.103-alpha3 versionCode: 103003 commit: v0.103-alpha3 subdir: app gradle: - - true + - yes ArchivePolicy: 12 versions AutoUpdateMode: None diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index d23271f7..486dca09 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -70,194 +70,6 @@ class MetadataTest(unittest.TestCase): # yaml.add_representer(fdroidserver.metadata.Build, _build_yaml_representer) # yaml.dump(frommeta, f, default_flow_style=False) - def test_write_yaml_allfields(self): - - mf = io.StringIO() - - app = fdroidserver.metadata.App() - app.Disabled = True - app.AntiFeatures = ['Karl', 'Bert'] - app.Provides = "org.fdroid.fdroid" - app.Categories = ['Secret', 'Stuff'] - app.License = 'GPL-3.0-or-later' - app.AuthorName = 'He who must not be named.' - app.AuthorEmail = 'tom@f-droid.org' - app.AuthorWebSite = 'https://f-droid.org/~theDarkLord' - app.WebSite = 'https://f-droid.org' - app.SourceCode = 'https://gitlab.com/fdroid/fdroidclient.git' - app.IssueTracker = "https://gitlab.com/fdroid/fdroidclient/issues" - app.Translation = 'https://hosted.weblate.org/projects/f-droid/f-droid' - app.Changelog = 'https://example.com/fdroidclient/raw/master/CHANGELOG.md' - app.Donate = 'https://f-droid.org/about' - app.FlattrID = '343053' - app.LiberapayID = '27859' - app.Bitcoin = '15u8aAPK4jJ5N8wpWJ5gutAyyeHtKX5i18' - app.Litecoin = '000000000000000000000000000000000' - app.Name = 'F-Droid' - app.AutoName = 'F-Droid' - app.Summary = 'The app store that respects freedom and privacy' - app.Description = 'The app store that respects freedom and privacy' - app.RequiresRoot = True - app.RepoType = 'git' - app.Repo = 'https://gitlab.com/fdroid/fdroidclient.git' - app.Binaries = 'https://f-droid.org/fdroid-%v.apk' - app.builds = [] - - build = fdroidserver.metadata.Build() - build.versionName = '1.0.1' - build.versionCode = 101 - build.disable = 'for this reason' - build.commit = '1.0.1' - build.timeout = 12345 - build.subdir = 'app' - build.submodules = True - build.sudo = 'apt-get update -y && apt-get upgrade -y' - build.init = 'sed -i -e "/replace this/with that/" build.gradle' - build.patch = ['remove-play-services.patch', 'add-other-service.patch'] - build.gradle = 'flavor' - build.maven = True - build.buildozer = True - build.output = 'app/build/fdroid-$$VERSION$$.zip' - build.scrlibs = ['DragSort@0.6.1,3', 'SlidingMenu@7ebe32772'] - build.oldsdkloc = True - build.encoding = 'utf-8' - build.forceversion = True - build.forcevercode = True - build.rm = ['app/file1', 'app/file2', 'app/other*'] - build.extlibs = ['android/android-support-v4.jar', 'android/android-support-v13.jar'] - build.prebuild = 'sed -i -e "/replace this/with that/" build.gradle' - build.androidupdate = [False] - build.target = 'android-99' - build.scanignore = ['libs/a.so', 'libs/b.so'] - build.scandelete = ['bin/exec', 'bin/run'] - build.build = 'export NDK_DIR=$$NDK$$' - build.buildjni = True - build.ndk = 'r99b' - build.preassemble = ':gradleTask' - build.gradleprops = 'prop4gradle' - build.antcommands = 'package' - build.novcheck = True - build.antifeatures = ['Karl', 'Hank'] - app.builds.append(build) - - app.MaintainerNotes = 'Great app, highly recommended.' - app.ArchivePolicy = '3 versions' - app.AutoUpdateMode = 'None' - app.UpdateCheckMode = 'Tags' - app.UpdateCheckIgnore = '(alpha|beta|rc|RC|dev)' - app.VercodeOperation = '%c + 2' - app.UpdateCheckName = 'org.fdroid.fdroid' - app.UpdateCheckData = 'https://raw.githubusercontent.com/proj/app/master/AndroidManifest.xml|android:versionCode="([0-9]*)"|.|android:versionCode="([0-9]*)"' - app.CurrentVersion = '1.0.1' - app.CurrentVersionCode = 101 - app.NoSourceSince = '1.0.1' - - fdroidserver.metadata.write_yaml(mf, app) - mf.seek(0) - - self.maxDiff = None - self.assertEqual(mf.read(), textwrap.dedent("""\ - Disabled: true - AntiFeatures: - - Karl - - Bert - Provides: org.fdroid.fdroid - Categories: - - Secret - - Stuff - License: GPL-3.0-or-later - AuthorName: He who must not be named. - AuthorEmail: tom@f-droid.org - AuthorWebSite: https://f-droid.org/~theDarkLord - WebSite: https://f-droid.org - SourceCode: https://gitlab.com/fdroid/fdroidclient.git - IssueTracker: https://gitlab.com/fdroid/fdroidclient/issues - Translation: https://hosted.weblate.org/projects/f-droid/f-droid - Changelog: https://example.com/fdroidclient/raw/master/CHANGELOG.md - Donate: https://f-droid.org/about - FlattrID: '343053' - LiberapayID: '27859' - Bitcoin: 15u8aAPK4jJ5N8wpWJ5gutAyyeHtKX5i18 - Litecoin: '000000000000000000000000000000000' - - Name: F-Droid - AutoName: F-Droid - Summary: The app store that respects freedom and privacy - Description: |- - The app store that respects freedom and privacy - - RequiresRoot: true - - RepoType: git - Repo: https://gitlab.com/fdroid/fdroidclient.git - Binaries: https://f-droid.org/fdroid-%v.apk - - Builds: - - versionName: 1.0.1 - versionCode: 101 - disable: for this reason - commit: 1.0.1 - timeout: 12345 - subdir: app - submodules: true - sudo: - - apt-get update -y - - apt-get upgrade -y - init: sed -i -e "/replace this/with that/" build.gradle - patch: - - remove-play-services.patch - - add-other-service.patch - gradle: flavor - maven: true - buildozer: true - output: app/build/fdroid-$$VERSION$$.zip - oldsdkloc: true - encoding: utf-8 - forceversion: true - forcevercode: true - rm: - - app/file1 - - app/file2 - - app/other* - extlibs: - - android/android-support-v4.jar - - android/android-support-v13.jar - prebuild: sed -i -e "/replace this/with that/" build.gradle - androidupdate: - - false - target: android-99 - scanignore: - - libs/a.so - - libs/b.so - scandelete: - - bin/exec - - bin/run - build: export NDK_DIR=$$NDK$$ - buildjni: true - ndk: r99b - preassemble: :gradleTask - gradleprops: prop4gradle - antcommands: package - novcheck: true - antifeatures: - - Karl - - Hank - - MaintainerNotes: |- - Great app, highly recommended. - - ArchivePolicy: 3 versions - AutoUpdateMode: None - UpdateCheckMode: Tags - UpdateCheckIgnore: (alpha|beta|rc|RC|dev) - VercodeOperation: '%c + 2' - UpdateCheckName: org.fdroid.fdroid - UpdateCheckData: https://raw.githubusercontent.com/proj/app/master/AndroidManifest.xml|android:versionCode="([0-9]*)"|.|android:versionCode="([0-9]*)" - CurrentVersion: 1.0.1 - CurrentVersionCode: 101 - - NoSourceSince: 1.0.1""")) - def test_rewrite_yaml_fakeotaupdate(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']} @@ -495,68 +307,6 @@ class MetadataTest(unittest.TestCase): 'prebuild': "a && b && " "sed -i 's,a,b,'"}]}) - def test_write_yaml_description_with_trailing_whitespace(self): - mf = io.StringIO() - app = fdroidserver.metadata.App() - app.Categories = ['None'] - app.Description = "this evil description has a trailing whitespace " - app.builds = [] - build = fdroidserver.metadata.Build() - build.versionCode = 102030 - build.versionName = 'v1.2.3' - build.build = "./gradlew compile" - app.builds.append(build) - fdroidserver.metadata.write_yaml(mf, app) - mf.seek(0) - self.maxDiff = None - self.assertEqual(mf.read(), textwrap.dedent("""\ - Categories: - - None - License: Unknown - - Description: |- - this evil description has a trailing whitespace - - Builds: - - versionName: v1.2.3 - versionCode: 102030 - build: ./gradlew compile - - AutoUpdateMode: None - UpdateCheckMode: None - """)) - - def test_write_yaml_long_description(self): - mf = io.StringIO() - app = fdroidserver.metadata.App() - app.Categories = ['None'] - app.Description = "long description is long; " * 20 - app.builds = [] - build = fdroidserver.metadata.Build() - build.versionCode = 102030 - build.versionName = 'v1.2.3' - build.build = "./gradlew compile" - app.builds.append(build) - fdroidserver.metadata.write_yaml(mf, app) - mf.seek(0) - self.maxDiff = None - self.assertEqual(mf.read(), textwrap.dedent("""\ - Categories: - - None - License: Unknown - - Description: |- - long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; long description is long; - - Builds: - - versionName: v1.2.3 - versionCode: 102030 - build: ./gradlew compile - - AutoUpdateMode: None - UpdateCheckMode: None - """)) - def test_write_yaml_1_line_scripts_as_string(self): mf = io.StringIO() app = fdroidserver.metadata.App() @@ -711,37 +461,6 @@ class MetadataTest(unittest.TestCase): UpdateCheckMode: None """)) - def test_write_yaml_very_long_script(self): - mf = io.StringIO() - app = fdroidserver.metadata.App() - app.Categories = ['None'] - app.builds = [] - build = fdroidserver.metadata.Build() - build.versionCode = 102030 - build.versionName = 'v1.2.3' - build.build = "./gradlew someSpecialTask && sed -i 'd/that wrong config/' gradle.properties && ./gradlew compile && long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long;" - app.builds.append(build) - fdroidserver.metadata.write_yaml(mf, app) - mf.seek(0) - self.maxDiff = None - self.assertEqual(mf.read(), textwrap.dedent("""\ - Categories: - - None - License: Unknown - - Builds: - - versionName: v1.2.3 - versionCode: 102030 - build: - - ./gradlew someSpecialTask - - sed -i 'd/that wrong config/' gradle.properties - - ./gradlew compile - - long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; long script is very long; - - AutoUpdateMode: None - UpdateCheckMode: None - """)) - if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 0ea03ddfaa4d73de49ea7fecaa5460057012df20 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Mon, 8 Apr 2019 16:30:32 +0000 Subject: [PATCH 0035/2775] metadata.py - typo --- fdroidserver/metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index bbf8d70b..2b970c8a 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -1119,7 +1119,7 @@ def write_yaml(mf, app): try: import ruamel.yaml except ImportError as e: - raise FDroidException('ruamel.yaml not instlled, can not write metadata.') from e + raise FDroidException('ruamel.yaml not installed, can not write metadata.') from e if not ruamel.yaml.__version__: raise FDroidException('ruamel.yaml.__version__ not accessible. Please make sure a ruamel.yaml >= 0.13 is installed..') m = re.match(r'(?P[0-9]+)\.(?P[0-9]+)\.(?P[0-9]+)(-.+)?', From 01fb62fff4c171785f63ede2d1d929a6a790a352 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 11 Apr 2019 13:30:23 +0200 Subject: [PATCH 0036/2775] publish: fix stupid error in repro-signing and add integration test stoopid mistake in ea84014f9b10114a0022961d86c8e43512b3ba48 --- fdroidserver/publish.py | 2 +- tests/run-tests | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index ac9a3f44..1369d177 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -280,7 +280,7 @@ def main(): signaturefile, signedfile, manifest = signingfiles with open(signaturefile, 'rb') as f: - devfp = common.signer_fingerprint_short(common.get_signature(f.read())) + devfp = common.signer_fingerprint_short(common.get_certificate(f.read())) devsigned = '{}_{}_{}.apk'.format(appid, vercode, devfp) devsignedtmp = os.path.join(tmp_dir, devsigned) shutil.copy(apkfile, devsignedtmp) diff --git a/tests/run-tests b/tests/run-tests index 63e3b71b..63cefb94 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -1104,6 +1104,35 @@ if have_git_2_3; then fi +#------------------------------------------------------------------------------# +echo_header 'test extracting and publishing with developer signature' + +REPOROOT=`create_test_dir` +cd $REPOROOT +fdroid_init_with_prebuilt_keystore +echo "accepted_formats = ['txt']" >> config.py +echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py +test -d metadata || mkdir metadata +cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ +test -d repo || mkdir repo +test -d unsigned || mkdir unsigned +cp $WORKSPACE/tests/repo/com.politedroid_6.apk unsigned/ +$fdroid signatures unsigned/com.politedroid_6.apk +test -d metadata/com.politedroid/signatures/6 +test -f metadata/com.politedroid/signatures/6/MANIFEST.MF +test -f metadata/com.politedroid/signatures/6/RELEASE.RSA +test -f metadata/com.politedroid/signatures/6/RELEASE.SF +! test -f repo/com.politedroid_6.apk +$fdroid publish +test -f repo/com.politedroid_6.apk +if which jarsigner; then + jarsigner -verify repo/com.politedroid_6.apk +fi +if which apksigner; then + apksigner verify repo/com.politedroid_6.apk +fi + + #------------------------------------------------------------------------------# # remove this to prevent git conflicts and complaining From dd2f9d60f8723d2ced34be32d354d3c8b796f24d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 11 Apr 2019 13:30:23 +0200 Subject: [PATCH 0037/2775] publish: fix stupid error in repro-signing and add integration test stoopid mistake in ea84014f9b10114a0022961d86c8e43512b3ba48 reported by @CiaranG --- fdroidserver/publish.py | 2 +- tests/run-tests | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index ac9a3f44..1369d177 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -280,7 +280,7 @@ def main(): signaturefile, signedfile, manifest = signingfiles with open(signaturefile, 'rb') as f: - devfp = common.signer_fingerprint_short(common.get_signature(f.read())) + devfp = common.signer_fingerprint_short(common.get_certificate(f.read())) devsigned = '{}_{}_{}.apk'.format(appid, vercode, devfp) devsignedtmp = os.path.join(tmp_dir, devsigned) shutil.copy(apkfile, devsignedtmp) diff --git a/tests/run-tests b/tests/run-tests index 63e3b71b..63cefb94 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -1104,6 +1104,35 @@ if have_git_2_3; then fi +#------------------------------------------------------------------------------# +echo_header 'test extracting and publishing with developer signature' + +REPOROOT=`create_test_dir` +cd $REPOROOT +fdroid_init_with_prebuilt_keystore +echo "accepted_formats = ['txt']" >> config.py +echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py +test -d metadata || mkdir metadata +cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ +test -d repo || mkdir repo +test -d unsigned || mkdir unsigned +cp $WORKSPACE/tests/repo/com.politedroid_6.apk unsigned/ +$fdroid signatures unsigned/com.politedroid_6.apk +test -d metadata/com.politedroid/signatures/6 +test -f metadata/com.politedroid/signatures/6/MANIFEST.MF +test -f metadata/com.politedroid/signatures/6/RELEASE.RSA +test -f metadata/com.politedroid/signatures/6/RELEASE.SF +! test -f repo/com.politedroid_6.apk +$fdroid publish +test -f repo/com.politedroid_6.apk +if which jarsigner; then + jarsigner -verify repo/com.politedroid_6.apk +fi +if which apksigner; then + apksigner verify repo/com.politedroid_6.apk +fi + + #------------------------------------------------------------------------------# # remove this to prevent git conflicts and complaining From 9045e2854a7cb8dd7892defcfdb4fa97ba4898ce Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 11 Apr 2019 14:16:03 +0200 Subject: [PATCH 0038/2775] travis-ci: revert change that broke upgrading old Java https://gitlab.com/fdroid/fdroidserver/merge_requests/637#note_159786747 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 864345ef..ae838b54 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,7 +64,7 @@ install: fi; brew install dash bash gnu-sed gradle jenv; export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"; - if ! ruby -e 'v = `javac -version 2>&1`.split()[1].gsub("_", "."); exit Gem::Dependency.new("", "~> 1.8.0.202").match?("", v)'; then + if ! ruby -e 'v = `javac -version 2>&1`.split()[1].gsub("_", "."); exit Gem::Dependency.new("", "~> 1.8.0.131").match?("", v)'; then brew cask uninstall java --force; brew cask install caskroom/versions/java8; fi; From 293e5483fc20740291daed55fdf840573d5a0f19 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Tue, 30 Apr 2019 17:59:13 +0000 Subject: [PATCH 0039/2775] Add Gradle 5.4 and 5.4.1, fix 5.3 --- gradlew-fdroid | 4 +++- makebuildserver | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 300fc4d9..20baf5f9 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -118,6 +118,8 @@ get_sha() { ["5.2.1"]="748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357" \ ["5.3"]="bed2bdd3955be5a09ca7e0201e9d131f194f7f6c466e1795a733733ccfb09f25" \ ["5.3.1"]="1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436" \ + ["5.4"]="c8c17574245ecee9ed7fe4f6b593b696d1692d1adbfef425bef9b333e3a0e8de" \ + ["5.4.1"]="7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc" \ ) [ ! ${gradle_hashes[$1]+abc} ] && exit 1 echo "${gradle_hashes["$1"]}" @@ -139,7 +141,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index cc1d6c2d..e5fd6efe 100755 --- a/makebuildserver +++ b/makebuildserver @@ -346,8 +346,14 @@ CACHE_FILES = [ '4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798'), ('https://downloads.gradle.org/distributions/gradle-5.2.1-bin.zip', '748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357'), + ('https://downloads.gradle.org/distributions/gradle-5.3-bin.zip', + 'bed2bdd3955be5a09ca7e0201e9d131f194f7f6c466e1795a733733ccfb09f25'), ('https://downloads.gradle.org/distributions/gradle-5.3.1-bin.zip', '1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436'), + ('https://downloads.gradle.org/distributions/gradle-5.4-bin.zip', + 'c8c17574245ecee9ed7fe4f6b593b696d1692d1adbfef425bef9b333e3a0e8de'), + ('https://downloads.gradle.org/distributions/gradle-5.4.1-bin.zip', + '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From cc193e903f3492825791d0adcdbefb6eb9041654 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 1 May 2019 14:07:39 +0200 Subject: [PATCH 0040/2775] remove obsloleted gradle versions from default buildserver install See https://gitlab.com/fdroid/fdroidserver/merge_requests/641 --- makebuildserver | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/makebuildserver b/makebuildserver index e5fd6efe..e0a7ed9f 100755 --- a/makebuildserver +++ b/makebuildserver @@ -340,18 +340,16 @@ CACHE_FILES = [ 'b49c6da1b2cb67a0caf6c7480630b51c70a11ca2016ff2f555eaeda863143a29'), ('https://downloads.gradle.org/distributions/gradle-4.10.3-bin.zip', '8626cbf206b4e201ade7b87779090690447054bc93f052954c78480fa6ed186e'), + # Only add the latest point released of gradle to the default install. + # Other versions will be downloaded on demand. ('https://downloads.gradle.org/distributions/gradle-5.0-bin.zip', '6157ac9f3410bc63644625b3b3e9e96c963afd7910ae0697792db57813ee79a6'), ('https://downloads.gradle.org/distributions/gradle-5.1.1-bin.zip', '4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798'), ('https://downloads.gradle.org/distributions/gradle-5.2.1-bin.zip', '748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357'), - ('https://downloads.gradle.org/distributions/gradle-5.3-bin.zip', - 'bed2bdd3955be5a09ca7e0201e9d131f194f7f6c466e1795a733733ccfb09f25'), ('https://downloads.gradle.org/distributions/gradle-5.3.1-bin.zip', '1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436'), - ('https://downloads.gradle.org/distributions/gradle-5.4-bin.zip', - 'c8c17574245ecee9ed7fe4f6b593b696d1692d1adbfef425bef9b333e3a0e8de'), ('https://downloads.gradle.org/distributions/gradle-5.4.1-bin.zip', '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', From 833f23cf8965c9a24794b0d25c592c87643ced10 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 1 May 2019 13:34:02 +0200 Subject: [PATCH 0041/2775] scanner: allow local Debian Maven repo file:///usr/share/maven-repo It is now possible to build an app using only things in Debian. Since the buildserver will always control the contents of file:///usr/share/maven-repo, it is the most safe repo there is. --- fdroidserver/scanner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 2d9e2a1d..5f315736 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -109,6 +109,7 @@ def scan_source(build_dir, build=metadata.Build()): 's3.amazonaws.com/repo.commonsware.com', # CommonsWare 'plugins.gradle.org/m2', # Gradle plugin repo 'maven.google.com', # Google Maven Repo, https://developer.android.com/studio/build/dependencies.html#google-maven + 'file:///usr/share/maven-repo', # local repo on Debian installs ] ] From 6e7e9b355c1a291b1535f072b5d807a8c62797fe Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 1 May 2019 13:43:24 +0200 Subject: [PATCH 0042/2775] deploy: if git mirror > 1GB after deleting history, delete the archive git mirrors are meant to be an easy way to host a repo that is zero maintenance. They are not meant to be the canonical repo with full, preserved archive. This option provides the zero maintenance mode. --- fdroidserver/server.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index ac9cba03..ce210f84 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -355,6 +355,10 @@ def update_servergitmirrors(servergitmirrors, repo_section): if os.path.isdir(dotgit) and _get_size(git_mirror_path) > 1000000000: logging.warning('Deleting git-mirror history, repo is too big (1 gig max)') shutil.rmtree(dotgit) + if options.no_keep_git_mirror_archive and _get_size(git_mirror_path) > 1000000000: + logging.warning('Deleting archive, repo is too big (1 gig max)') + archive_path = os.path.join(git_mirror_path, 'fdroid', 'archive') + shutil.rmtree(archive_path, ignore_errors=True) # rsync is very particular about trailing slashes common.local_rsync(options, @@ -626,6 +630,8 @@ def main(): help=_("Specify a local folder to sync the repo to")) parser.add_argument("--no-checksum", action="store_true", default=False, help=_("Don't use rsync checksums")) + parser.add_argument("--no-keep-git-mirror-archive", action="store_true", default=False, + help=_("If a git mirror gets to big, allow the archive to be deleted")) options = parser.parse_args() config = common.read_config(options) From 5a2534b60418ba6d19a09eefdc25ee5a1765f11c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 1 May 2019 13:49:56 +0200 Subject: [PATCH 0043/2775] nightly: archive older versions; remove archive if git mirror is full --- fdroidserver/nightly.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 9579ae50..d3a11db1 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -102,6 +102,8 @@ def main(): help=_('The file to be included in the repo (path or glob)')) parser.add_argument("--no-checksum", action="store_true", default=False, help=_("Don't use rsync checksums")) + parser.add_argument("--archive-older", default=20, + help=_("Set maximum releases in repo before older ones are archived")) # TODO add --with-btlog options = parser.parse_args() @@ -233,6 +235,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, config += "archive_name = '%s'\n" % (repo_git_base + ' archive') config += "archive_url = '%s'\n" % (repo_base + '/archive') config += "archive_icon = 'icon.png'\n" + config += "archive_older = %i\n" % options.archive_older config += "servergitmirrors = '%s'\n" % servergitmirror config += "keystore = '%s'\n" % KEYSTORE_FILE config += "repo_keyalias = '%s'\n" % KEY_ALIAS @@ -293,7 +296,8 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, if not options.no_deploy: try: - subprocess.check_call(['fdroid', 'server', 'update', '--verbose'], cwd=repo_basedir) + cmd = ['fdroid', 'server', 'update', '--verbose', '--no-keep-git-mirror-archive'] + subprocess.check_call(cmd, cwd=repo_basedir) except subprocess.CalledProcessError: logging.error(_('cannot publish update, did you set the deploy key?') + '\n' + deploy_key_url) From a84b515430758f4aa9e14db19f26bbba12ac664a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 17 Apr 2019 21:49:58 +0200 Subject: [PATCH 0044/2775] add weblate config for wlc CLI tool Set API key by sticking this in a file called ~/.config/weblate: [weblate] url = https://hosted.weblate.org/api/ translation = weblate/master [keys] https://hosted.weblate.org/api/ = ... --- .weblate | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .weblate diff --git a/.weblate b/.weblate new file mode 100644 index 00000000..cf2e653f --- /dev/null +++ b/.weblate @@ -0,0 +1,3 @@ +[weblate] +url = https://hosted.weblate.org/api/ +translation = f-droid/fdroidserver From f0460dea6ed9fe56787aa7971073f448dd1e850c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 1 May 2019 13:34:02 +0200 Subject: [PATCH 0045/2775] scanner: allow local Debian Maven repo file:///usr/share/maven-repo It is now possible to build an app using only things in Debian. Since the buildserver will always control the contents of file:///usr/share/maven-repo, it is the most safe repo there is. --- fdroidserver/scanner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 7c3dddef..866b8032 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -110,6 +110,7 @@ def scan_source(build_dir, build=metadata.Build()): 's3.amazonaws.com/repo.commonsware.com', # CommonsWare 'plugins.gradle.org/m2', # Gradle plugin repo 'maven.google.com', # Google Maven Repo, https://developer.android.com/studio/build/dependencies.html#google-maven + 'file:///usr/share/maven-repo', # local repo on Debian installs ] ] From 869c68dbdbd3fb5bd889fe8bece05258989c215f Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 1 May 2019 13:43:24 +0200 Subject: [PATCH 0046/2775] deploy: if git mirror > 1GB after deleting history, delete the archive git mirrors are meant to be an easy way to host a repo that is zero maintenance. They are not meant to be the canonical repo with full, preserved archive. This option provides the zero maintenance mode. --- fdroidserver/server.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index ca4b2d6b..964edc3b 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -355,6 +355,10 @@ def update_servergitmirrors(servergitmirrors, repo_section): if os.path.isdir(dotgit) and _get_size(git_mirror_path) > 1000000000: logging.warning('Deleting git-mirror history, repo is too big (1 gig max)') shutil.rmtree(dotgit) + if options.no_keep_git_mirror_archive and _get_size(git_mirror_path) > 1000000000: + logging.warning('Deleting archive, repo is too big (1 gig max)') + archive_path = os.path.join(git_mirror_path, 'fdroid', 'archive') + shutil.rmtree(archive_path, ignore_errors=True) # rsync is very particular about trailing slashes common.local_rsync(options, @@ -629,6 +633,8 @@ def main(): help=_("Specify a local folder to sync the repo to")) parser.add_argument("--no-checksum", action="store_true", default=False, help=_("Don't use rsync checksums")) + parser.add_argument("--no-keep-git-mirror-archive", action="store_true", default=False, + help=_("If a git mirror gets to big, allow the archive to be deleted")) options = parser.parse_args() config = common.read_config(options) From 5959a395c49f5a4f163d765944326f3d591d0b49 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 1 May 2019 13:49:56 +0200 Subject: [PATCH 0047/2775] nightly: archive older versions; remove archive if git mirror is full --- fdroidserver/nightly.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index e6f766c0..42202e71 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -102,6 +102,8 @@ def main(): help=_('The file to be included in the repo (path or glob)')) parser.add_argument("--no-checksum", action="store_true", default=False, help=_("Don't use rsync checksums")) + parser.add_argument("--archive-older", default=20, + help=_("Set maximum releases in repo before older ones are archived")) # TODO add --with-btlog options = parser.parse_args() @@ -233,6 +235,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, config += "archive_name = '%s'\n" % (repo_git_base + ' archive') config += "archive_url = '%s'\n" % (repo_base + '/archive') config += "archive_icon = 'icon.png'\n" + config += "archive_older = %i\n" % options.archive_older config += "servergitmirrors = '%s'\n" % servergitmirror config += "keystore = '%s'\n" % KEYSTORE_FILE config += "repo_keyalias = '%s'\n" % KEY_ALIAS @@ -293,7 +296,8 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, if not options.no_deploy: try: - subprocess.check_call(['fdroid', 'server', 'update', '--verbose'], cwd=repo_basedir) + cmd = ['fdroid', 'server', 'update', '--verbose', '--no-keep-git-mirror-archive'] + subprocess.check_call(cmd, cwd=repo_basedir) except subprocess.CalledProcessError: logging.error(_('cannot publish update, did you set the deploy key?') + '\n' + deploy_key_url) From 0e807264f57695049aae146dd98b142646db4c15 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 2 May 2019 08:51:39 +0200 Subject: [PATCH 0048/2775] update bash completion for new deploy/nightly flags --- completion/bash-completion | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index 531f9131..d00a767a 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -275,7 +275,7 @@ __complete_mirror() { __complete_nightly() { opts="-v -q" - lopts="--show-secret-var" + lopts="--show-secret-var --archive-older" __complete_options } @@ -288,7 +288,7 @@ __complete_stats() { __complete_deploy() { opts="-i -v -q" lopts="--identity-file --local-copy-dir --sync-from-local-copy-dir - --verbose --quiet --no-checksum" + --verbose --quiet --no-checksum --no-keep-git-mirror-archive" __complete_options } From 74a0abc530ddf732dc4dc34132230aac2dd20a2e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 2 May 2019 08:51:39 +0200 Subject: [PATCH 0049/2775] update bash completion for new deploy/nightly flags --- completion/bash-completion | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index 531f9131..d00a767a 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -275,7 +275,7 @@ __complete_mirror() { __complete_nightly() { opts="-v -q" - lopts="--show-secret-var" + lopts="--show-secret-var --archive-older" __complete_options } @@ -288,7 +288,7 @@ __complete_stats() { __complete_deploy() { opts="-i -v -q" lopts="--identity-file --local-copy-dir --sync-from-local-copy-dir - --verbose --quiet --no-checksum" + --verbose --quiet --no-checksum --no-keep-git-mirror-archive" __complete_options } From 06cec2041dfdaf38a587bed08092d398115879d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 7 May 2019 22:43:05 +0200 Subject: [PATCH 0050/2775] improve bitcoin validation regex + testcases --- fdroidserver/metadata.py | 2 +- tests/metadata.TestCase | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 2b970c8a..9f67b20e 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -453,7 +453,7 @@ valuetypes = { ["AuthorEmail"]), FieldValidator("Bitcoin address", - r'^[a-zA-Z0-9]{27,34}$', + r'^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$', ["Bitcoin"]), FieldValidator("Litecoin address", diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 486dca09..dc786095 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -39,6 +39,35 @@ class MetadataTest(unittest.TestCase): os.makedirs(self.tmpdir) os.chdir(self.basedir) + def test_FieldValidator(self): + validator = None + for vali in fdroidserver.metadata.valuetypes: + if vali.name == 'Bitcoin address': + validator = vali + break + self.assertIsNotNone(validator, "could not find 'Bitcoin address' validator") + + fdroidserver.metadata.warnings_action = 'error' + + # some valid addresses (P2PKH, P2SH, Bech32) + self.assertIsNone(validator.check('1BrrrrErsrWetrTrnrrrrm4GFg7xJaNVN2', 'fake.app.id')) + self.assertIsNone(validator.check('3JrrrrWrEZr3rNrrvrecrnyirrnqRhWNLy', 'fake.app.id')) + self.assertIsNone(validator.check('bc1qar0srrr7xrkvr5lr43lrdnwrre5rgtrzrf5rrq', 'fake.app.id')) + + # some invalid addresses (various special use/testnet addresses) + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '21BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '5Hrgr3ur5rGLrfKrrrrrrHSrqJrroGrrzrQrrrrrrLNrsrDrrrA', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'L1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id') + def test_read_metadata(self): def _build_yaml_representer(dumper, data): @@ -54,6 +83,7 @@ class MetadataTest(unittest.TestCase): config['ndk_paths'] = dict() config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config + fdroidserver.metadata.warnings_action = None apps = fdroidserver.metadata.read_metadata(xref=True) for appid in ('org.smssecure.smssecure', 'org.adaway', @@ -73,6 +103,7 @@ class MetadataTest(unittest.TestCase): def test_rewrite_yaml_fakeotaupdate(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']} + fdroidserver.metadata.warnings_action = None # rewrite metadata allapps = fdroidserver.metadata.read_metadata(xref=True) From 716f84ec5e91280422c8ca1db604cd477f323543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 24 May 2019 23:14:20 +0200 Subject: [PATCH 0051/2775] use actually working bandit version when running tests on alpine --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6c5f7ebc..35680b85 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -126,7 +126,7 @@ lint_format_safety_bandit_checks: script: - apk add --no-cache bash dash ca-certificates python3 - python3 -m ensurepip - - pip3 install Babel bandit pycodestyle pyflakes 'pylint<2.0' safety + - pip3 install Babel 'bandit<1.6.0' pycodestyle pyflakes 'pylint<2.0' safety - export EXITVALUE=0 - ./hooks/pre-commit || export EXITVALUE=1 - bandit From e895e981ad1ec1f30cd519e40b02f542acf8ca15 Mon Sep 17 00:00:00 2001 From: rubo77 Date: Mon, 27 May 2019 12:35:57 +0200 Subject: [PATCH 0052/2775] makebuildserver: show number of files to download --- makebuildserver | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/makebuildserver b/makebuildserver index e0a7ed9f..063f4461 100755 --- a/makebuildserver +++ b/makebuildserver @@ -413,13 +413,14 @@ def run_via_vagrant_ssh(v, cmdlist): def update_cache(cachedir): + count_files = 0 for srcurl, shasum in CACHE_FILES: filename = os.path.basename(srcurl) local_filename = os.path.join(cachedir, filename) - + count_files = count_files + 1 if os.path.exists(local_filename): if sha256_for_file(local_filename) == shasum: - logging.info("\t...shasum verified for %s", local_filename) + logging.info("\t...shasum verified for '{filename}'\t({filecounter} of {filesum} files)".format(filename=local_filename, filecounter=count_files, filesum=len(CACHE_FILES))) continue local_length = os.path.getsize(local_filename) else: @@ -462,7 +463,7 @@ def update_cache(cachedir): v = sha256_for_file(local_filename) if v == shasum: - logging.info("\t...shasum verified for %s", local_filename) + logging.info("\t...shasum verified for '{filename}'\t({filecounter} of {filesum} files)".format(filename=local_filename, filecounter=count_files, filesum=len(CACHE_FILES))) else: logging.critical("Invalid shasum of '%s' detected for %s", v, local_filename) os.remove(local_filename) From 66105de83308d72670ba643e0495c14185e50398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 10 May 2019 12:02:13 +0200 Subject: [PATCH 0053/2775] improve litecoin validation + tests --- fdroidserver/metadata.py | 2 +- tests/metadata.TestCase | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 9f67b20e..17a3e739 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -457,7 +457,7 @@ valuetypes = { ["Bitcoin"]), FieldValidator("Litecoin address", - r'^L[a-zA-Z0-9]{33}$', + r'^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$', ["Litecoin"]), FieldValidator("Repo Type", diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index dc786095..d7b72f71 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -39,7 +39,7 @@ class MetadataTest(unittest.TestCase): os.makedirs(self.tmpdir) os.chdir(self.basedir) - def test_FieldValidator(self): + def test_FieldValidator_BitcoinAddress(self): validator = None for vali in fdroidserver.metadata.valuetypes: if vali.name == 'Bitcoin address': @@ -54,9 +54,9 @@ class MetadataTest(unittest.TestCase): self.assertIsNone(validator.check('3JrrrrWrEZr3rNrrvrecrnyirrnqRhWNLy', 'fake.app.id')) self.assertIsNone(validator.check('bc1qar0srrr7xrkvr5lr43lrdnwrre5rgtrzrf5rrq', 'fake.app.id')) - # some invalid addresses (various special use/testnet addresses) + # some invalid addresses self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, - '21BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + '21BvMrSYsrWrtrrlL5A10mlGFr7rrarrN2', 'fake.app.id') self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, '5Hrgr3ur5rGLrfKrrrrrrHSrqJrroGrrzrQrrrrrrLNrsrDrrrA', 'fake.app.id') self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, @@ -68,6 +68,35 @@ class MetadataTest(unittest.TestCase): self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, 'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id') + def test_FieldValidator_LitecoinAddress(self): + validator = None + for vali in fdroidserver.metadata.valuetypes: + if vali.name == 'Litecoin address': + validator = vali + break + self.assertIsNotNone(validator, "could not find 'Litecoin address' validator") + + fdroidserver.metadata.warnings_action = 'error' + + # some valid addresses (L, M, 3) + self.assertIsNone(validator.check('LgeGrrrrJAxyXprrPrrBrrX5Qrrrrrrrrd', 'fake.app.id')) + self.assertIsNone(validator.check('MrrrrrrrJAxyXpanPtrrRAX5QHxvUJo8id', 'fake.app.id')) + self.assertIsNone(validator.check('3rereVr9rAryrranrrrrrAXrrHx', 'fake.app.id')) + + # some invalid addresses (various special use/testnet addresses, invalid chars) + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '21BvMrSYsrWrtrrrn5Au4l4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '5Hrgr3ur5rGLrfKrrrrrr1SrqJrroGrrzrQrrrrrrLNrsrDrrrA', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'L0000rSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id') + def test_read_metadata(self): def _build_yaml_representer(dumper, data): From 06bbd3044bae7104039c6b6911c24c8f60b28c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 28 May 2019 12:07:36 +0200 Subject: [PATCH 0054/2775] makebuildserver: explicit timeout for cache downloading --- makebuildserver | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makebuildserver b/makebuildserver index 063f4461..ed037da8 100755 --- a/makebuildserver +++ b/makebuildserver @@ -452,8 +452,8 @@ def update_cache(cachedir): logging.info("Downloading %s to cache", filename) if download: - r = requests.get(srcurl, headers=resume_header, - stream=True, allow_redirects=True) + r = requests.get(srcurl, headers=resume_header, stream=True, + allow_redirects=True, timeout=60) content_length = int(r.headers.get('content-length')) with open(local_filename, 'ab') as f: for chunk in progress.bar(r.iter_content(chunk_size=65536), From 781b55f777bc016c71e6e1fc79929867c4ac8faa Mon Sep 17 00:00:00 2001 From: relan Date: Thu, 13 Jun 2019 19:51:29 +0300 Subject: [PATCH 0055/2775] checkupdates: match whole words Match only whole words when looking for versionCode, versionName, etc. in manifests. A real build.gradle example: flutterVersionCode = '1' flutterVersionName = '1.0' ... defaultConfig { versionCode 53 versionName "2.0.3" } Before this change checkupdates was erroneously getting version code and version name from the first two lines and failing to find a new release. --- fdroidserver/common.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 535a3f2a..61751d0c 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1348,11 +1348,11 @@ def remove_debuggable_flags(root_dir): os.path.join(root, 'AndroidManifest.xml')) -vcsearch_g = re.compile(r'''.*[Vv]ersionCode\s*=?\s*["']*([0-9]+)["']*''').search -vnsearch_g = re.compile(r'''.*[Vv]ersionName\s*=?\s*(["'])((?:(?=(\\?))\3.)*?)\1.*''').search -vnssearch_g = re.compile(r'''.*[Vv]ersionNameSuffix\s*=?\s*(["'])((?:(?=(\\?))\3.)*?)\1.*''').search -psearch_g = re.compile(r'''.*(packageName|applicationId)\s*=*\s*["']([^"']+)["'].*''').search -fsearch_g = re.compile(r'''.*(applicationIdSuffix)\s*=*\s*["']([^"']+)["'].*''').search +vcsearch_g = re.compile(r'''\b[Vv]ersionCode\s*=?\s*["']*([0-9]+)["']*''').search +vnsearch_g = re.compile(r'''\b[Vv]ersionName\s*=?\s*(["'])((?:(?=(\\?))\3.)*?)\1''').search +vnssearch_g = re.compile(r'''\b[Vv]ersionNameSuffix\s*=?\s*(["'])((?:(?=(\\?))\3.)*?)\1''').search +psearch_g = re.compile(r'''\b(packageName|applicationId)\s*=*\s*["']([^"']+)["']''').search +fsearch_g = re.compile(r'''\b(applicationIdSuffix)\s*=*\s*["']([^"']+)["']''').search def app_matches_packagename(app, package): From 7381a94b476c01edd7b3fb4f55639f1bc7e04c6b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 30 Jun 2019 22:48:52 +0200 Subject: [PATCH 0056/2775] gitlab-ci: disable bandit fail on standard debug keystore password --- fdroidserver/nightly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 42202e71..6f09aa4d 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -39,7 +39,7 @@ from . import common # hard coded defaults for Android ~/.android/debug.keystore files # https://developers.google.com/android/guides/client-auth KEYSTORE_FILE = os.path.join(os.getenv('HOME'), '.android', 'debug.keystore') -PASSWORD = 'android' +PASSWORD = 'android' # nosec B105 standard hardcoded password for debug keystores KEY_ALIAS = 'androiddebugkey' DISTINGUISHED_NAME = 'CN=Android Debug,O=Android,C=US' From 2e59220644bc25e8c73543f8ee728f327809294b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 30 Jun 2019 22:48:52 +0200 Subject: [PATCH 0057/2775] gitlab-ci: disable bandit fail on standard debug keystore password --- fdroidserver/nightly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index d3a11db1..7a90294d 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -39,7 +39,7 @@ from . import common # hard coded defaults for Android ~/.android/debug.keystore files # https://developers.google.com/android/guides/client-auth KEYSTORE_FILE = os.path.join(os.getenv('HOME'), '.android', 'debug.keystore') -PASSWORD = 'android' +PASSWORD = 'android' # nosec B105 standard hardcoded password for debug keystores KEY_ALIAS = 'androiddebugkey' DISTINGUISHED_NAME = 'CN=Android Debug,O=Android,C=US' From e2351f6c531e4ea00c5b0bd12528e8da357fb711 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 11:22:32 +0200 Subject: [PATCH 0058/2775] gitlab-ci: move pip job to Xenial, Trusty is over --- .gitlab-ci.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 35680b85..1669e016 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -78,9 +78,9 @@ ubuntu_lts: - cd tests - ./run-tests -# test using TrustyLTS with all depends from pypi -ubuntu_trusty_pip: - image: ubuntu:trusty +# test using Xenial LTS with all depends from pypi +ubuntu_xenial_pip: + image: ubuntu:xenial only: - master@fdroid/fdroidserver variables: @@ -90,11 +90,10 @@ ubuntu_trusty_pip: - echo Etc/UTC > /etc/timezone - apt-get -qy update - apt-get -qy dist-upgrade - - apt-get -qy install git default-jdk python3-pip python3.4-venv + - apt-get -qy install --no-install-recommends git default-jdk-headless python3-pip python3-venv rsync zipalign - rm -rf env - - pyvenv-3.4 env + - pyvenv env - . env/bin/activate - - echo sed -i "s/'requests.*',$/'requests',/" setup.py - pip3 install --upgrade babel pip setuptools - pip3 install -e . - ./setup.py compile_catalog From a9b8687e9483822ab4ff56d61e0cde03830dda37 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 11:34:59 +0200 Subject: [PATCH 0059/2775] gitlab-ci: the ubuntu_lts test also tests the PPA --- .gitlab-ci.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1669e016..cbc87721 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -57,12 +57,14 @@ debian_testing: - ./run-tests # test using LTS set up with the PPA, including Recommends -ubuntu_lts: +ubuntu_lts_ppa: image: ubuntu:latest only: - master@fdroid/fdroidserver variables: + ANDROID_HOME: /usr/lib/android-sdk DEBIAN_FRONTEND: noninteractive + LANG: C.UTF-8 script: - echo Etc/UTC > /etc/timezone - apt-get -qy update @@ -72,13 +74,13 @@ ubuntu_lts: - echo "deb http://ppa.launchpad.net/fdroid/fdroidserver/ubuntu $RELEASE main" >> /etc/apt/sources.list - apt-get -qy update - apt-get -qy dist-upgrade - - apt-get -qy install --install-recommends fdroidserver git python3-defusedxml python3-setuptools - - export ANDROID_HOME=/usr/lib/android-sdk - - export LANG=C.UTF-8 + - apt-get -qy install --install-recommends binfmt-support fdroidserver git python3-defusedxml python3-setuptools + - grep binfmt /proc/modules || apt -qy purge apksigner - cd tests - ./run-tests # test using Xenial LTS with all depends from pypi +# apksigner is recommended, but requires binfmt support in the kernel ubuntu_xenial_pip: image: ubuntu:xenial only: From 57b9d1e3163a289e9a9364bb7b986b9bf8fc57ac Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 11:43:18 +0200 Subject: [PATCH 0060/2775] tests: handle when apksigner considers MD5 signatures valid --- tests/common.TestCase | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/common.TestCase b/tests/common.TestCase index 9b03f4cd..1ac6d5e1 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -340,10 +340,16 @@ class CommonTest(unittest.TestCase): fdroidserver.common.config = config self.assertTrue(fdroidserver.common.verify_apk_signature('bad-unicode-πÇÇ现代通用字-български-عربي1.apk')) - self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_1.apk')) - self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_2.apk')) - self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_3.apk')) - self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_4.apk')) + if 'apksigner' in fdroidserver.common.config: # apksigner considers MD5 signatures valid + self.assertTrue(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_1.apk')) + self.assertTrue(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_2.apk')) + self.assertTrue(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_3.apk')) + self.assertTrue(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_4.apk')) + else: + self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_1.apk')) + self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_2.apk')) + self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_3.apk')) + self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_4.apk')) self.assertTrue(fdroidserver.common.verify_apk_signature('org.dyndns.fules.ck_20.apk')) self.assertTrue(fdroidserver.common.verify_apk_signature('urzip.apk')) self.assertFalse(fdroidserver.common.verify_apk_signature('urzip-badcert.apk')) From a0f5ee661ed68b78c5a43418592ba445b9375aae Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 22:07:15 +0200 Subject: [PATCH 0061/2775] tests: common.test_sign_apk requires aapt to run --- tests/common.TestCase | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/common.TestCase b/tests/common.TestCase index 1ac6d5e1..8930ed65 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -569,6 +569,7 @@ class CommonTest(unittest.TestCase): def test_sign_apk(self): try: + fdroidserver.common.find_sdk_tools_cmd('aapt') fdroidserver.common.find_sdk_tools_cmd('zipalign') except fdroidserver.exception.FDroidException: print('\n\nSKIPPING test_sign_apk, zipalign is not installed!\n') From 4881e6818b6561eaf763140714543268d9a19af0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 10:15:49 +0200 Subject: [PATCH 0062/2775] travis: purge "linux" test now that the runner was upgraded to Xenial Xenial test runs are already well covered by GitLab-CI. --- .travis.yml | 103 +++++++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 66 deletions(-) diff --git a/.travis.yml b/.travis.yml index ae838b54..3c93f2ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,6 @@ language: java matrix: include: - - os: linux - language: android - os: osx osx_image: xcode10.2 env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk @@ -23,20 +21,6 @@ matrix: env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk env: ANDROID_HOME=/usr/local/share/android-sdk -# On Ubuntu/trusty 14.04, the PPA is needed on to provide lots of the -# dependencies, but this then also serves as a test of the PPA, which -# is used on Windows Subsystem for Linux. -addons: - apt: - update: true - sources: - - sourceline: 'ppa:fdroid/fdroidserver' - packages: - - python3-babel - - python3-defusedxml - - python3-setuptools - - fdroidserver - android: components: - android-23 # required for `fdroid build` test @@ -50,62 +34,49 @@ android: # https://blogs.oracle.com/java-platform-group/oracle-jre-will-no-longer-trust-md5-signed-code-by-default # https://opsech.io/posts/2017/Jun/09/openjdk-april-2017-security-update-131-8u131-and-md5-signed-jars.html install: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - echo "Skipping Uyghur locale, this has too old a gettext to support it"; - rm -rf locale/ug; - fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - set -x; - brew update > /dev/null; - if [ "`sw_vers -productVersion | sed 's,10\.\([0-9]*\).*,\1,'`" -gt 10 ]; then + - brew update > /dev/null + - if [ "`sw_vers -productVersion | sed 's,10\.\([0-9]*\).*,\1,'`" -gt 10 ]; then brew upgrade python; - else + else brew install python3; - fi; - brew install dash bash gnu-sed gradle jenv; - export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"; - if ! ruby -e 'v = `javac -version 2>&1`.split()[1].gsub("_", "."); exit Gem::Dependency.new("", "~> 1.8.0.131").match?("", v)'; then - brew cask uninstall java --force; - brew cask install caskroom/versions/java8; - fi; - brew cask install android-sdk; - - export AAPT_VERSION=`sed -n "s,^MINIMUM_AAPT_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py`; - mkdir -p "$ANDROID_HOME/licenses"; - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"; - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> "$ANDROID_HOME/licenses/android-sdk-license"; - echo -e "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" >> "$ANDROID_HOME/licenses/android-sdk-license"; - echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"; - echo y | $ANDROID_HOME/tools/bin/sdkmanager "platform-tools"; - echo y | $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$AAPT_VERSION"; - echo y | $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-23"; - - sudo pip3 install babel; - sudo pip3 install --quiet --editable . ; - sudo rm -rf fdroidserver.egg-info; - - ls -l /System/Library/Java/JavaVirtualMachines || true; - ls -l /Library/Java/JavaVirtualMachines || true; - echo $PATH; - echo $JAVA_HOME; - jenv versions; - /usr/libexec/java_home; - java -version; - which java; - javac -version; - which javac; - jarsigner -help; - which jarsigner; - keytool -help; - which keytool; - set +x; fi + - brew install dash bash gnu-sed gradle jenv + - export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" + - brew cask uninstall java --force + - brew cask install caskroom/versions/java8 + - brew cask install android-sdk + + - export AAPT_VERSION=`sed -n "s,^MINIMUM_AAPT_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py` + - mkdir -p "$ANDROID_HOME/licenses" + - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license" + - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> "$ANDROID_HOME/licenses/android-sdk-license" + - echo -e "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" >> "$ANDROID_HOME/licenses/android-sdk-license" + - echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license" + - echo y | $ANDROID_HOME/tools/bin/sdkmanager "platform-tools" + - echo y | $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$AAPT_VERSION" + - echo y | $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-23" + + - sudo pip3 install babel + - sudo pip3 install --quiet --editable . + - sudo rm -rf fdroidserver.egg-info + + - ls -l /System/Library/Java/JavaVirtualMachines || true + - ls -l /Library/Java/JavaVirtualMachines || true + - echo $PATH + - echo $JAVA_HOME + - jenv versions + - /usr/libexec/java_home + - java -version + - which java + - javac -version + - which javac + - jarsigner -help + - which jarsigner + - keytool -help + - which keytool # The OSX tests seem to run slower, they often timeout. So only run # the test suite with the installed version of fdroid. -# -# Supporting pip on Ubuntu/trusty was too painful here, since it seems -# that pip installs conflict with the Ubuntu packages. script: - ./tests/run-tests From 59920b9ab6eb9097f3f587010efa8342d1dd61c7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 22:43:06 +0200 Subject: [PATCH 0063/2775] travis: upgrade Java to newest release if old enough to still use MD5 The Android SDK still requires Java8, so just force it on all macOS versions. --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3c93f2ba..4313d6d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,7 @@ android: # https://blogs.oracle.com/java-platform-group/oracle-jre-will-no-longer-trust-md5-signed-code-by-default # https://opsech.io/posts/2017/Jun/09/openjdk-april-2017-security-update-131-8u131-and-md5-signed-jars.html install: + - export HOMEBREW_CURL_RETRIES=10 - brew update > /dev/null - if [ "`sw_vers -productVersion | sed 's,10\.\([0-9]*\).*,\1,'`" -gt 10 ]; then brew upgrade python; @@ -42,8 +43,10 @@ install: fi - brew install dash bash gnu-sed gradle jenv - export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" - - brew cask uninstall java --force - - brew cask install caskroom/versions/java8 + - brew uninstall java --force || true + - brew cask uninstall java --force || true + - brew tap adoptopenjdk/openjdk + - brew cask install adoptopenjdk8 - brew cask install android-sdk - export AAPT_VERSION=`sed -n "s,^MINIMUM_AAPT_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py` @@ -62,6 +65,7 @@ install: - ls -l /System/Library/Java/JavaVirtualMachines || true - ls -l /Library/Java/JavaVirtualMachines || true + - for f in /Library/Java/JavaVirtualMachines/*.jdk; do jenv add $f; done - echo $PATH - echo $JAVA_HOME - jenv versions @@ -74,6 +78,7 @@ install: - which jarsigner - keytool -help - which keytool + - sudo rm -rf /Library/Java/JavaVirtualMachines/jdk1.8.0_1*.jdk || true # The OSX tests seem to run slower, they often timeout. So only run # the test suite with the installed version of fdroid. From 13dbf995d5d9fc554b1b2967f90d09a4dbbde9b0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 11:06:16 +0200 Subject: [PATCH 0064/2775] travis: uninstall mercurial since it requires Python2 and is unused --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4313d6d6..7e8d26f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,10 +33,14 @@ android: # * Java needs to be at least 1.8.0_131 to have MD5 properly disabled # https://blogs.oracle.com/java-platform-group/oracle-jre-will-no-longer-trust-md5-signed-code-by-default # https://opsech.io/posts/2017/Jun/09/openjdk-april-2017-security-update-131-8u131-and-md5-signed-jars.html +# * mercurial is unused and requires Python 2.x install: - export HOMEBREW_CURL_RETRIES=10 - brew update > /dev/null - - if [ "`sw_vers -productVersion | sed 's,10\.\([0-9]*\).*,\1,'`" -gt 10 ]; then + - if [ "`sw_vers -productVersion | sed 's,10\.\([0-9]*\).*,\1,'`" -ge 14 ]; then + python3 --version; + elif [ "`sw_vers -productVersion | sed 's,10\.\([0-9]*\).*,\1,'`" -gt 10 ]; then + brew uninstall mercurial --force; brew upgrade python; else brew install python3; From 828ba8aad90ae6cfa7f20cc2018a3c3c2d3f8828 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 2 Jul 2019 21:15:15 +0200 Subject: [PATCH 0065/2775] travis: use travis_retry to retry failed sdkmanager/pip3 downloads --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7e8d26f7..3d7cd9cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,12 +59,12 @@ install: - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> "$ANDROID_HOME/licenses/android-sdk-license" - echo -e "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" >> "$ANDROID_HOME/licenses/android-sdk-license" - echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license" - - echo y | $ANDROID_HOME/tools/bin/sdkmanager "platform-tools" - - echo y | $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$AAPT_VERSION" - - echo y | $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-23" + - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "platform-tools" + - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$AAPT_VERSION" + - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-23" - - sudo pip3 install babel - - sudo pip3 install --quiet --editable . + - travis_retry sudo pip3 install babel + - travis_retry sudo pip3 install --quiet --editable . - sudo rm -rf fdroidserver.egg-info - ls -l /System/Library/Java/JavaVirtualMachines || true From ab8a623c90fd130dceab7f492a7d9c56b53fb42c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 2 Jul 2019 21:15:15 +0200 Subject: [PATCH 0066/2775] travis: tame unneeded messages in log to prevent job terminiation This is to avoid random job fails from: "The job exceeded the maximum log length, and has been terminated." --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d7cd9cf..782f72f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,12 +59,12 @@ install: - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> "$ANDROID_HOME/licenses/android-sdk-license" - echo -e "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" >> "$ANDROID_HOME/licenses/android-sdk-license" - echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license" - - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "platform-tools" - - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$AAPT_VERSION" - - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-23" + - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "platform-tools" > /dev/null + - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$AAPT_VERSION" > /dev/null + - echo y | travis_retry $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-23" > /dev/null - - travis_retry sudo pip3 install babel - - travis_retry sudo pip3 install --quiet --editable . + - travis_retry sudo pip3 install --progress-bar off babel + - travis_retry sudo pip3 install --quiet --progress-bar off --editable . - sudo rm -rf fdroidserver.egg-info - ls -l /System/Library/Java/JavaVirtualMachines || true From 2f198c24b951fe0443a47963b1cf0c3587f2ac27 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 09:06:29 +0200 Subject: [PATCH 0067/2775] travis: purge xcode9.2 runner, it has flaky networking --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 782f72f5..c9cb33eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,6 @@ matrix: osx_image: xcode9.3 env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk env: ANDROID_HOME=/usr/local/share/android-sdk - - os: osx - osx_image: xcode9.2 - env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk - env: ANDROID_HOME=/usr/local/share/android-sdk - os: osx osx_image: xcode8.3 env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk From b9475374a89567567d9159a062fafd235b899f1c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 11:29:38 +0200 Subject: [PATCH 0068/2775] update test badges in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0eeab45d..1b0a1c02 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ | CI Builds | fdroidserver | buildserver | fdroid build --all | publishing tools | |--------------------------|:-------------:|:-----------:|:------------------:|:----------------:| -| Debian | [![fdroidserver status on Debian](https://gitlab.com/fdroid/fdroidserver/badges/master/build.svg)](https://gitlab.com/fdroid/fdroidserver/builds) | [![buildserver status](https://jenkins.debian.net/job/reproducible_setup_fdroid_build_environment/badge/icon)](https://jenkins.debian.net/job/reproducible_setup_fdroid_build_environment) | [![fdroid build all status](https://jenkins.debian.net/job/reproducible_fdroid_build_apps/badge/icon)](https://jenkins.debian.net/job/reproducible_fdroid_build_apps/) | [![fdroid test status](https://jenkins.debian.net/job/reproducible_fdroid_test/badge/icon)](https://jenkins.debian.net/job/reproducible_fdroid_test/) | -| macOS & Ubuntu/trusty | [![fdroidserver status on macOS & Ubuntu/LTS](https://travis-ci.org/fdroidtravis/fdroidserver.svg?branch=master)](https://travis-ci.org/fdroidtravis/fdroidserver) | | | | +| GNU/Linux | [![fdroidserver status on GNU/Linux](https://gitlab.com/fdroid/fdroidserver/badges/master/build.svg)](https://gitlab.com/fdroid/fdroidserver/builds) | [![buildserver status](https://jenkins.debian.net/job/reproducible_setup_fdroid_build_environment/badge/icon)](https://jenkins.debian.net/job/reproducible_setup_fdroid_build_environment) | [![fdroid build all status](https://jenkins.debian.net/job/reproducible_fdroid_build_apps/badge/icon)](https://jenkins.debian.net/job/reproducible_fdroid_build_apps/) | [![fdroid test status](https://jenkins.debian.net/job/reproducible_fdroid_test/badge/icon)](https://jenkins.debian.net/job/reproducible_fdroid_test/) | +| macOS | [![fdroidserver status on macOS](https://travis-ci.org/fdroidtravis/fdroidserver.svg?branch=master)](https://travis-ci.org/fdroidtravis/fdroidserver) | | | | # F-Droid Server From b484e9ecfd50ccf39822c63cbb25c287ed6d7dbd Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 11:43:18 +0200 Subject: [PATCH 0069/2775] tests: handle when apksigner considers MD5 signatures valid --- tests/common.TestCase | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/common.TestCase b/tests/common.TestCase index b976376f..0bfb166b 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -340,10 +340,16 @@ class CommonTest(unittest.TestCase): fdroidserver.common.config = config self.assertTrue(fdroidserver.common.verify_apk_signature('bad-unicode-πÇÇ现代通用字-български-عربي1.apk')) - self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_1.apk')) - self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_2.apk')) - self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_3.apk')) - self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_4.apk')) + if 'apksigner' in fdroidserver.common.config: # apksigner considers MD5 signatures valid + self.assertTrue(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_1.apk')) + self.assertTrue(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_2.apk')) + self.assertTrue(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_3.apk')) + self.assertTrue(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_4.apk')) + else: + self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_1.apk')) + self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_2.apk')) + self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_3.apk')) + self.assertFalse(fdroidserver.common.verify_apk_signature('org.bitbucket.tickytacky.mirrormirror_4.apk')) self.assertTrue(fdroidserver.common.verify_apk_signature('org.dyndns.fules.ck_20.apk')) self.assertTrue(fdroidserver.common.verify_apk_signature('urzip.apk')) self.assertFalse(fdroidserver.common.verify_apk_signature('urzip-badcert.apk')) From 9e32e2d770ad6993104ac5da09f06a0d093d8dea Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 1 Jul 2019 22:07:15 +0200 Subject: [PATCH 0070/2775] tests: common.test_sign_apk requires aapt to run --- tests/common.TestCase | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/common.TestCase b/tests/common.TestCase index 0bfb166b..5defdac5 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -569,6 +569,7 @@ class CommonTest(unittest.TestCase): def test_sign_apk(self): try: + fdroidserver.common.find_sdk_tools_cmd('aapt') fdroidserver.common.find_sdk_tools_cmd('zipalign') except fdroidserver.exception.FDroidException: print('\n\nSKIPPING test_sign_apk, zipalign is not installed!\n') From 1fdeb4691ceb8385bfb4fe204b5088cd410fdde8 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 18:54:52 +0200 Subject: [PATCH 0071/2775] include all relevant files in source tarball (MANIFEST.in) --- MANIFEST.in | 550 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 548 insertions(+), 2 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index ba173c91..8be4dabf 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,9 +4,9 @@ include buildserver/provision-android-sdk include buildserver/provision-apt-get-install include buildserver/provision-apt-proxy include buildserver/provision-gradle -include buildserver/provision-pip include buildserver/setup-env-vars include buildserver/Vagrantfile +include CHANGELOG.md include completion/bash-completion include docker/Dockerfile include docker/drozer.py @@ -41,15 +41,513 @@ include locale/uk/LC_MESSAGES/fdroidserver.mo include locale/zh_Hans/LC_MESSAGES/fdroidserver.mo include locale/zh_Hant/LC_MESSAGES/fdroidserver.mo include makebuildserver -include README.rst +include README.md include tests/androguard_test.py include tests/bad-unicode-*.apk include tests/build.TestCase +include tests/build-tools/17.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/17.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/17.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/17.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/17.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/17.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/17.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/17.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/17.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/17.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/17.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/17.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/17.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/17.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/17.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/18.1.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/18.1.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/18.1.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/18.1.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/18.1.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/18.1.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/18.1.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/18.1.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/18.1.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/18.1.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/18.1.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/18.1.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/18.1.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/18.1.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/18.1.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/19.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/19.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/19.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/19.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/19.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/19.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/19.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/19.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/19.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/19.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/19.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/19.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/19.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/19.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/19.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/19.1.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/19.1.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/19.1.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/19.1.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/19.1.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/19.1.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/19.1.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/19.1.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/19.1.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/19.1.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/19.1.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/19.1.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/19.1.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/19.1.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/19.1.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/20.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/20.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/20.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/20.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/20.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/20.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/20.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/20.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/20.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/20.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/20.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/20.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/20.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/20.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/20.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/21.1.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/21.1.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/21.1.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/21.1.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/21.1.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/21.1.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/21.1.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/21.1.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/21.1.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/21.1.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/21.1.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/21.1.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/21.1.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/21.1.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/21.1.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/21.1.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/21.1.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/21.1.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/21.1.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/21.1.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/21.1.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/21.1.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/21.1.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/21.1.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/21.1.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/21.1.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/21.1.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/21.1.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/21.1.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/21.1.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/22.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/22.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/22.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/22.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/22.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/22.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/22.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/22.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/22.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/22.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/22.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/22.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/22.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/22.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/22.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/22.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/22.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/22.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/22.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/22.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/22.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/22.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/22.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/22.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/22.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/22.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/22.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/22.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/22.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/22.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/23.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/23.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/23.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/23.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/23.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/23.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/23.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/23.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/23.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/23.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/23.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/23.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/23.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/23.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/23.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/23.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/23.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/23.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/23.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/23.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/23.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/23.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/23.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/23.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/23.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/23.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/23.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/23.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/23.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/23.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/23.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/23.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/23.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/23.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/23.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/23.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/23.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/23.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/23.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/23.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/23.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/23.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/23.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/23.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/23.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/23.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/23.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/23.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/23.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/23.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/23.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/23.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/23.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/23.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/23.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/23.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/23.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/23.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/23.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/23.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/24.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/24.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/24.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/24.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/24.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/24.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/24.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/24.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/24.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/24.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/24.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/24.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/24.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/24.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/24.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/24.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/24.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/24.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/24.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/24.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/24.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/24.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/24.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/24.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/24.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/24.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/24.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/24.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/24.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/24.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/24.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/24.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/24.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/24.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/24.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/24.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/24.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/24.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/24.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/24.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/24.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/24.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/24.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/24.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/24.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/24.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/24.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/24.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/24.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/24.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/24.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/24.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/24.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/24.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/24.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/24.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/24.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/24.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/24.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/24.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/25.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/25.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/25.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/25.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/25.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/25.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/25.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/25.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/25.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/25.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/25.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/25.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/25.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/25.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/25.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/25.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/25.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/25.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/25.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/25.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/25.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/25.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/25.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/25.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/25.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/25.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/25.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/25.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/25.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/25.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/25.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/25.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/25.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/25.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/25.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/25.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/25.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/25.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/25.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/25.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/25.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/25.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/25.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/25.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/25.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/25.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/25.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/25.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/25.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/25.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/25.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/25.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/25.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/25.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/25.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/25.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/25.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/25.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/25.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/25.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/26.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/26.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/26.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/26.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/26.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/26.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/26.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/26.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/26.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/26.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/26.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/26.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/26.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/26.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/26.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/26.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/26.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/26.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/26.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/26.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/26.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/26.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/26.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/26.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/26.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/26.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/26.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/26.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/26.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/26.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/26.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/26.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/26.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/26.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/26.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/26.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/26.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/26.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/26.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/26.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/26.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/26.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/26.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/26.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/26.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/26.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/26.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/26.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/26.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/26.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/26.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/26.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/26.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/26.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/26.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/26.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/26.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/26.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/26.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/26.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/27.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/27.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/27.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/27.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/27.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/27.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/27.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/27.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/27.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/27.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/27.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/27.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/27.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/27.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/27.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/27.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/27.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/27.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/27.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/27.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/27.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/27.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/27.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/27.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/27.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/27.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/27.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/27.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/27.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/27.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/27.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/27.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/27.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/27.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/27.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/27.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/27.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/27.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/27.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/27.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/27.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/27.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/27.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/27.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/27.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/27.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/27.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/27.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/27.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/27.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/27.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/27.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/27.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/27.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/27.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/27.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/27.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/27.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/27.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/27.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/28.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/28.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/28.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/28.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/28.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/28.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/28.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/28.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/28.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/28.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/28.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/28.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/28.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/28.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/28.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/28.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/28.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/28.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/28.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/28.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/28.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/28.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/28.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/28.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/28.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/28.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/28.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/28.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/28.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/28.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/28.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/28.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/28.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/28.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/28.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/28.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/28.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/28.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/28.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/28.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/28.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/28.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/28.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/28.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/28.0.3/aapt-output-com.example.test.helloworld_1.txt +include tests/build-tools/28.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/28.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/28.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/28.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/28.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/28.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/28.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/28.0.3/aapt-output-no.min.target.sdk_987.txt +include tests/build-tools/28.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/28.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/28.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/28.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/28.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/28.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/generate.sh +include tests/check-fdroid-apk include tests/common.TestCase include tests/complete-ci-tests include tests/config.py include tests/description-parsing.py +include tests/dummy-keystore.jks include tests/dump_internal_metadata_format.py +include tests/exception.TestCase include tests/extra/convert_metadata_to_yaml_then_txt.sh include tests/extra/manual-vmtools-test.py include tests/getsig/getsig.java @@ -63,6 +561,8 @@ include tests/import_proxy.py include tests/import.TestCase include tests/index.TestCase include tests/install.TestCase +include tests/IsMD5Disabled.java +include tests/janus.apk include tests/keystore.jks include tests/lint.TestCase include tests/metadata/apk/info.guardianproject.urzip.yaml @@ -73,6 +573,7 @@ include tests/metadata/dump/com.politedroid.yaml include tests/metadata/dump/org.adaway.yaml include tests/metadata/dump/org.smssecure.smssecure.yaml include tests/metadata/dump/org.videolan.vlc.yaml +include tests/metadata/duplicate.permisssions.yml include tests/metadata/fake.ota.update.txt include tests/metadata/info.guardianproject.checkey/en-US/description.txt include tests/metadata/info.guardianproject.checkey/en-US/phoneScreenshots/checkey-phone.png @@ -87,18 +588,27 @@ include tests/metadata/info.guardianproject.urzip/en-US/short_description.txt include tests/metadata/info.guardianproject.urzip/en-US/title.txt include tests/metadata/info.guardianproject.urzip/en-US/video.txt include tests/metadata/info.guardianproject.urzip.yml +include tests/metadata/info.zwanenburg.caffeinetile.yml +include tests/metadata/no.min.target.sdk.yml include tests/metadata/obb.main.oldversion.txt include tests/metadata/obb.mainpatch.current.txt include tests/metadata/obb.main.twoversions.txt include tests/metadata/org.adaway.json include tests/metadata/org.fdroid.ci.test.app.txt include tests/metadata/org.fdroid.fdroid.txt +include tests/metadata/org.smssecure.smssecure/signatures/134/28969C09.RSA +include tests/metadata/org.smssecure.smssecure/signatures/134/28969C09.SF +include tests/metadata/org.smssecure.smssecure/signatures/134/MANIFEST.MF +include tests/metadata/org.smssecure.smssecure/signatures/135/28969C09.RSA +include tests/metadata/org.smssecure.smssecure/signatures/135/28969C09.SF +include tests/metadata/org.smssecure.smssecure/signatures/135/MANIFEST.MF include tests/metadata/org.smssecure.smssecure.txt include tests/metadata/org.videolan.vlc.yml include tests/metadata/raw.template.txt include tests/metadata-rewrite-yml/app.with.special.build.params.yml include tests/metadata-rewrite-yml/fake.ota.update.yml include tests/metadata-rewrite-yml/org.fdroid.fdroid.yml +include tests/metadata/souch.smsbypass.txt include tests/metadata.TestCase include tests/openssl-version-check-test.py include tests/org.bitbucket.tickytacky.mirrormirror_1.apk @@ -106,17 +616,23 @@ include tests/org.bitbucket.tickytacky.mirrormirror_2.apk include tests/org.bitbucket.tickytacky.mirrormirror_3.apk include tests/org.bitbucket.tickytacky.mirrormirror_4.apk include tests/org.dyndns.fules.ck_20.apk +include tests/publish.TestCase include tests/repo/categories.txt +include tests/repo/com.example.test.helloworld_1.apk include tests/repo/com.politedroid_3.apk include tests/repo/com.politedroid_4.apk include tests/repo/com.politedroid_5.apk include tests/repo/com.politedroid_6.apk +include tests/repo/duplicate.permisssions_9999999.apk include tests/repo/fake.ota.update_1234.zip +include tests/repo/index-v1.json include tests/repo/index.xml +include tests/repo/info.zwanenburg.caffeinetile_4.apk include tests/repo/main.1101613.obb.main.twoversions.obb include tests/repo/main.1101615.obb.main.twoversions.obb include tests/repo/main.1434483388.obb.main.oldversion.obb include tests/repo/main.1619.obb.mainpatch.current.obb +include tests/repo/no.min.target.sdk_987.apk include tests/repo/obb.main.oldversion_1444412523.apk include tests/repo/obb.mainpatch.current_1619_another-release-key.apk include tests/repo/obb.mainpatch.current_1619.apk @@ -154,19 +670,45 @@ include tests/repo/org.videolan.vlc/en-US/sevenInchScreenshots/screenshot5.png include tests/repo/org.videolan.vlc/en-US/sevenInchScreenshots/screenshot6.png include tests/repo/org.videolan.vlc/en-US/sevenInchScreenshots/screenshot8.png include tests/repo/patch.1619.obb.mainpatch.current.obb +include tests/repo/souch.smsbypass_9.apk include tests/repo/urzip-*.apk +include tests/repo/v1.v2.sig_1020.apk include tests/run-tests +include tests/scanner.TestCase +include tests/server.TestCase include tests/signatures.TestCase include tests/signindex/guardianproject.jar include tests/signindex/guardianproject-v1.jar include tests/signindex/testy.jar include tests/signindex/unsigned.jar +include tests/source-files/at.bitfire.davdroid/build.gradle +include tests/source-files/com.kunzisoft.testcase/build.gradle +include tests/source-files/com.nextcloud.client/build.gradle +include tests/source-files/com.nextcloud.client.dev/src/generic/fastlane/metadata/android/en-US/full_description.txt +include tests/source-files/com.nextcloud.client.dev/src/generic/fastlane/metadata/android/en-US/short_description.txt +include tests/source-files/com.nextcloud.client.dev/src/generic/fastlane/metadata/android/en-US/title.txt +include tests/source-files/com.nextcloud.client.dev/src/versionDev/fastlane/metadata/android/en-US/full_description.txt +include tests/source-files/com.nextcloud.client.dev/src/versionDev/fastlane/metadata/android/en-US/short_description.txt +include tests/source-files/com.nextcloud.client.dev/src/versionDev/fastlane/metadata/android/en-US/title.txt +include tests/source-files/com.nextcloud.client/src/generic/fastlane/metadata/android/en-US/full_description.txt +include tests/source-files/com.nextcloud.client/src/generic/fastlane/metadata/android/en-US/short_description.txt +include tests/source-files/com.nextcloud.client/src/generic/fastlane/metadata/android/en-US/title.txt +include tests/source-files/com.nextcloud.client/src/versionDev/fastlane/metadata/android/en-US/full_description.txt +include tests/source-files/com.nextcloud.client/src/versionDev/fastlane/metadata/android/en-US/short_description.txt +include tests/source-files/com.nextcloud.client/src/versionDev/fastlane/metadata/android/en-US/title.txt +include tests/source-files/eu.siacs.conversations/build.gradle +include tests/source-files/eu.siacs.conversations/metadata/en-US/name.txt include tests/source-files/fdroid/fdroidclient/AndroidManifest.xml include tests/source-files/fdroid/fdroidclient/build.gradle +include tests/source-files/firebase-suspect/app/build.gradle +include tests/source-files/firebase-suspect/build.gradle +include tests/source-files/firebase-whitelisted/app/build.gradle +include tests/source-files/firebase-whitelisted/build.gradle include tests/source-files/open-keychain/open-keychain/build.gradle include tests/source-files/open-keychain/open-keychain/OpenKeychain/build.gradle include tests/source-files/osmandapp/osmand/build.gradle include tests/source-files/Zillode/syncthing-silk/build.gradle +include tests/SpeedoMeterApp.main_1.apk include tests/stats/known_apks.txt include tests/testcommon.py include tests/update.TestCase @@ -175,3 +717,7 @@ include tests/urzip-badcert.apk include tests/urzip-badsig.apk include tests/urzip-release.apk include tests/urzip-release-unsigned.apk +include tests/v2.only.sig_2.apk +include tests/valid-package-names/random-package-names +include tests/valid-package-names/RandomPackageNames.java +include tests/valid-package-names/test.py From aa1e95836001cebfd5c7310e0ac2fdb034af90a7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 19:39:52 +0200 Subject: [PATCH 0072/2775] tests: only run hooks/pre-commit if its present (not in source tarball) --- tests/run-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-tests b/tests/run-tests index 63cefb94..353005e1 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -128,7 +128,7 @@ set -x # show each command as it is executed echo_header "run commit hooks" cd $WORKSPACE -./hooks/pre-commit +test -x ./hooks/pre-commit && ./hooks/pre-commit #------------------------------------------------------------------------------# From 60173d35df75499a2776d0986cdc0cd16ccd4aa7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 16:20:15 +0200 Subject: [PATCH 0073/2775] ./setup.py release: make upload step manual so CI can run first There is lots of CI tests for the Debian package, so it is good to first run those Debian CI tests before uploading an fdroidserver release. --- setup.cfg | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index ed171a15..d4887223 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,8 @@ # uploading here requires Python 3.5.3+ or setuptools 27+, -# use instead: twine upload dist/fdroidserver*.tar.gz* +# use instead: twine upload --sign dist/fdroidserver*.tar.gz [aliases] -release = versioncheck compile_catalog register sdist upload --sign +release = versioncheck compile_catalog sdist # All this below is for Babel config. Ideally we would only use # Babel, but it is still missing some key features that gettext gives diff --git a/setup.py b/setup.py index f491e631..1f51e157 100755 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ class VersionCheckCommand(Command): print('ERROR: Release version mismatch! setup.py (%s) does not match git (%s)' % (version, version_git)) sys.exit(1) - print('Upload using: twine upload dist/fdroidserver*.tar.gz*') + print('Upload using: twine upload --sign dist/fdroidserver-%s.tar.gz' % version) def get_data_files(): From 4ddd840471814b7afbfca99be775482eb646ca77 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 19:39:52 +0200 Subject: [PATCH 0074/2775] tests: only run hooks/pre-commit if its present (not in source tarball) --- tests/run-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-tests b/tests/run-tests index 63cefb94..353005e1 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -128,7 +128,7 @@ set -x # show each command as it is executed echo_header "run commit hooks" cd $WORKSPACE -./hooks/pre-commit +test -x ./hooks/pre-commit && ./hooks/pre-commit #------------------------------------------------------------------------------# From a9aa8788e0b4a05cbca04c4509705710ba63049c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 22:33:01 +0200 Subject: [PATCH 0075/2775] tests: only run source tarball test if running from git clone --- tests/run-tests | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/run-tests b/tests/run-tests index 353005e1..742a1cfc 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -636,19 +636,21 @@ $fdroid install || true #------------------------------------------------------------------------------# -echo_header "create a source tarball" +# only run this test if running from a git repo, not all files are in the tarball +if [ -e .git/config ]; then + echo_header "create a source tarball" -cd $WORKSPACE -./setup.py compile_catalog sdist - -REPOROOT=`create_test_dir` -cd $REPOROOT -tar xzf `ls -1 $WORKSPACE/dist/fdroidserver-*.tar.gz | sort -n | tail -1` -cd $REPOROOT -./fdroidserver-*/fdroid init -copy_apks_into_repo $REPOROOT -./fdroidserver-*/fdroid update --create-metadata --verbose + cd $WORKSPACE + ./setup.py compile_catalog sdist + REPOROOT=`create_test_dir` + cd $REPOROOT + tar xzf `ls -1 $WORKSPACE/dist/fdroidserver-*.tar.gz | sort -n | tail -1` + cd $REPOROOT + ./fdroidserver-*/fdroid init + copy_apks_into_repo $REPOROOT + ./fdroidserver-*/fdroid update --create-metadata --verbose +fi #------------------------------------------------------------------------------# echo_header "test config checks of local_copy_dir" From 5ba741912815b55b8e1a1068facf4d9a89f929fd Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 22:33:01 +0200 Subject: [PATCH 0076/2775] tests: only run source tarball test if running from git clone --- tests/run-tests | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/run-tests b/tests/run-tests index 353005e1..742a1cfc 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -636,19 +636,21 @@ $fdroid install || true #------------------------------------------------------------------------------# -echo_header "create a source tarball" +# only run this test if running from a git repo, not all files are in the tarball +if [ -e .git/config ]; then + echo_header "create a source tarball" -cd $WORKSPACE -./setup.py compile_catalog sdist - -REPOROOT=`create_test_dir` -cd $REPOROOT -tar xzf `ls -1 $WORKSPACE/dist/fdroidserver-*.tar.gz | sort -n | tail -1` -cd $REPOROOT -./fdroidserver-*/fdroid init -copy_apks_into_repo $REPOROOT -./fdroidserver-*/fdroid update --create-metadata --verbose + cd $WORKSPACE + ./setup.py compile_catalog sdist + REPOROOT=`create_test_dir` + cd $REPOROOT + tar xzf `ls -1 $WORKSPACE/dist/fdroidserver-*.tar.gz | sort -n | tail -1` + cd $REPOROOT + ./fdroidserver-*/fdroid init + copy_apks_into_repo $REPOROOT + ./fdroidserver-*/fdroid update --create-metadata --verbose +fi #------------------------------------------------------------------------------# echo_header "test config checks of local_copy_dir" From e8cd0986e357da37832743a51518157bc051a11d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 18:54:52 +0200 Subject: [PATCH 0077/2775] include all relevant files in source tarball (MANIFEST.in) --- MANIFEST.in | 550 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 548 insertions(+), 2 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index ba173c91..8be4dabf 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,9 +4,9 @@ include buildserver/provision-android-sdk include buildserver/provision-apt-get-install include buildserver/provision-apt-proxy include buildserver/provision-gradle -include buildserver/provision-pip include buildserver/setup-env-vars include buildserver/Vagrantfile +include CHANGELOG.md include completion/bash-completion include docker/Dockerfile include docker/drozer.py @@ -41,15 +41,513 @@ include locale/uk/LC_MESSAGES/fdroidserver.mo include locale/zh_Hans/LC_MESSAGES/fdroidserver.mo include locale/zh_Hant/LC_MESSAGES/fdroidserver.mo include makebuildserver -include README.rst +include README.md include tests/androguard_test.py include tests/bad-unicode-*.apk include tests/build.TestCase +include tests/build-tools/17.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/17.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/17.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/17.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/17.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/17.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/17.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/17.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/17.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/17.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/17.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/17.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/17.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/17.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/17.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/18.1.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/18.1.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/18.1.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/18.1.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/18.1.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/18.1.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/18.1.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/18.1.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/18.1.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/18.1.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/18.1.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/18.1.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/18.1.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/18.1.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/18.1.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/19.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/19.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/19.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/19.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/19.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/19.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/19.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/19.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/19.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/19.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/19.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/19.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/19.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/19.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/19.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/19.1.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/19.1.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/19.1.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/19.1.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/19.1.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/19.1.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/19.1.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/19.1.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/19.1.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/19.1.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/19.1.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/19.1.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/19.1.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/19.1.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/19.1.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/20.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/20.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/20.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/20.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/20.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/20.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/20.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/20.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/20.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/20.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/20.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/20.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/20.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/20.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/20.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/21.1.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/21.1.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/21.1.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/21.1.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/21.1.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/21.1.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/21.1.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/21.1.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/21.1.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/21.1.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/21.1.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/21.1.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/21.1.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/21.1.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/21.1.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/21.1.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/21.1.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/21.1.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/21.1.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/21.1.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/21.1.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/21.1.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/21.1.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/21.1.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/21.1.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/21.1.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/21.1.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/21.1.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/21.1.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/21.1.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/22.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/22.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/22.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/22.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/22.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/22.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/22.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/22.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/22.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/22.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/22.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/22.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/22.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/22.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/22.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/22.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/22.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/22.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/22.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/22.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/22.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/22.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/22.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/22.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/22.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/22.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/22.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/22.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/22.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/22.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/23.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/23.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/23.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/23.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/23.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/23.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/23.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/23.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/23.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/23.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/23.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/23.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/23.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/23.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/23.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/23.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/23.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/23.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/23.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/23.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/23.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/23.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/23.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/23.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/23.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/23.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/23.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/23.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/23.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/23.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/23.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/23.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/23.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/23.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/23.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/23.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/23.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/23.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/23.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/23.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/23.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/23.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/23.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/23.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/23.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/23.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/23.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/23.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/23.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/23.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/23.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/23.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/23.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/23.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/23.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/23.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/23.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/23.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/23.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/23.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/24.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/24.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/24.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/24.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/24.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/24.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/24.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/24.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/24.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/24.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/24.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/24.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/24.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/24.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/24.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/24.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/24.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/24.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/24.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/24.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/24.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/24.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/24.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/24.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/24.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/24.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/24.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/24.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/24.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/24.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/24.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/24.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/24.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/24.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/24.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/24.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/24.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/24.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/24.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/24.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/24.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/24.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/24.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/24.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/24.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/24.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/24.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/24.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/24.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/24.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/24.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/24.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/24.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/24.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/24.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/24.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/24.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/24.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/24.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/24.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/25.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/25.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/25.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/25.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/25.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/25.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/25.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/25.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/25.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/25.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/25.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/25.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/25.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/25.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/25.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/25.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/25.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/25.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/25.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/25.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/25.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/25.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/25.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/25.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/25.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/25.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/25.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/25.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/25.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/25.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/25.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/25.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/25.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/25.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/25.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/25.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/25.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/25.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/25.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/25.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/25.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/25.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/25.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/25.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/25.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/25.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/25.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/25.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/25.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/25.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/25.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/25.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/25.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/25.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/25.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/25.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/25.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/25.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/25.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/25.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/26.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/26.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/26.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/26.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/26.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/26.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/26.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/26.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/26.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/26.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/26.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/26.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/26.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/26.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/26.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/26.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/26.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/26.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/26.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/26.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/26.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/26.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/26.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/26.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/26.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/26.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/26.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/26.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/26.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/26.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/26.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/26.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/26.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/26.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/26.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/26.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/26.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/26.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/26.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/26.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/26.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/26.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/26.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/26.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/26.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/26.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/26.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/26.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/26.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/26.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/26.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/26.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/26.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/26.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/26.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/26.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/26.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/26.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/26.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/26.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/27.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/27.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/27.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/27.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/27.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/27.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/27.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/27.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/27.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/27.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/27.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/27.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/27.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/27.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/27.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/27.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/27.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/27.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/27.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/27.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/27.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/27.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/27.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/27.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/27.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/27.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/27.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/27.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/27.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/27.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/27.0.2/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/27.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/27.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/27.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/27.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/27.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/27.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/27.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/27.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/27.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/27.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/27.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/27.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/27.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/27.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/27.0.3/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/27.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/27.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/27.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/27.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/27.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/27.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/27.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/27.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/27.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/27.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/27.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/27.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/27.0.3/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/27.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/28.0.0/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/28.0.0/aapt-output-com.politedroid_3.txt +include tests/build-tools/28.0.0/aapt-output-com.politedroid_4.txt +include tests/build-tools/28.0.0/aapt-output-com.politedroid_5.txt +include tests/build-tools/28.0.0/aapt-output-com.politedroid_6.txt +include tests/build-tools/28.0.0/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/28.0.0/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/28.0.0/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/28.0.0/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/28.0.0/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/28.0.0/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/28.0.0/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/28.0.0/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/28.0.0/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/28.0.0/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/28.0.1/aapt-output-com.moez.QKSMS_182.txt +include tests/build-tools/28.0.1/aapt-output-com.politedroid_3.txt +include tests/build-tools/28.0.1/aapt-output-com.politedroid_4.txt +include tests/build-tools/28.0.1/aapt-output-com.politedroid_5.txt +include tests/build-tools/28.0.1/aapt-output-com.politedroid_6.txt +include tests/build-tools/28.0.1/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/28.0.1/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/28.0.1/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/28.0.1/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/28.0.1/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/28.0.1/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/28.0.1/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/28.0.1/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/28.0.1/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/28.0.1/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/28.0.2/aapt-output-com.politedroid_3.txt +include tests/build-tools/28.0.2/aapt-output-com.politedroid_4.txt +include tests/build-tools/28.0.2/aapt-output-com.politedroid_5.txt +include tests/build-tools/28.0.2/aapt-output-com.politedroid_6.txt +include tests/build-tools/28.0.2/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/28.0.2/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/28.0.2/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/28.0.2/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/28.0.2/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/28.0.2/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/28.0.2/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/28.0.2/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/28.0.2/aapt-output-org.droidtr.keyboard_34.txt +include tests/build-tools/28.0.2/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/28.0.3/aapt-output-com.example.test.helloworld_1.txt +include tests/build-tools/28.0.3/aapt-output-com.politedroid_3.txt +include tests/build-tools/28.0.3/aapt-output-com.politedroid_4.txt +include tests/build-tools/28.0.3/aapt-output-com.politedroid_5.txt +include tests/build-tools/28.0.3/aapt-output-com.politedroid_6.txt +include tests/build-tools/28.0.3/aapt-output-duplicate.permisssions_9999999.txt +include tests/build-tools/28.0.3/aapt-output-info.guardianproject.urzip_100.txt +include tests/build-tools/28.0.3/aapt-output-info.zwanenburg.caffeinetile_4.txt +include tests/build-tools/28.0.3/aapt-output-no.min.target.sdk_987.txt +include tests/build-tools/28.0.3/aapt-output-obb.main.oldversion_1444412523.txt +include tests/build-tools/28.0.3/aapt-output-obb.mainpatch.current_1619.txt +include tests/build-tools/28.0.3/aapt-output-obb.main.twoversions_1101613.txt +include tests/build-tools/28.0.3/aapt-output-obb.main.twoversions_1101615.txt +include tests/build-tools/28.0.3/aapt-output-obb.main.twoversions_1101617.txt +include tests/build-tools/28.0.3/aapt-output-souch.smsbypass_9.txt +include tests/build-tools/generate.sh +include tests/check-fdroid-apk include tests/common.TestCase include tests/complete-ci-tests include tests/config.py include tests/description-parsing.py +include tests/dummy-keystore.jks include tests/dump_internal_metadata_format.py +include tests/exception.TestCase include tests/extra/convert_metadata_to_yaml_then_txt.sh include tests/extra/manual-vmtools-test.py include tests/getsig/getsig.java @@ -63,6 +561,8 @@ include tests/import_proxy.py include tests/import.TestCase include tests/index.TestCase include tests/install.TestCase +include tests/IsMD5Disabled.java +include tests/janus.apk include tests/keystore.jks include tests/lint.TestCase include tests/metadata/apk/info.guardianproject.urzip.yaml @@ -73,6 +573,7 @@ include tests/metadata/dump/com.politedroid.yaml include tests/metadata/dump/org.adaway.yaml include tests/metadata/dump/org.smssecure.smssecure.yaml include tests/metadata/dump/org.videolan.vlc.yaml +include tests/metadata/duplicate.permisssions.yml include tests/metadata/fake.ota.update.txt include tests/metadata/info.guardianproject.checkey/en-US/description.txt include tests/metadata/info.guardianproject.checkey/en-US/phoneScreenshots/checkey-phone.png @@ -87,18 +588,27 @@ include tests/metadata/info.guardianproject.urzip/en-US/short_description.txt include tests/metadata/info.guardianproject.urzip/en-US/title.txt include tests/metadata/info.guardianproject.urzip/en-US/video.txt include tests/metadata/info.guardianproject.urzip.yml +include tests/metadata/info.zwanenburg.caffeinetile.yml +include tests/metadata/no.min.target.sdk.yml include tests/metadata/obb.main.oldversion.txt include tests/metadata/obb.mainpatch.current.txt include tests/metadata/obb.main.twoversions.txt include tests/metadata/org.adaway.json include tests/metadata/org.fdroid.ci.test.app.txt include tests/metadata/org.fdroid.fdroid.txt +include tests/metadata/org.smssecure.smssecure/signatures/134/28969C09.RSA +include tests/metadata/org.smssecure.smssecure/signatures/134/28969C09.SF +include tests/metadata/org.smssecure.smssecure/signatures/134/MANIFEST.MF +include tests/metadata/org.smssecure.smssecure/signatures/135/28969C09.RSA +include tests/metadata/org.smssecure.smssecure/signatures/135/28969C09.SF +include tests/metadata/org.smssecure.smssecure/signatures/135/MANIFEST.MF include tests/metadata/org.smssecure.smssecure.txt include tests/metadata/org.videolan.vlc.yml include tests/metadata/raw.template.txt include tests/metadata-rewrite-yml/app.with.special.build.params.yml include tests/metadata-rewrite-yml/fake.ota.update.yml include tests/metadata-rewrite-yml/org.fdroid.fdroid.yml +include tests/metadata/souch.smsbypass.txt include tests/metadata.TestCase include tests/openssl-version-check-test.py include tests/org.bitbucket.tickytacky.mirrormirror_1.apk @@ -106,17 +616,23 @@ include tests/org.bitbucket.tickytacky.mirrormirror_2.apk include tests/org.bitbucket.tickytacky.mirrormirror_3.apk include tests/org.bitbucket.tickytacky.mirrormirror_4.apk include tests/org.dyndns.fules.ck_20.apk +include tests/publish.TestCase include tests/repo/categories.txt +include tests/repo/com.example.test.helloworld_1.apk include tests/repo/com.politedroid_3.apk include tests/repo/com.politedroid_4.apk include tests/repo/com.politedroid_5.apk include tests/repo/com.politedroid_6.apk +include tests/repo/duplicate.permisssions_9999999.apk include tests/repo/fake.ota.update_1234.zip +include tests/repo/index-v1.json include tests/repo/index.xml +include tests/repo/info.zwanenburg.caffeinetile_4.apk include tests/repo/main.1101613.obb.main.twoversions.obb include tests/repo/main.1101615.obb.main.twoversions.obb include tests/repo/main.1434483388.obb.main.oldversion.obb include tests/repo/main.1619.obb.mainpatch.current.obb +include tests/repo/no.min.target.sdk_987.apk include tests/repo/obb.main.oldversion_1444412523.apk include tests/repo/obb.mainpatch.current_1619_another-release-key.apk include tests/repo/obb.mainpatch.current_1619.apk @@ -154,19 +670,45 @@ include tests/repo/org.videolan.vlc/en-US/sevenInchScreenshots/screenshot5.png include tests/repo/org.videolan.vlc/en-US/sevenInchScreenshots/screenshot6.png include tests/repo/org.videolan.vlc/en-US/sevenInchScreenshots/screenshot8.png include tests/repo/patch.1619.obb.mainpatch.current.obb +include tests/repo/souch.smsbypass_9.apk include tests/repo/urzip-*.apk +include tests/repo/v1.v2.sig_1020.apk include tests/run-tests +include tests/scanner.TestCase +include tests/server.TestCase include tests/signatures.TestCase include tests/signindex/guardianproject.jar include tests/signindex/guardianproject-v1.jar include tests/signindex/testy.jar include tests/signindex/unsigned.jar +include tests/source-files/at.bitfire.davdroid/build.gradle +include tests/source-files/com.kunzisoft.testcase/build.gradle +include tests/source-files/com.nextcloud.client/build.gradle +include tests/source-files/com.nextcloud.client.dev/src/generic/fastlane/metadata/android/en-US/full_description.txt +include tests/source-files/com.nextcloud.client.dev/src/generic/fastlane/metadata/android/en-US/short_description.txt +include tests/source-files/com.nextcloud.client.dev/src/generic/fastlane/metadata/android/en-US/title.txt +include tests/source-files/com.nextcloud.client.dev/src/versionDev/fastlane/metadata/android/en-US/full_description.txt +include tests/source-files/com.nextcloud.client.dev/src/versionDev/fastlane/metadata/android/en-US/short_description.txt +include tests/source-files/com.nextcloud.client.dev/src/versionDev/fastlane/metadata/android/en-US/title.txt +include tests/source-files/com.nextcloud.client/src/generic/fastlane/metadata/android/en-US/full_description.txt +include tests/source-files/com.nextcloud.client/src/generic/fastlane/metadata/android/en-US/short_description.txt +include tests/source-files/com.nextcloud.client/src/generic/fastlane/metadata/android/en-US/title.txt +include tests/source-files/com.nextcloud.client/src/versionDev/fastlane/metadata/android/en-US/full_description.txt +include tests/source-files/com.nextcloud.client/src/versionDev/fastlane/metadata/android/en-US/short_description.txt +include tests/source-files/com.nextcloud.client/src/versionDev/fastlane/metadata/android/en-US/title.txt +include tests/source-files/eu.siacs.conversations/build.gradle +include tests/source-files/eu.siacs.conversations/metadata/en-US/name.txt include tests/source-files/fdroid/fdroidclient/AndroidManifest.xml include tests/source-files/fdroid/fdroidclient/build.gradle +include tests/source-files/firebase-suspect/app/build.gradle +include tests/source-files/firebase-suspect/build.gradle +include tests/source-files/firebase-whitelisted/app/build.gradle +include tests/source-files/firebase-whitelisted/build.gradle include tests/source-files/open-keychain/open-keychain/build.gradle include tests/source-files/open-keychain/open-keychain/OpenKeychain/build.gradle include tests/source-files/osmandapp/osmand/build.gradle include tests/source-files/Zillode/syncthing-silk/build.gradle +include tests/SpeedoMeterApp.main_1.apk include tests/stats/known_apks.txt include tests/testcommon.py include tests/update.TestCase @@ -175,3 +717,7 @@ include tests/urzip-badcert.apk include tests/urzip-badsig.apk include tests/urzip-release.apk include tests/urzip-release-unsigned.apk +include tests/v2.only.sig_2.apk +include tests/valid-package-names/random-package-names +include tests/valid-package-names/RandomPackageNames.java +include tests/valid-package-names/test.py From fd1e22e79140be3b614932b82398b9e034d0ef76 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 16:20:15 +0200 Subject: [PATCH 0078/2775] ./setup.py release: make upload step manual so CI can run first There is lots of CI tests for the Debian package, so it is good to first run those Debian CI tests before uploading an fdroidserver release. --- setup.cfg | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index ed171a15..d4887223 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,8 @@ # uploading here requires Python 3.5.3+ or setuptools 27+, -# use instead: twine upload dist/fdroidserver*.tar.gz* +# use instead: twine upload --sign dist/fdroidserver*.tar.gz [aliases] -release = versioncheck compile_catalog register sdist upload --sign +release = versioncheck compile_catalog sdist # All this below is for Babel config. Ideally we would only use # Babel, but it is still missing some key features that gettext gives diff --git a/setup.py b/setup.py index c32f4449..43c9be25 100755 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ class VersionCheckCommand(Command): print('ERROR: Release version mismatch! setup.py (%s) does not match git (%s)' % (version, version_git)) sys.exit(1) - print('Upload using: twine upload dist/fdroidserver*.tar.gz*') + print('Upload using: twine upload --sign dist/fdroidserver-%s.tar.gz' % version) def get_data_files(): From fd870c59bd7514bac1a3641d2f2e818467109730 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jul 2019 19:02:12 +0200 Subject: [PATCH 0079/2775] bump to version v1.1.3 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 43c9be25..14a0607b 100755 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ def get_data_files(): setup(name='fdroidserver', - version='1.1.2', + version='1.1.3', description='F-Droid Server Tools', long_description='README.md', long_description_content_type='text/markdown', From a248a696921ba65e9ef54a44e47a0732bbdd82f1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 4 Jul 2019 00:13:41 +0200 Subject: [PATCH 0080/2775] tests: skip disabled_algorithms test when apksigner is present apksigner doesn't treat MD5 signatures as deprecated, so that portion of the tests would always fail. --- tests/update.TestCase | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/update.TestCase b/tests/update.TestCase index bce7e41c..f9a46d88 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -625,6 +625,10 @@ class UpdateTest(unittest.TestCase): self.assertFalse(os.path.exists(os.path.join('archive', apkName))) self.assertTrue(os.path.exists(os.path.join('repo', apkName))) + if os.path.exists('/usr/bin/apksigner') or 'apksigner' in config: + print('SKIPPING: apksigner installed and it allows MD5 signatures') + return + javac = config['jarsigner'].replace('jarsigner', 'javac') v = subprocess.check_output([javac, '-version'], stderr=subprocess.STDOUT)[6:-1].decode('utf-8') if LooseVersion(v) < LooseVersion('1.8.0_132'): From f30983368cb0a6baa9b6bdf9bc7036480f496485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 26 Jun 2019 17:00:01 +0200 Subject: [PATCH 0081/2775] build: rsync buildlogs to /repo --- fdroidserver/common.py | 2 +- tests/common.TestCase | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 535a3f2a..96c7e91f 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3272,7 +3272,7 @@ def deploy_build_log_with_rsync(appid, vercode, log_content, # TODO: sign compressed log file, if a signing key is configured for webroot in config.get('serverwebroot', []): - dest_path = os.path.join(webroot, "buildlogs") + dest_path = os.path.join(webroot, "repo") if not dest_path.endswith('/'): dest_path += '/' # make sure rsync knows this is a directory cmd = ['rsync', diff --git a/tests/common.TestCase b/tests/common.TestCase index 8930ed65..66d9ef22 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -951,8 +951,8 @@ class CommonTest(unittest.TestCase): fdroidserver.common.options.quiet = False fdroidserver.common.config = {} fdroidserver.common.config['serverwebroot'] = [ - 'example.com:/var/www/fdroid/repo/', - 'example.com:/var/www/fdroid/archive/'] + 'example.com:/var/www/fdroid/', + 'example.com:/var/www/fbot/'] fdroidserver.common.config['deploy_process_logs'] = True fdroidserver.common.config['identity_file'] = 'ssh/id_rsa' @@ -969,7 +969,7 @@ class CommonTest(unittest.TestCase): '-e', 'ssh -oBatchMode=yes -oIdentitiesOnly=yes -i ssh/id_rsa', cmd[6], - 'example.com:/var/www/fdroid/repo/buildlogs/'], + 'example.com:/var/www/fdroid/repo/'], cmd) self.assertTrue(cmd[6].endswith('/com.example.app_4711_1.log.gz')) with gzip.open(cmd[6], 'r') as f: @@ -982,7 +982,7 @@ class CommonTest(unittest.TestCase): '-e', 'ssh -oBatchMode=yes -oIdentitiesOnly=yes -i ssh/id_rsa', cmd[6], - 'example.com:/var/www/fdroid/archive/buildlogs/'], + 'example.com:/var/www/fbot/repo/'], cmd) self.assertTrue(cmd[6].endswith('/com.example.app_4711_1.log.gz')) with gzip.open(cmd[6], 'r') as f: From 2c87b5e6f9b7c76e6b0ea7176d1eb94fcf680a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 3 Jul 2019 16:22:14 +0200 Subject: [PATCH 0082/2775] deploy build logs: no timestamps --- examples/config.py | 4 ++-- fdroidserver/common.py | 13 +++---------- tests/common.TestCase | 6 +++--- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/examples/config.py b/examples/config.py index cc84e18e..b2aa6443 100644 --- a/examples/config.py +++ b/examples/config.py @@ -173,8 +173,8 @@ The repository of older versions of applications from the main demo repository. # Uncomment this option if you want to logs of builds and other processes to # your repository server(s). Logs get published to all servers configured in -# 'serverwebroot'. For builds, only logs from build-jobs running inside a -# buildserver VM are supported. +# 'serverwebroot'. The name scheme is: .../repo/$APPID_$VERCODE.log.gz +# Only logs from build-jobs running inside a buildserver VM are supported. # # deploy_process_logs = True diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 96c7e91f..fe5e6201 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3232,8 +3232,7 @@ def local_rsync(options, fromdir, todir): raise FDroidException() -def deploy_build_log_with_rsync(appid, vercode, log_content, - timestamp=int(time.time())): +def deploy_build_log_with_rsync(appid, vercode, log_content): """Upload build log of one individual app build to an fdroid repository. :param appid: package name for dientifying to which app this log belongs. @@ -3241,7 +3240,6 @@ def deploy_build_log_with_rsync(appid, vercode, log_content, :param log_content: Content of the log which is about to be posted. Should be either a string or bytes. (bytes will be decoded as 'utf-8') - :param timestamp: timestamp for avoiding logfile name collisions. """ # check if deploying logs is enabled in config @@ -3253,16 +3251,11 @@ def deploy_build_log_with_rsync(appid, vercode, log_content, logging.warning(_('skip deploying full build logs: log content is empty')) return - if not (isinstance(timestamp, int) or isinstance(timestamp, float)): - raise ValueError(_("supplied timestamp value '{timestamp}' is not a unix timestamp" - .format(timestamp=timestamp))) - with tempfile.TemporaryDirectory() as tmpdir: # gzip compress log file log_gz_path = os.path.join( - tmpdir, '{pkg}_{ver}_{ts}.log.gz'.format(pkg=appid, - ver=vercode, - ts=int(timestamp))) + tmpdir, '{pkg}_{ver}.log.gz'.format(pkg=appid, + ver=vercode)) with gzip.open(log_gz_path, 'wb') as f: if isinstance(log_content, str): f.write(bytes(log_content, 'utf-8')) diff --git a/tests/common.TestCase b/tests/common.TestCase index 66d9ef22..52e48d89 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -971,7 +971,7 @@ class CommonTest(unittest.TestCase): cmd[6], 'example.com:/var/www/fdroid/repo/'], cmd) - self.assertTrue(cmd[6].endswith('/com.example.app_4711_1.log.gz')) + self.assertTrue(cmd[6].endswith('/com.example.app_4711.log.gz')) with gzip.open(cmd[6], 'r') as f: self.assertTrue(f.read(), mocklogcontent) elif assert_subprocess_call_iteration == 1: @@ -984,7 +984,7 @@ class CommonTest(unittest.TestCase): cmd[6], 'example.com:/var/www/fbot/repo/'], cmd) - self.assertTrue(cmd[6].endswith('/com.example.app_4711_1.log.gz')) + self.assertTrue(cmd[6].endswith('/com.example.app_4711.log.gz')) with gzip.open(cmd[6], 'r') as f: self.assertTrue(f.read(), mocklogcontent) else: @@ -996,7 +996,7 @@ class CommonTest(unittest.TestCase): with mock.patch('subprocess.call', side_effect=assert_subprocess_call): fdroidserver.common.deploy_build_log_with_rsync( - 'com.example.app', '4711', mocklogcontent, 1.1) + 'com.example.app', '4711', mocklogcontent) if __name__ == "__main__": From 48fce5f6bea8d6903fdd25cb61a73669d2c57a3f Mon Sep 17 00:00:00 2001 From: Thomas Wirth Date: Sun, 7 Jul 2019 21:03:24 +0200 Subject: [PATCH 0083/2775] Add Gradle 5.5 --- gradlew-fdroid | 3 ++- makebuildserver | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 20baf5f9..9742faa7 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -120,6 +120,7 @@ get_sha() { ["5.3.1"]="1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436" \ ["5.4"]="c8c17574245ecee9ed7fe4f6b593b696d1692d1adbfef425bef9b333e3a0e8de" \ ["5.4.1"]="7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc" \ + ["5.5"]="8d78b2ed63e7f07ad169c1186d119761c4773e681f332cfe1901045b1b0141bc" \ ) [ ! ${gradle_hashes[$1]+abc} ] && exit 1 echo "${gradle_hashes["$1"]}" @@ -141,7 +142,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index ed037da8..9b1083d1 100755 --- a/makebuildserver +++ b/makebuildserver @@ -352,6 +352,8 @@ CACHE_FILES = [ '1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436'), ('https://downloads.gradle.org/distributions/gradle-5.4.1-bin.zip', '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc'), + ('https://services.gradle.org/distributions/gradle-5.5-bin.zip', + '8d78b2ed63e7f07ad169c1186d119761c4773e681f332cfe1901045b1b0141bc'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 051596dd0d4bd4e3685acdd9ebdcf458eabc5e10 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 10 Jul 2019 13:22:55 +0200 Subject: [PATCH 0084/2775] tests: conditionally disable tests that can't work with apksigner apksigner treats MD5 signatures as valid, fdroid does not. --- tests/run-tests | 187 +++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 90 deletions(-) diff --git a/tests/run-tests b/tests/run-tests index 742a1cfc..c6248954 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -305,80 +305,85 @@ cp $WORKSPACE/tests/urzip.apk \ $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py $fdroid update --pretty --nosign -echo "This will fail when jarsigner allows MD5 for APK signatures" -test `grep '' archive/index.xml | wc -l` -eq 5 -test `grep '' repo/index.xml | wc -l` -eq 7 - +if which apksigner; then + test `grep '' archive/index.xml | wc -l` -eq 2 + test `grep '' repo/index.xml | wc -l` -eq 10 +else + echo "This will fail when jarsigner allows MD5 for APK signatures" + test `grep '' archive/index.xml | wc -l` -eq 5 + test `grep '' repo/index.xml | wc -l` -eq 7 +fi #------------------------------------------------------------------------------# -echo_header 'test per-app "Archive Policy"' +if ! which apksigner; then + echo_header 'test per-app "Archive Policy"' -REPOROOT=`create_test_dir` -cd $REPOROOT -fdroid_init_with_prebuilt_keystore -echo "accepted_formats = ['txt']" >> config.py -test -d metadata || mkdir metadata -cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ -test -d repo || mkdir repo -cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ -$sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py + REPOROOT=`create_test_dir` + cd $REPOROOT + fdroid_init_with_prebuilt_keystore + echo "accepted_formats = ['txt']" >> config.py + test -d metadata || mkdir metadata + cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ + test -d repo || mkdir repo + cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ + $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 0 -test `grep '' repo/index.xml | wc -l` -eq 4 -grep -F com.politedroid_3.apk repo/index.xml -grep -F com.politedroid_4.apk repo/index.xml -grep -F com.politedroid_5.apk repo/index.xml -grep -F com.politedroid_6.apk repo/index.xml -test -e repo/com.politedroid_3.apk -test -e repo/com.politedroid_4.apk -test -e repo/com.politedroid_5.apk -test -e repo/com.politedroid_6.apk + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 0 + test `grep '' repo/index.xml | wc -l` -eq 4 + grep -F com.politedroid_3.apk repo/index.xml + grep -F com.politedroid_4.apk repo/index.xml + grep -F com.politedroid_5.apk repo/index.xml + grep -F com.politedroid_6.apk repo/index.xml + test -e repo/com.politedroid_3.apk + test -e repo/com.politedroid_4.apk + test -e repo/com.politedroid_5.apk + test -e repo/com.politedroid_6.apk -echo "enable one app in the repo" -$sed -i.tmp 's,^Archive Policy:4,Archive Policy:1,' metadata/com.politedroid.txt -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 3 -test `grep '' repo/index.xml | wc -l` -eq 1 -grep -F com.politedroid_3.apk archive/index.xml -grep -F com.politedroid_4.apk archive/index.xml -grep -F com.politedroid_5.apk archive/index.xml -grep -F com.politedroid_6.apk repo/index.xml -test -e archive/com.politedroid_3.apk -test -e archive/com.politedroid_4.apk -test -e archive/com.politedroid_5.apk -test -e repo/com.politedroid_6.apk + echo "enable one app in the repo" + $sed -i.tmp 's,^Archive Policy:4,Archive Policy:1,' metadata/com.politedroid.txt + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 3 + test `grep '' repo/index.xml | wc -l` -eq 1 + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk archive/index.xml + grep -F com.politedroid_5.apk archive/index.xml + grep -F com.politedroid_6.apk repo/index.xml + test -e archive/com.politedroid_3.apk + test -e archive/com.politedroid_4.apk + test -e archive/com.politedroid_5.apk + test -e repo/com.politedroid_6.apk -echo "remove all apps from the repo" -$sed -i.tmp 's,^Archive Policy:1,Archive Policy:0,' metadata/com.politedroid.txt -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 4 -test `grep '' repo/index.xml | wc -l` -eq 0 -grep -F com.politedroid_3.apk archive/index.xml -grep -F com.politedroid_4.apk archive/index.xml -grep -F com.politedroid_5.apk archive/index.xml -grep -F com.politedroid_6.apk archive/index.xml -test -e archive/com.politedroid_3.apk -test -e archive/com.politedroid_4.apk -test -e archive/com.politedroid_5.apk -test -e archive/com.politedroid_6.apk -! test -e repo/com.politedroid_6.apk - -echo "move back one from archive to the repo" -$sed -i.tmp 's,^Archive Policy:0,Archive Policy:1,' metadata/com.politedroid.txt -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 3 -test `grep '' repo/index.xml | wc -l` -eq 1 -grep -F com.politedroid_3.apk archive/index.xml -grep -F com.politedroid_4.apk archive/index.xml -grep -F com.politedroid_5.apk archive/index.xml -grep -F com.politedroid_6.apk repo/index.xml -test -e archive/com.politedroid_3.apk -test -e archive/com.politedroid_4.apk -test -e archive/com.politedroid_5.apk -! test -e archive/com.politedroid_6.apk -test -e repo/com.politedroid_6.apk + echo "remove all apps from the repo" + $sed -i.tmp 's,^Archive Policy:1,Archive Policy:0,' metadata/com.politedroid.txt + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 4 + test `grep '' repo/index.xml | wc -l` -eq 0 + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk archive/index.xml + grep -F com.politedroid_5.apk archive/index.xml + grep -F com.politedroid_6.apk archive/index.xml + test -e archive/com.politedroid_3.apk + test -e archive/com.politedroid_4.apk + test -e archive/com.politedroid_5.apk + test -e archive/com.politedroid_6.apk + ! test -e repo/com.politedroid_6.apk + echo "move back one from archive to the repo" + $sed -i.tmp 's,^Archive Policy:0,Archive Policy:1,' metadata/com.politedroid.txt + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 3 + test `grep '' repo/index.xml | wc -l` -eq 1 + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk archive/index.xml + grep -F com.politedroid_5.apk archive/index.xml + grep -F com.politedroid_6.apk repo/index.xml + test -e archive/com.politedroid_3.apk + test -e archive/com.politedroid_4.apk + test -e archive/com.politedroid_5.apk + ! test -e archive/com.politedroid_6.apk + test -e repo/com.politedroid_6.apk +fi #------------------------------------------------------------------------------# @@ -505,29 +510,31 @@ test -e repo/org.bitbucket.tickytacky.mirrormirror_3.apk test -e repo/org.bitbucket.tickytacky.mirrormirror_4.apk test -e archive/urzip-badsig.apk -$sed -i.tmp '/allow_disabled_algorithms/d' config.py -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 5 -test `grep '' repo/index.xml | wc -l` -eq 3 -grep -F org.bitbucket.tickytacky.mirrormirror_1.apk archive/index.xml -grep -F org.bitbucket.tickytacky.mirrormirror_2.apk archive/index.xml -grep -F org.bitbucket.tickytacky.mirrormirror_3.apk archive/index.xml -grep -F org.bitbucket.tickytacky.mirrormirror_4.apk archive/index.xml -grep -F com.politedroid_3.apk archive/index.xml -grep -F com.politedroid_4.apk repo/index.xml -grep -F com.politedroid_5.apk repo/index.xml -grep -F com.politedroid_6.apk repo/index.xml -! grep -F urzip-badsig.apk repo/index.xml -! grep -F urzip-badsig.apk archive/index.xml -test -e archive/org.bitbucket.tickytacky.mirrormirror_1.apk -test -e archive/org.bitbucket.tickytacky.mirrormirror_2.apk -test -e archive/org.bitbucket.tickytacky.mirrormirror_3.apk -test -e archive/org.bitbucket.tickytacky.mirrormirror_4.apk -test -e archive/com.politedroid_3.apk -test -e archive/urzip-badsig.apk -test -e repo/com.politedroid_4.apk -test -e repo/com.politedroid_5.apk -test -e repo/com.politedroid_6.apk +if ! which apksigner; then + $sed -i.tmp '/allow_disabled_algorithms/d' config.py + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 5 + test `grep '' repo/index.xml | wc -l` -eq 3 + grep -F org.bitbucket.tickytacky.mirrormirror_1.apk archive/index.xml + grep -F org.bitbucket.tickytacky.mirrormirror_2.apk archive/index.xml + grep -F org.bitbucket.tickytacky.mirrormirror_3.apk archive/index.xml + grep -F org.bitbucket.tickytacky.mirrormirror_4.apk archive/index.xml + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk repo/index.xml + grep -F com.politedroid_5.apk repo/index.xml + grep -F com.politedroid_6.apk repo/index.xml + ! grep -F urzip-badsig.apk repo/index.xml + ! grep -F urzip-badsig.apk archive/index.xml + test -e archive/org.bitbucket.tickytacky.mirrormirror_1.apk + test -e archive/org.bitbucket.tickytacky.mirrormirror_2.apk + test -e archive/org.bitbucket.tickytacky.mirrormirror_3.apk + test -e archive/org.bitbucket.tickytacky.mirrormirror_4.apk + test -e archive/com.politedroid_3.apk + test -e archive/urzip-badsig.apk + test -e repo/com.politedroid_4.apk + test -e repo/com.politedroid_5.apk + test -e repo/com.politedroid_6.apk +fi #------------------------------------------------------------------------------# From 191363ad55ca41a630500f0700c1b2a0f5ed8997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 11 Jul 2019 01:40:42 +0200 Subject: [PATCH 0085/2775] exclude Provides metadata from yml --- fdroidserver/metadata.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 17a3e739..b228c924 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -52,7 +52,7 @@ def warn_or_exception(value): app_fields = set([ 'Disabled', 'AntiFeatures', - 'Provides', + 'Provides', # deprecated, txt only 'Categories', 'License', 'Author Name', @@ -96,7 +96,6 @@ app_fields = set([ yaml_app_field_order = [ 'Disabled', 'AntiFeatures', - 'Provides', 'Categories', 'License', 'AuthorName', From 723bd110a68c024933255c99bda39eab8dbaef53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 11 Jul 2019 01:46:18 +0200 Subject: [PATCH 0086/2775] test that yaml parsing does not accept provides --- tests/metadata.TestCase | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index d7b72f71..d669c567 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -367,6 +367,24 @@ class MetadataTest(unittest.TestCase): 'prebuild': "a && b && " "sed -i 's,a,b,'"}]}) + def test_parse_yaml_provides_should_raise_exception(self): + mf = io.StringIO(textwrap.dedent("""\ + Provides: this.is.deprecated + AutoName: F-Droid + RepoType: git + Builds: + - versionCode: 1 + versionName: v0.1.0 + prebuild: |- + a && b && sed -i 's,a,b,' + """)) + mf.name = 'mock_filename.yaml' + mf.seek(0) + result = {} + with mock.patch('fdroidserver.metadata.warnings_action', 'error'): + with self.assertRaises(fdroidserver.metadata.MetaDataException): + fdroidserver.metadata.parse_yaml_metadata(mf, result) + def test_write_yaml_1_line_scripts_as_string(self): mf = io.StringIO() app = fdroidserver.metadata.App() From 6e48663230ed9449f828b438f370a82072f5fcf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 11 Jul 2019 03:18:30 +0200 Subject: [PATCH 0087/2775] test that write yaml does not write provides --- tests/metadata.TestCase | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index d669c567..68e402ab 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -539,6 +539,34 @@ class MetadataTest(unittest.TestCase): UpdateCheckMode: None """)) + def test_write_yaml_make_sure_provides_does_not_get_written(self): + mf = io.StringIO() + app = fdroidserver.metadata.App() + app.Categories = ['None'] + app.Provides = 'this.is.deprecated' + app.builds = [] + build = fdroidserver.metadata.Build() + build.versionCode = 102030 + build.versionName = 'v1.2.3' + build.gradle = ['yes'] + app.builds.append(build) + fdroidserver.metadata.write_yaml(mf, app) + mf.seek(0) + self.assertEqual(mf.read(), textwrap.dedent("""\ + Categories: + - None + License: Unknown + + Builds: + - versionName: v1.2.3 + versionCode: 102030 + gradle: + - yes + + AutoUpdateMode: None + UpdateCheckMode: None + """)) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From dcf3837bcbebd0f1d0e77f942c0d867162e3dc71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 15 Jul 2019 15:45:02 +0200 Subject: [PATCH 0088/2775] parse yaml: ignore (and warn) deprecated field: Provides --- fdroidserver/metadata.py | 19 ++++++++++++++++--- tests/metadata.TestCase | 7 ++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index b228c924..d08f4102 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -1071,12 +1071,25 @@ def parse_json_metadata(mf, app): def parse_yaml_metadata(mf, app): yamldata = yaml.safe_load(mf) + deprecated_in_yaml = ['Provides'] + if yamldata: for field in yamldata: if field not in yaml_app_fields: - warn_or_exception(_("Unrecognised app field '{fieldname}' " - "in '{path}'").format(fieldname=field, - path=mf.name)) + if field not in deprecated_in_yaml: + warn_or_exception(_("Unrecognised app field " + "'{fieldname}' in '{path}'") + .format(fieldname=field, + path=mf.name)) + + for deprecated_field in deprecated_in_yaml: + if deprecated_field in yamldata: + logging.warning(_("Ignoring '{field}' in '{metapath}' " + "metadata because it is deprecated.") + .format(field=deprecated_field, + metapath=mf.name)) + del(yamldata[deprecated_field]) + if yamldata.get('Builds', None): for build in yamldata.get('Builds', []): # put all build flag keywords into a set to avoid diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 68e402ab..686301db 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -367,7 +367,7 @@ class MetadataTest(unittest.TestCase): 'prebuild': "a && b && " "sed -i 's,a,b,'"}]}) - def test_parse_yaml_provides_should_raise_exception(self): + def test_parse_yaml_provides_should_be_ignored(self): mf = io.StringIO(textwrap.dedent("""\ Provides: this.is.deprecated AutoName: F-Droid @@ -382,8 +382,9 @@ class MetadataTest(unittest.TestCase): mf.seek(0) result = {} with mock.patch('fdroidserver.metadata.warnings_action', 'error'): - with self.assertRaises(fdroidserver.metadata.MetaDataException): - fdroidserver.metadata.parse_yaml_metadata(mf, result) + fdroidserver.metadata.parse_yaml_metadata(mf, result) + self.assertNotIn('Provides', result) + self.assertNotIn('provides', result) def test_write_yaml_1_line_scripts_as_string(self): mf = io.StringIO() From 24e0db1c837c0ea377580ce7aac97902bb4928ff Mon Sep 17 00:00:00 2001 From: relan Date: Sun, 21 Jul 2019 18:20:25 +0300 Subject: [PATCH 0089/2775] Add Gradle 5.5.1 --- gradlew-fdroid | 3 ++- makebuildserver | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 9742faa7..f337cb62 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -121,6 +121,7 @@ get_sha() { ["5.4"]="c8c17574245ecee9ed7fe4f6b593b696d1692d1adbfef425bef9b333e3a0e8de" \ ["5.4.1"]="7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc" \ ["5.5"]="8d78b2ed63e7f07ad169c1186d119761c4773e681f332cfe1901045b1b0141bc" \ + ["5.5.1"]="222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00" \ ) [ ! ${gradle_hashes[$1]+abc} ] && exit 1 echo "${gradle_hashes["$1"]}" @@ -142,7 +143,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 9b1083d1..0ae74d0a 100755 --- a/makebuildserver +++ b/makebuildserver @@ -352,8 +352,8 @@ CACHE_FILES = [ '1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436'), ('https://downloads.gradle.org/distributions/gradle-5.4.1-bin.zip', '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc'), - ('https://services.gradle.org/distributions/gradle-5.5-bin.zip', - '8d78b2ed63e7f07ad169c1186d119761c4773e681f332cfe1901045b1b0141bc'), + ('https://services.gradle.org/distributions/gradle-5.5.1-bin.zip', + '222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From e2fed09af11a80ff3ead001eeb3cdfaae3e8fcf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 22 Jul 2019 01:34:55 +0200 Subject: [PATCH 0090/2775] make metadata template behaves well for empty values --- fdroidserver/update.py | 5 +++ tests/update.TestCase | 83 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 0b41c44e..f7440786 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1869,6 +1869,11 @@ def create_metadata_from_template(apk): r'\1 ' + apk['packageName'], metatxt, flags=re.IGNORECASE | re.MULTILINE) + # make sure unset string values will be interpreted as blank strings + str_fields = [x for x in metadata.yaml_app_fields if metadata.fieldtype(x) == metadata.TYPE_STRING] + metatxt = re.sub(r'^(' + '|'.join(str_fields) + '):\\s*$', + r"\1: ''", metatxt, + flags=re.MULTILINE) with open(os.path.join('metadata', apk['packageName'] + '.yml'), 'w') as f: f.write(metatxt) else: diff --git a/tests/update.TestCase b/tests/update.TestCase index f9a46d88..028d7c43 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -15,8 +15,10 @@ import tempfile import unittest import yaml import zipfile +import textwrap from binascii import unhexlify from distutils.version import LooseVersion +from testcommon import TmpCwd localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) @@ -833,6 +835,87 @@ class UpdateTest(unittest.TestCase): icons_src = fdroidserver.update._get_apk_icons_src('urzip-release.apk', None) assert icons_src == {} + def test_create_metadata_from_template_empty_keys(self): + apk = {'packageName': 'rocks.janicerand'} + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir('metadata') + with open('template.yml', 'w') as f: + f.write(textwrap.dedent('''\ + Disabled: + Provides: + License: + AuthorName: + AuthorEmail: + AuthorWebSite: + WebSite: + SourceCode: + IssueTracker: + Translation: + Changelog: + Donate: + FlattrID: + LiberapayID: + Bitcoin: + Litecoin: + Name: + AutoName: + Summary: + RequiresRoot: + RepoType: + Repo: + Binaries: + Builds: + ArchivePolicy: + AutoUpdateMode: + UpdateCheckMode: + UpdateCheckIgnore: + VercodeOperation: + UpdateCheckName: + UpdateCheckData: + CurrentVersion: + CurrentVersionCode: + NoSourceSince: + ''')) + fdroidserver.update.create_metadata_from_template(apk) + with open(os.path.join('metadata', 'rocks.janicerand.yml')) as f: + metadata_content = yaml.load(f) + self.maxDiff = None + self.assertDictEqual(metadata_content, + {'ArchivePolicy': '', + 'AuthorEmail': '', + 'AuthorName': '', + 'AuthorWebSite': '', + 'AutoName': 'rocks.janicerand', + 'AutoUpdateMode': '', + 'Binaries': '', + 'Bitcoin': '', + 'Builds': '', + 'Changelog': '', + 'CurrentVersion': '', + 'CurrentVersionCode': '', + 'Disabled': '', + 'Donate': '', + 'FlattrID': '', + 'IssueTracker': '', + 'LiberapayID': '', + 'License': '', + 'Litecoin': '', + 'Name': 'rocks.janicerand', + 'NoSourceSince': '', + 'Provides': '', + 'Repo': '', + 'RepoType': '', + 'RequiresRoot': '', + 'SourceCode': '', + 'Summary': 'rocks.janicerand', + 'Translation': '', + 'UpdateCheckData': '', + 'UpdateCheckIgnore': '', + 'UpdateCheckMode': '', + 'UpdateCheckName': '', + 'VercodeOperation': '', + 'WebSite': ''}) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 7c4bed05580171e4e86a5ac0ad977ae11899c4aa Mon Sep 17 00:00:00 2001 From: Gerhard Olsson Date: Tue, 23 Jul 2019 00:21:28 +0200 Subject: [PATCH 0091/2775] UpdateCheckIgnore: Exception if version not matched Ignoreversions were checked also if version did not match which raised the exception The 'version check' runs in some unexpected situations like just to find directories where to find the AutoName. --- fdroidserver/checkupdates.py | 8 ++++++-- fdroidserver/common.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index d8d6af43..e472bee7 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -43,6 +43,9 @@ from .exception import VCSException, NoSubmodulesException, FDroidException, Met # required. def check_http(app): + ignoreversions = app.UpdateCheckIgnore + ignoresearch = re.compile(ignoreversions).search if ignoreversions else None + try: if not app.UpdateCheckData: @@ -82,8 +85,9 @@ def check_http(app): raise FDroidException("No RE match for version") version = m.group(1) - return (version, vercode) - + if version and ignoresearch and not ignoresearch(version): + return (version, vercode) + return (None, ("Version {version} is ignored").format(version=version)) except FDroidException: msg = "Could not complete http check for app {0} due to unknown error: {1}".format(app.id, traceback.format_exc()) return (None, msg) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index d3141f08..55052355 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1508,7 +1508,7 @@ def parse_androidmanifests(paths, app): if vercode is not None \ and (max_vercode is None or vercode > max_vercode): - if not ignoresearch or not ignoresearch(version): + if version and (not ignoresearch or not ignoresearch(version)): if version is not None: max_version = version if vercode is not None: From 19aa7360110e6df1296e6b233f25a71140871d33 Mon Sep 17 00:00:00 2001 From: Gerhard Olsson Date: Tue, 23 Jul 2019 00:22:32 +0200 Subject: [PATCH 0092/2775] UpdateCheckName is Ignore: Do not parse manifests --- fdroidserver/checkupdates.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index e472bee7..988ad31a 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -355,7 +355,8 @@ def possible_subdirs(app): def fetch_autoname(app, tag): - if not app.RepoType or app.UpdateCheckMode in ('None', 'Static'): + if not app.RepoType or app.UpdateCheckMode in ('None', 'Static') \ + or app.UpdateCheckName == "Ignore": return None if app.RepoType == 'srclib': From 1c4d377793e9ae3a130ca6fdea05261a3074e019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 23 Jul 2019 15:55:28 +0200 Subject: [PATCH 0093/2775] use logging.warning in checkupdates --- fdroidserver/checkupdates.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 988ad31a..c34d2fa2 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -454,7 +454,7 @@ def checkupdates_app(app): if noverok: logging.info(logmsg) else: - logging.warn(logmsg) + logging.warning(logmsg) elif vercode == app.CurrentVersionCode: logging.info("...up to date") else: @@ -475,7 +475,7 @@ def checkupdates_app(app): if options.auto: mode = app.AutoUpdateMode if not app.CurrentVersionCode: - logging.warn("Can't auto-update app with no current version code: " + app.id) + logging.warning("Can't auto-update app with no current version code: " + app.id) elif mode in ('None', 'Static'): pass elif mode.startswith('Version '): @@ -512,7 +512,7 @@ def checkupdates_app(app): ver = common.getcvname(app) commitmsg = "Update %s to %s" % (name, ver) else: - logging.warn('Invalid auto update mode "' + mode + '" on ' + app.id) + logging.warning('Invalid auto update mode "' + mode + '" on ' + app.id) if commitmsg: metadata.write_metadata(app.metadatapath, app) From 1c7af1dc2cf6fa9d5fbb0586a22919040a6e98d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 23 Jul 2019 17:28:19 +0200 Subject: [PATCH 0094/2775] add test for checkupdates_app() --- tests/checkupdates.TestCase | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100755 tests/checkupdates.TestCase diff --git a/tests/checkupdates.TestCase b/tests/checkupdates.TestCase new file mode 100755 index 00000000..d6231f62 --- /dev/null +++ b/tests/checkupdates.TestCase @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 + +import inspect +import logging +import optparse +import os +import sys +import unittest +from unittest import mock + + +localmodule = os.path.realpath( + os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) +print('localmodule: ' + localmodule) +if localmodule not in sys.path: + sys.path.insert(0, localmodule) + +import fdroidserver.checkupdates +import fdroidserver.metadata + + +class CommonTest(unittest.TestCase): + '''fdroidserver/common.py''' + + def setUp(self): + logging.basicConfig(level=logging.DEBUG) + self.basedir = os.path.join(localmodule, 'tests') + self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) + if not os.path.exists(self.tmpdir): + os.makedirs(self.tmpdir) + os.chdir(self.basedir) + + def test_checkupdates_app_http(self): + fdroidserver.checkupdates.options = mock.Mock() + fdroidserver.checkupdates.options.auto = 'bleh' + fdroidserver.checkupdates.config = {} + + app = fdroidserver.metadata.App() + app.id = 'loop.starts.shooting' + app.metadatapath = 'metadata/' + app.id + '.yml' + app.CurrentVersionCode = 10108 + app.UpdateCheckMode = 'HTTP' + app.UpdateCheckData = 'mock' + + with mock.patch('fdroidserver.checkupdates.check_http', lambda app: (None, 'bla')): + fdroidserver.checkupdates.checkupdates_app(app) + + with mock.patch('fdroidserver.checkupdates.check_http', lambda app: ('1.1.9', 10109)): + with mock.patch('fdroidserver.metadata.write_metadata', mock.Mock()) as wrmock: + with mock.patch('subprocess.call', lambda cmd: 0): + fdroidserver.checkupdates.checkupdates_app(app) + wrmock.assert_called_with(app.metadatapath, app) + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + + parser = optparse.OptionParser() + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="Spew out even more information than normal") + (fdroidserver.common.options, args) = parser.parse_args(['--verbose']) + + newSuite = unittest.TestSuite() + newSuite.addTest(unittest.makeSuite(CommonTest)) + unittest.main(failfast=False) From 23280b6029055a028059eda76863ab6cd4af2787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 23 Jul 2019 20:45:04 +0200 Subject: [PATCH 0095/2775] checkupdates add check_http test --- tests/checkupdates.TestCase | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/checkupdates.TestCase b/tests/checkupdates.TestCase index d6231f62..e310fc8f 100755 --- a/tests/checkupdates.TestCase +++ b/tests/checkupdates.TestCase @@ -53,6 +53,23 @@ class CommonTest(unittest.TestCase): fdroidserver.checkupdates.checkupdates_app(app) wrmock.assert_called_with(app.metadatapath, app) + def test_check_http(self): + fdroidserver.checkupdates.options = mock.Mock() + + app = fdroidserver.metadata.App() + app.id = 'loop.starts.shooting' + app.metadatapath = 'metadata/' + app.id + '.yml' + app.CurrentVersionCode = 10108 + app.UpdateCheckMode = 'HTTP' + app.UpdateCheckData = 'https://a.net/b.txt|c(.*)|https://d.net/e.txt|v(.*)' + + respmock = mock.Mock() + respmock.read = lambda: 'v1.1.9\nc10109'.encode('utf-8') + with mock.patch('urllib.request.urlopen', lambda a, b, c: respmock): + vername, vercode = fdroidserver.checkupdates.check_http(app) + self.assertEqual(vername, '1.1.9') + self.assertEqual(vercode, '10109') + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From be3d498391b721c7e79f3895b5895f8691a189ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 23 Jul 2019 18:07:22 +0200 Subject: [PATCH 0096/2775] checkupdates: check_http fix ignore check --- fdroidserver/checkupdates.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index c34d2fa2..b166ca39 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -85,9 +85,13 @@ def check_http(app): raise FDroidException("No RE match for version") version = m.group(1) - if version and ignoresearch and not ignoresearch(version): + if ignoresearch and version: + if not ignoresearch(version): + return (version, vercode) + else: + return (None, ("Version {version} is ignored").format(version=version)) + else: return (version, vercode) - return (None, ("Version {version} is ignored").format(version=version)) except FDroidException: msg = "Could not complete http check for app {0} due to unknown error: {1}".format(app.id, traceback.format_exc()) return (None, msg) From bad888856a87b7edfeabad23f5229d92cc29874a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 23 Jul 2019 20:51:51 +0200 Subject: [PATCH 0097/2775] checkupdates: add check_http ignore test --- tests/checkupdates.TestCase | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/checkupdates.TestCase b/tests/checkupdates.TestCase index e310fc8f..503f6b76 100755 --- a/tests/checkupdates.TestCase +++ b/tests/checkupdates.TestCase @@ -62,6 +62,7 @@ class CommonTest(unittest.TestCase): app.CurrentVersionCode = 10108 app.UpdateCheckMode = 'HTTP' app.UpdateCheckData = 'https://a.net/b.txt|c(.*)|https://d.net/e.txt|v(.*)' + app.UpdateCheckIgnore = 'beta' respmock = mock.Mock() respmock.read = lambda: 'v1.1.9\nc10109'.encode('utf-8') @@ -70,6 +71,24 @@ class CommonTest(unittest.TestCase): self.assertEqual(vername, '1.1.9') self.assertEqual(vercode, '10109') + def test_check_http_ignore(self): + fdroidserver.checkupdates.options = mock.Mock() + + app = fdroidserver.metadata.App() + app.id = 'loop.starts.shooting' + app.metadatapath = 'metadata/' + app.id + '.yml' + app.CurrentVersionCode = 10108 + app.UpdateCheckMode = 'HTTP' + app.UpdateCheckData = 'https://a.net/b.txt|c(.*)|https://d.net/e.txt|v(.*)' + app.UpdateCheckIgnore = 'beta' + + respmock = mock.Mock() + respmock.read = lambda: 'v1.1.9-beta\nc10109'.encode('utf-8') + with mock.patch('urllib.request.urlopen', lambda a, b, c: respmock): + vername, vercode = fdroidserver.checkupdates.check_http(app) + self.assertEqual(vername, None) + self.assertEqual(vercode, 'Version 1.1.9-beta is ignored') + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From d0368d0ad8b4debc2206e7fe54cd1c1d3049b684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 23 Jul 2019 22:44:45 +0200 Subject: [PATCH 0098/2775] common add parse_androidmanifests_ignore test --- tests/common.TestCase | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/common.TestCase b/tests/common.TestCase index 52e48d89..f99150ea 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -806,6 +806,19 @@ class CommonTest(unittest.TestCase): self.assertEqual(('0.94-test', '940', 'org.fdroid.fdroid'), fdroidserver.common.parse_androidmanifests(paths, app)) + def test_parse_androidmanifests_ignore(self): + app = fdroidserver.metadata.App() + app.id = 'org.fdroid.fdroid' + app.UpdateCheckIgnore = '-test' + paths = [ + os.path.join('source-files', 'fdroid', 'fdroidclient', 'AndroidManifest.xml'), + os.path.join('source-files', 'fdroid', 'fdroidclient', 'build.gradle'), + ] + for path in paths: + self.assertTrue(os.path.isfile(path)) + self.assertEqual(('Ignore', None, 'org.fdroid.fdroid'), + fdroidserver.common.parse_androidmanifests(paths, app)) + def test_parse_androidmanifests_with_flavor(self): app = fdroidserver.metadata.App() build = fdroidserver.metadata.Build() From bdf67784f517a3acc3f069871aa51af94dba0e67 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 31 Jul 2019 15:37:58 +0200 Subject: [PATCH 0099/2775] makebuildserver: add ndk r20 --- buildserver/config.buildserver.py | 1 + buildserver/provision-android-ndk | 2 +- examples/config.py | 1 + makebuildserver | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index 4d04f488..7edf693c 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -10,6 +10,7 @@ ndk_paths = { 'r17c': "/home/vagrant/android-ndk/r17c", 'r18b': "/home/vagrant/android-ndk/r18b", 'r19c': "/home/vagrant/android-ndk/r19c", + 'r20': "/home/vagrant/android-ndk/r20", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index bb652390..7e137d48 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/examples/config.py b/examples/config.py index b2aa6443..b5793eeb 100644 --- a/examples/config.py +++ b/examples/config.py @@ -21,6 +21,7 @@ # 'r17c': None, # 'r18b': None, # 'r19c': None, +# 'r20': None, # } # Directory to store downloaded tools in (i.e. gradle versions) diff --git a/makebuildserver b/makebuildserver index 0ae74d0a..fc4541ce 100755 --- a/makebuildserver +++ b/makebuildserver @@ -374,6 +374,8 @@ CACHE_FILES = [ '4f61cbe4bbf6406aa5ef2ae871def78010eed6271af72de83f8bd0b07a9fd3fd'), ('https://dl.google.com/android/repository/android-ndk-r19c-linux-x86_64.zip', '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), + ('https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip', + '57435158f109162f41f2f43d5563d2164e4d5d0364783a9a6fab3ef12cb06ce0'), ] From 8fe1583f83ecbeadc731286cb5251b8e3aac70d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 7 May 2019 22:43:05 +0200 Subject: [PATCH 0100/2775] improve bitcoin validation regex + testcases --- fdroidserver/metadata.py | 2 +- tests/metadata.TestCase | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index bbf8d70b..d8ed98b9 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -453,7 +453,7 @@ valuetypes = { ["AuthorEmail"]), FieldValidator("Bitcoin address", - r'^[a-zA-Z0-9]{27,34}$', + r'^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$', ["Bitcoin"]), FieldValidator("Litecoin address", diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 486dca09..dc786095 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -39,6 +39,35 @@ class MetadataTest(unittest.TestCase): os.makedirs(self.tmpdir) os.chdir(self.basedir) + def test_FieldValidator(self): + validator = None + for vali in fdroidserver.metadata.valuetypes: + if vali.name == 'Bitcoin address': + validator = vali + break + self.assertIsNotNone(validator, "could not find 'Bitcoin address' validator") + + fdroidserver.metadata.warnings_action = 'error' + + # some valid addresses (P2PKH, P2SH, Bech32) + self.assertIsNone(validator.check('1BrrrrErsrWetrTrnrrrrm4GFg7xJaNVN2', 'fake.app.id')) + self.assertIsNone(validator.check('3JrrrrWrEZr3rNrrvrecrnyirrnqRhWNLy', 'fake.app.id')) + self.assertIsNone(validator.check('bc1qar0srrr7xrkvr5lr43lrdnwrre5rgtrzrf5rrq', 'fake.app.id')) + + # some invalid addresses (various special use/testnet addresses) + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '21BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '5Hrgr3ur5rGLrfKrrrrrrHSrqJrroGrrzrQrrrrrrLNrsrDrrrA', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'L1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id') + def test_read_metadata(self): def _build_yaml_representer(dumper, data): @@ -54,6 +83,7 @@ class MetadataTest(unittest.TestCase): config['ndk_paths'] = dict() config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config + fdroidserver.metadata.warnings_action = None apps = fdroidserver.metadata.read_metadata(xref=True) for appid in ('org.smssecure.smssecure', 'org.adaway', @@ -73,6 +103,7 @@ class MetadataTest(unittest.TestCase): def test_rewrite_yaml_fakeotaupdate(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']} + fdroidserver.metadata.warnings_action = None # rewrite metadata allapps = fdroidserver.metadata.read_metadata(xref=True) From 6b013d01aca1a3c343887bd4ce05eb1a9f7d2e22 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 4 Jul 2019 00:13:41 +0200 Subject: [PATCH 0101/2775] tests: skip disabled_algorithms test when apksigner is present apksigner doesn't treat MD5 signatures as deprecated, so that portion of the tests would always fail. --- tests/update.TestCase | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/update.TestCase b/tests/update.TestCase index bce7e41c..f9a46d88 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -625,6 +625,10 @@ class UpdateTest(unittest.TestCase): self.assertFalse(os.path.exists(os.path.join('archive', apkName))) self.assertTrue(os.path.exists(os.path.join('repo', apkName))) + if os.path.exists('/usr/bin/apksigner') or 'apksigner' in config: + print('SKIPPING: apksigner installed and it allows MD5 signatures') + return + javac = config['jarsigner'].replace('jarsigner', 'javac') v = subprocess.check_output([javac, '-version'], stderr=subprocess.STDOUT)[6:-1].decode('utf-8') if LooseVersion(v) < LooseVersion('1.8.0_132'): From dff47beb019c095632002b940097aa42cd584ddf Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 10 Jul 2019 13:22:55 +0200 Subject: [PATCH 0102/2775] tests: conditionally disable tests that can't work with apksigner apksigner treats MD5 signatures as valid, fdroid does not. --- tests/run-tests | 187 +++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 90 deletions(-) diff --git a/tests/run-tests b/tests/run-tests index 742a1cfc..c6248954 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -305,80 +305,85 @@ cp $WORKSPACE/tests/urzip.apk \ $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py $fdroid update --pretty --nosign -echo "This will fail when jarsigner allows MD5 for APK signatures" -test `grep '' archive/index.xml | wc -l` -eq 5 -test `grep '' repo/index.xml | wc -l` -eq 7 - +if which apksigner; then + test `grep '' archive/index.xml | wc -l` -eq 2 + test `grep '' repo/index.xml | wc -l` -eq 10 +else + echo "This will fail when jarsigner allows MD5 for APK signatures" + test `grep '' archive/index.xml | wc -l` -eq 5 + test `grep '' repo/index.xml | wc -l` -eq 7 +fi #------------------------------------------------------------------------------# -echo_header 'test per-app "Archive Policy"' +if ! which apksigner; then + echo_header 'test per-app "Archive Policy"' -REPOROOT=`create_test_dir` -cd $REPOROOT -fdroid_init_with_prebuilt_keystore -echo "accepted_formats = ['txt']" >> config.py -test -d metadata || mkdir metadata -cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ -test -d repo || mkdir repo -cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ -$sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py + REPOROOT=`create_test_dir` + cd $REPOROOT + fdroid_init_with_prebuilt_keystore + echo "accepted_formats = ['txt']" >> config.py + test -d metadata || mkdir metadata + cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ + test -d repo || mkdir repo + cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ + $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 0 -test `grep '' repo/index.xml | wc -l` -eq 4 -grep -F com.politedroid_3.apk repo/index.xml -grep -F com.politedroid_4.apk repo/index.xml -grep -F com.politedroid_5.apk repo/index.xml -grep -F com.politedroid_6.apk repo/index.xml -test -e repo/com.politedroid_3.apk -test -e repo/com.politedroid_4.apk -test -e repo/com.politedroid_5.apk -test -e repo/com.politedroid_6.apk + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 0 + test `grep '' repo/index.xml | wc -l` -eq 4 + grep -F com.politedroid_3.apk repo/index.xml + grep -F com.politedroid_4.apk repo/index.xml + grep -F com.politedroid_5.apk repo/index.xml + grep -F com.politedroid_6.apk repo/index.xml + test -e repo/com.politedroid_3.apk + test -e repo/com.politedroid_4.apk + test -e repo/com.politedroid_5.apk + test -e repo/com.politedroid_6.apk -echo "enable one app in the repo" -$sed -i.tmp 's,^Archive Policy:4,Archive Policy:1,' metadata/com.politedroid.txt -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 3 -test `grep '' repo/index.xml | wc -l` -eq 1 -grep -F com.politedroid_3.apk archive/index.xml -grep -F com.politedroid_4.apk archive/index.xml -grep -F com.politedroid_5.apk archive/index.xml -grep -F com.politedroid_6.apk repo/index.xml -test -e archive/com.politedroid_3.apk -test -e archive/com.politedroid_4.apk -test -e archive/com.politedroid_5.apk -test -e repo/com.politedroid_6.apk + echo "enable one app in the repo" + $sed -i.tmp 's,^Archive Policy:4,Archive Policy:1,' metadata/com.politedroid.txt + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 3 + test `grep '' repo/index.xml | wc -l` -eq 1 + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk archive/index.xml + grep -F com.politedroid_5.apk archive/index.xml + grep -F com.politedroid_6.apk repo/index.xml + test -e archive/com.politedroid_3.apk + test -e archive/com.politedroid_4.apk + test -e archive/com.politedroid_5.apk + test -e repo/com.politedroid_6.apk -echo "remove all apps from the repo" -$sed -i.tmp 's,^Archive Policy:1,Archive Policy:0,' metadata/com.politedroid.txt -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 4 -test `grep '' repo/index.xml | wc -l` -eq 0 -grep -F com.politedroid_3.apk archive/index.xml -grep -F com.politedroid_4.apk archive/index.xml -grep -F com.politedroid_5.apk archive/index.xml -grep -F com.politedroid_6.apk archive/index.xml -test -e archive/com.politedroid_3.apk -test -e archive/com.politedroid_4.apk -test -e archive/com.politedroid_5.apk -test -e archive/com.politedroid_6.apk -! test -e repo/com.politedroid_6.apk - -echo "move back one from archive to the repo" -$sed -i.tmp 's,^Archive Policy:0,Archive Policy:1,' metadata/com.politedroid.txt -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 3 -test `grep '' repo/index.xml | wc -l` -eq 1 -grep -F com.politedroid_3.apk archive/index.xml -grep -F com.politedroid_4.apk archive/index.xml -grep -F com.politedroid_5.apk archive/index.xml -grep -F com.politedroid_6.apk repo/index.xml -test -e archive/com.politedroid_3.apk -test -e archive/com.politedroid_4.apk -test -e archive/com.politedroid_5.apk -! test -e archive/com.politedroid_6.apk -test -e repo/com.politedroid_6.apk + echo "remove all apps from the repo" + $sed -i.tmp 's,^Archive Policy:1,Archive Policy:0,' metadata/com.politedroid.txt + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 4 + test `grep '' repo/index.xml | wc -l` -eq 0 + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk archive/index.xml + grep -F com.politedroid_5.apk archive/index.xml + grep -F com.politedroid_6.apk archive/index.xml + test -e archive/com.politedroid_3.apk + test -e archive/com.politedroid_4.apk + test -e archive/com.politedroid_5.apk + test -e archive/com.politedroid_6.apk + ! test -e repo/com.politedroid_6.apk + echo "move back one from archive to the repo" + $sed -i.tmp 's,^Archive Policy:0,Archive Policy:1,' metadata/com.politedroid.txt + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 3 + test `grep '' repo/index.xml | wc -l` -eq 1 + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk archive/index.xml + grep -F com.politedroid_5.apk archive/index.xml + grep -F com.politedroid_6.apk repo/index.xml + test -e archive/com.politedroid_3.apk + test -e archive/com.politedroid_4.apk + test -e archive/com.politedroid_5.apk + ! test -e archive/com.politedroid_6.apk + test -e repo/com.politedroid_6.apk +fi #------------------------------------------------------------------------------# @@ -505,29 +510,31 @@ test -e repo/org.bitbucket.tickytacky.mirrormirror_3.apk test -e repo/org.bitbucket.tickytacky.mirrormirror_4.apk test -e archive/urzip-badsig.apk -$sed -i.tmp '/allow_disabled_algorithms/d' config.py -$fdroid update --pretty --nosign -test `grep '' archive/index.xml | wc -l` -eq 5 -test `grep '' repo/index.xml | wc -l` -eq 3 -grep -F org.bitbucket.tickytacky.mirrormirror_1.apk archive/index.xml -grep -F org.bitbucket.tickytacky.mirrormirror_2.apk archive/index.xml -grep -F org.bitbucket.tickytacky.mirrormirror_3.apk archive/index.xml -grep -F org.bitbucket.tickytacky.mirrormirror_4.apk archive/index.xml -grep -F com.politedroid_3.apk archive/index.xml -grep -F com.politedroid_4.apk repo/index.xml -grep -F com.politedroid_5.apk repo/index.xml -grep -F com.politedroid_6.apk repo/index.xml -! grep -F urzip-badsig.apk repo/index.xml -! grep -F urzip-badsig.apk archive/index.xml -test -e archive/org.bitbucket.tickytacky.mirrormirror_1.apk -test -e archive/org.bitbucket.tickytacky.mirrormirror_2.apk -test -e archive/org.bitbucket.tickytacky.mirrormirror_3.apk -test -e archive/org.bitbucket.tickytacky.mirrormirror_4.apk -test -e archive/com.politedroid_3.apk -test -e archive/urzip-badsig.apk -test -e repo/com.politedroid_4.apk -test -e repo/com.politedroid_5.apk -test -e repo/com.politedroid_6.apk +if ! which apksigner; then + $sed -i.tmp '/allow_disabled_algorithms/d' config.py + $fdroid update --pretty --nosign + test `grep '' archive/index.xml | wc -l` -eq 5 + test `grep '' repo/index.xml | wc -l` -eq 3 + grep -F org.bitbucket.tickytacky.mirrormirror_1.apk archive/index.xml + grep -F org.bitbucket.tickytacky.mirrormirror_2.apk archive/index.xml + grep -F org.bitbucket.tickytacky.mirrormirror_3.apk archive/index.xml + grep -F org.bitbucket.tickytacky.mirrormirror_4.apk archive/index.xml + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk repo/index.xml + grep -F com.politedroid_5.apk repo/index.xml + grep -F com.politedroid_6.apk repo/index.xml + ! grep -F urzip-badsig.apk repo/index.xml + ! grep -F urzip-badsig.apk archive/index.xml + test -e archive/org.bitbucket.tickytacky.mirrormirror_1.apk + test -e archive/org.bitbucket.tickytacky.mirrormirror_2.apk + test -e archive/org.bitbucket.tickytacky.mirrormirror_3.apk + test -e archive/org.bitbucket.tickytacky.mirrormirror_4.apk + test -e archive/com.politedroid_3.apk + test -e archive/urzip-badsig.apk + test -e repo/com.politedroid_4.apk + test -e repo/com.politedroid_5.apk + test -e repo/com.politedroid_6.apk +fi #------------------------------------------------------------------------------# From bb36bf6c6708619ed43bc06b04de987dfecfd727 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 15 Aug 2019 10:45:23 +0200 Subject: [PATCH 0103/2775] update CHANGELOG for v1.1.4 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e78ed677..27fec605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ +### 1.1.4 (2019-08-15) + +* include bitcoin validation regex required by fdroiddata + +* merged Debian patches to fix test suite there + +### 1.1.3 (2019-07-03) + +* fixed test suite when run from source tarball + +* fixed test runs in Debian + ### 1.1.2 (2019-03-29) * fix bug while downloading repo index ([!636](https://gitlab.com/fdroid/fdroidserver/merge_requests/636)) From c02a98f364a600d6d42a83d61f7a0e7b708d1e1b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 15 Aug 2019 10:45:50 +0200 Subject: [PATCH 0104/2775] bump to version v1.1.4 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 14a0607b..61b4e6e1 100755 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ def get_data_files(): setup(name='fdroidserver', - version='1.1.3', + version='1.1.4', description='F-Droid Server Tools', long_description='README.md', long_description_content_type='text/markdown', From b40906d148cd418191d671bb41eb8660a356fdc0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 15 Aug 2019 10:54:19 +0200 Subject: [PATCH 0105/2775] update CHANGELOG for v1.1.4 --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a76b7013..27fec605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,20 @@ +### 1.1.4 (2019-08-15) + +* include bitcoin validation regex required by fdroiddata + +* merged Debian patches to fix test suite there + +### 1.1.3 (2019-07-03) + +* fixed test suite when run from source tarball + +* fixed test runs in Debian + +### 1.1.2 (2019-03-29) + +* fix bug while downloading repo index ([!636](https://gitlab.com/fdroid/fdroidserver/merge_requests/636)) + ### 1.1.1 (2019-02-03) * support APK Signature v2 and v3 From 39e4e05c9f9a8b809c4efa319be4ef4996e80de3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 15 Aug 2019 12:19:29 +0200 Subject: [PATCH 0106/2775] setup.py: use officially documented way of including README https://packaging.python.org/tutorials/packaging-projects/ --- setup.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 61b4e6e1..5a4a9105 100755 --- a/setup.py +++ b/setup.py @@ -48,11 +48,13 @@ def get_data_files(): data_files.append((d, [f, ])) return data_files +with open("README.md", "r") as fh: + long_description = fh.read() setup(name='fdroidserver', version='1.1.4', description='F-Droid Server Tools', - long_description='README.md', + long_description=long_description, long_description_content_type='text/markdown', author='The F-Droid Project', author_email='team@f-droid.org', From 004e2c8f26bb0730830010040f08043ff2eb8aee Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 21 Aug 2019 14:40:41 +0200 Subject: [PATCH 0107/2775] setup.py: ruamel.yaml >= 0.15 required for yml rewrites --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5a4a9105..68d897f9 100755 --- a/setup.py +++ b/setup.py @@ -82,7 +82,7 @@ setup(name='fdroidserver', 'python-vagrant', 'PyYAML', 'qrcode', - 'ruamel.yaml >= 0.13', + 'ruamel.yaml >= 0.15', 'requests >= 2.5.2, != 2.11.0, != 2.12.2, != 2.18.0', 'docker-py >= 1.9, < 2.0', ], From fd2a9d07cae4b687bdb818b979978be8534a3a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 21 Aug 2019 22:11:02 +0200 Subject: [PATCH 0108/2775] format CHANGELOG.md to conform with _keep a changelog_ v1.0.0 --- CHANGELOG.md | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27fec605..f62bf17e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,49 +1,47 @@ +# Changelog -### 1.1.4 (2019-08-15) +All notable changes to this project will be documented in this file. +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) + +## [1.1.4] - 2019-08-15 +### Fixed * include bitcoin validation regex required by fdroiddata - * merged Debian patches to fix test suite there -### 1.1.3 (2019-07-03) - +## [1.1.3] - 2019-07-03 +### Fixed * fixed test suite when run from source tarball - * fixed test runs in Debian -### 1.1.2 (2019-03-29) - +## [1.1.2] - 2019-03-29 +### Fixed * fix bug while downloading repo index ([!636](https://gitlab.com/fdroid/fdroidserver/merge_requests/636)) -### 1.1.1 (2019-02-03) - +## [1.1.1] - 2019-02-03 +### Fixed * support APK Signature v2 and v3 - * all SDK Version values are output as integers in the index JSON - * take graphics from Fastlane dirs using any valid RFC5646 locale - * print warning if not running in UTF-8 encoding - * fdroid build: hide --on-server cli flag -### 1.1 (2019-01-28) - +## [1.1] - 2019-01-28 +### Fixed * a huge update with many fixes and new features: https://gitlab.com/fdroid/fdroidserver/milestones/7 - * can run without and Android SDK installed - * much more reliable operation with large binary APK collections - * sync all translations, including newly added languages: hu it ko pl pt_PT ru - * many security fixes, based on the security audit - * NoSourceSince automatically adds SourceGone Anti-Feature - * aapt scraping works with all known aapt versions - * smoother mirror setups - * much faster `fdroid update` when using androguard + +[Unreleased]: https://gitlab.com/fdroid/fdroidserver/compare/1.1.4...master +[1.1.4]: https://gitlab.com/fdroid/fdroidserver/compare/1.1.3...1.1.4 +[1.1.3]: https://gitlab.com/fdroid/fdroidserver/compare/1.1.2...1.1.3 +[1.1.2]: https://gitlab.com/fdroid/fdroidserver/compare/1.1.1...1.1.2 +[1.1.1]: https://gitlab.com/fdroid/fdroidserver/compare/1.1...1.1.1 +[1.1]: https://gitlab.com/fdroid/fdroidserver/tags/1.1 From 6b5fb27532407c717641fec96e75c36ce1d08a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 22 Aug 2019 01:48:58 +0200 Subject: [PATCH 0109/2775] add some missing items to CHANGELOG.md --- CHANGELOG.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f62bf17e..3deb6e79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +## [Unreleased] +### Added +* makebuildserver: added ndk r20 + ([!663](https://gitlab.com/fdroid/fdroidserver/merge_requests/663)) +* added support for gradle 5.5.1 + ([!656](https://gitlab.com/fdroid/fdroidserver/merge_requests/656)) + +### Fixed +* checkupdates: UpdateCheckIngore gets properly observed now + ([!659](https://gitlab.com/fdroid/fdroidserver/merge_requests/659), + [!660](https://gitlab.com/fdroid/fdroidserver/merge_requests/660)) +* import: `template.yml` now supports omitting values + ([!657](https://gitlab.com/fdroid/fdroidserver/merge_requests/657)) +* build: deploying buildlogs with rsync + ([!651](https://gitlab.com/fdroid/fdroidserver/merge_requests/651)) + ## [1.1.4] - 2019-08-15 ### Fixed * include bitcoin validation regex required by fdroiddata @@ -16,7 +32,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [1.1.2] - 2019-03-29 ### Fixed -* fix bug while downloading repo index ([!636](https://gitlab.com/fdroid/fdroidserver/merge_requests/636)) +* fix bug while downloading repo index + ([!636](https://gitlab.com/fdroid/fdroidserver/merge_requests/636)) ## [1.1.1] - 2019-02-03 ### Fixed From 16c1f69f7b1b5d794ead4408eb2b4d0e15c839a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rutkowski?= Date: Fri, 23 Aug 2019 18:20:40 +0200 Subject: [PATCH 0110/2775] Add Gradle 5.6 --- gradlew-fdroid | 3 ++- makebuildserver | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index f337cb62..4d1e453b 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -122,6 +122,7 @@ get_sha() { ["5.4.1"]="7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc" \ ["5.5"]="8d78b2ed63e7f07ad169c1186d119761c4773e681f332cfe1901045b1b0141bc" \ ["5.5.1"]="222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00" \ + ["5.6"]="15c02ef5dd3631ec02ac52e8725703e0285d9a7eecbf4e5939aa9e924604d01d" \ ) [ ! ${gradle_hashes[$1]+abc} ] && exit 1 echo "${gradle_hashes["$1"]}" @@ -143,7 +144,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index fc4541ce..ef80daee 100755 --- a/makebuildserver +++ b/makebuildserver @@ -354,6 +354,8 @@ CACHE_FILES = [ '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc'), ('https://services.gradle.org/distributions/gradle-5.5.1-bin.zip', '222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00'), + ('https://services.gradle.org/distributions/gradle-5.6-bin.zip', + '15c02ef5dd3631ec02ac52e8725703e0285d9a7eecbf4e5939aa9e924604d01d'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 2f07bafbedc2a13e2403c21453144be6f5e0e35e Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Mon, 26 Aug 2019 09:46:35 +0000 Subject: [PATCH 0111/2775] Add platform 29 & buildtools --- makebuildserver | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/makebuildserver b/makebuildserver index fc4541ce..09a27138 100755 --- a/makebuildserver +++ b/makebuildserver @@ -198,6 +198,8 @@ CACHE_FILES = [ '020c4c090bc82ce87ebaae5d1a922e21b39a1d03c78ffa43f0c3e42fc7d28169'), ('https://dl.google.com/android/repository/platform-28_r06.zip', '8452dbbf9668a428abb243c4f02a943b7aa83af3cca627629a15c4c09f28e7bd'), + ('https://dl.google.com/android/repository/platform-29_r02.zip', + 'de5b5a88e3ba94e3d83972ffe6d0b7f97088998f84a3c1b7c0848aa7951ac7f4'), ('https://dl.google.com/android/repository/build-tools_r19.1-linux.zip', '3833b409f78c002a83244e220be380ea6fa44d604e0d47de4b7e5daefe7cd3f4'), ('https://dl.google.com/android/repository/build-tools_r20-linux.zip', @@ -252,6 +254,8 @@ CACHE_FILES = [ '12cebcafd8f30119c7ef53ffb3562a5b5b9f776c9399038587c18df44ea6452b'), ('https://dl.google.com/android/repository/build-tools_r28.0.3-linux.zip', '7954956a40633c88f693d638cbc23f68e9e2499dc7a4b7dfdaf6a3e91387749a'), + ('https://dl.google.com/android/repository/build-tools_r29.0.2-linux.zip', + '1e9393cbfd4a4b82e30e7f55ab38db4a5a3259db93d5821c63597bc74522fa08'), ('https://services.gradle.org/distributions/gradle-2.2.1-bin.zip', '420aa50738299327b611c10b8304b749e8d3a579407ee9e755b15921d95ff418'), ('https://services.gradle.org/distributions/gradle-2.3-bin.zip', From aa18746cc4071ddba94432a1b64ec7a129026c9e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 26 Aug 2019 14:58:38 +0200 Subject: [PATCH 0112/2775] bump to version v1.1.5 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 68d897f9..9f81aaa9 100755 --- a/setup.py +++ b/setup.py @@ -52,7 +52,7 @@ with open("README.md", "r") as fh: long_description = fh.read() setup(name='fdroidserver', - version='1.1.4', + version='1.1.5', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From 08acb5589757d7e266210755e59c96bc4c1052f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 22 Jul 2019 19:49:28 +0200 Subject: [PATCH 0113/2775] keep yaml metadata when rewrite failed --- fdroidserver/metadata.py | 14 +++++--------- fdroidserver/rewritemeta.py | 12 ++++++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 17a3e739..33c2f5af 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -1584,15 +1584,11 @@ def write_metadata(metadatapath, app): warn_or_exception(_('Cannot write "{path}", not an accepted format, use: {formats}') .format(path=metadatapath, formats=', '.join(accepted))) - try: - with open(metadatapath, 'w') as mf: - if ext == 'txt': - return write_txt(mf, app) - elif ext == 'yml': - return write_yaml(mf, app) - except FDroidException as e: - os.remove(metadatapath) - raise e + with open(metadatapath, 'w') as mf: + if ext == 'txt': + return write_txt(mf, app) + elif ext == 'yml': + return write_yaml(mf, app) warn_or_exception(_('Unknown metadata format: %s') % metadatapath) diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 07fb7492..0cc5c416 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -108,10 +108,14 @@ def main(): newbuilds.append(new) app.builds = newbuilds - metadata.write_metadata(base + '.' + to_ext, app) - - if ext != to_ext: - os.remove(path) + try: + metadata.write_metadata(base + '.' + to_ext, app) + # remove old format metadata if there was a format change + # and rewriting to the new format worked + if ext != to_ext: + os.remove(path) + finally: + pass logging.debug(_("Finished")) From 902f1307dc0c5ae0ef5b829da19bc70e74ae4592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 24 Jul 2019 16:54:15 +0200 Subject: [PATCH 0114/2775] rewritemeta: refactor supported list to module variable SUPPORTED_FORMATS --- fdroidserver/rewritemeta.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 0cc5c416..97d15852 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -30,6 +30,9 @@ config = None options = None +SUPPORTED_FORMATS = ['txt', 'yml'] + + def proper_format(app): s = io.StringIO() # TODO: currently reading entire file again, should reuse first @@ -50,15 +53,13 @@ def main(): global config, options - supported = ['txt', 'yml'] - # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] [APPID [APPID ...]]") common.setup_global_opts(parser) parser.add_argument("-l", "--list", action="store_true", default=False, help=_("List files that would be reformatted")) parser.add_argument("-t", "--to", default=None, - help=_("Rewrite to a specific format: ") + ', '.join(supported)) + help=_("Rewrite to a specific format: ") + ', '.join(SUPPORTED_FORMATS)) parser.add_argument("appid", nargs='*', help=_("applicationId in the form APPID")) metadata.add_metadata_arguments(parser) options = parser.parse_args() @@ -73,14 +74,14 @@ def main(): if options.list and options.to is not None: 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_FORMATS: parser.error(_("Unsupported metadata format, use: --to [{supported}]") - .format(supported=' '.join(supported))) + .format(supported=' '.join(SUPPORTED_FORMATS))) for appid, app in apps.items(): path = app.metadatapath base, ext = common.get_extension(path) - if not options.to and ext not in supported: + if not options.to and ext not in SUPPORTED_FORMATS: logging.info(_("Ignoring {ext} file at '{path}'").format(ext=ext, path=path)) continue elif options.to is not None: From 3951d93196ab0cf5cb893c1b2abd173f18e5d734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 25 Jul 2019 02:26:43 +0200 Subject: [PATCH 0115/2775] add rewritemeta.TestCase --- tests/rewritemeta.TestCase | 152 +++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100755 tests/rewritemeta.TestCase diff --git a/tests/rewritemeta.TestCase b/tests/rewritemeta.TestCase new file mode 100755 index 00000000..c8b4b236 --- /dev/null +++ b/tests/rewritemeta.TestCase @@ -0,0 +1,152 @@ +#!/usr/bin/env python3 + +# +# command which created the keystore used in this test case: +# +# $ for ALIAS in 'repokey a163ec9b d2d51ff2 dc3b169e 78688a0f'; \ +# do keytool -genkey -keystore dummy-keystore.jks \ +# -alias $ALIAS -keyalg 'RSA' -keysize '2048' \ +# -validity '10000' -storepass 123456 \ +# -keypass 123456 -dname 'CN=test, OU=F-Droid'; done +# + +import inspect +import logging +import optparse +import os +import sys +import unittest +import tempfile +import textwrap +from unittest import mock +from testcommon import TmpCwd + +localmodule = os.path.realpath( + os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) +print('localmodule: ' + localmodule) +if localmodule not in sys.path: + sys.path.insert(0, localmodule) + +from fdroidserver import common +from fdroidserver import rewritemeta +from fdroidserver.exception import FDroidException + + +class RewriteMetaTest(unittest.TestCase): + '''fdroidserver/publish.py''' + + def setUp(self): + logging.basicConfig(level=logging.DEBUG) + self.basedir = os.path.join(localmodule, 'tests') + self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) + if not os.path.exists(self.tmpdir): + os.makedirs(self.tmpdir) + os.chdir(self.basedir) + + def test_rewrite_scenario_trivial(self): + + sys.argv.append('a') + sys.argv.append('b') + + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir('metadata') + with open('metadata/a.txt', 'w') as f: + f.write('Auto Name:a') + with open('metadata/b.yml', 'w') as f: + f.write('AutoName: b') + + rewritemeta.main() + + with open('metadata/a.txt') as f: + self.assertEqual(f.read(), textwrap.dedent('''\ + Categories: + License:Unknown + Web Site: + Source Code: + Issue Tracker: + + Auto Name:a + + Auto Update Mode:None + Update Check Mode:None + ''')) + + with open('metadata/b.yml') as f: + self.assertEqual(f.read(), textwrap.dedent('''\ + License: Unknown + + AutoName: b + + AutoUpdateMode: None + UpdateCheckMode: None + ''')) + + # cleanup argv + sys.argv.remove('b') + sys.argv.remove('a') + + def test_rewrite_scenario_txt_to_yml(self): + + sys.argv.append('--to') + sys.argv.append('yml') + sys.argv.append('a') + + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir('metadata') + with open('metadata/a.txt', 'w') as f: + f.write('Auto Name:a') + + rewritemeta.main() + + with open('metadata/a.yml') as f: + self.assertEqual(f.read(), textwrap.dedent('''\ + License: Unknown + + AutoName: a + + AutoUpdateMode: None + UpdateCheckMode: None + ''')) + + sys.argv.remove('a') + sys.argv.remove('yml') + sys.argv.remove('--to') + + def test_rewrite_scenario_txt_to_yml_no_ruamel(self): + + sys.argv.append('--to') + sys.argv.append('yml') + sys.argv.append('a') + + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir('metadata') + with open('metadata/a.txt', 'w') as f: + f.write('Auto Name:a') + + def boom(mf, app): + raise FDroidException() + + with mock.patch('fdroidserver.metadata.write_yaml', boom): + with self.assertRaises(FDroidException): + rewritemeta.main() + + with open('metadata/a.txt') as f: + self.assertEqual(f.read(), textwrap.dedent('''\ + Auto Name:a''')) + + sys.argv.remove('a') + sys.argv.remove('yml') + sys.argv.remove('--to') + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + + parser = optparse.OptionParser() + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="Spew out even more information than normal") + (common.options, args) = parser.parse_args(['--verbose']) + + newSuite = unittest.TestSuite() + newSuite.addTest(unittest.makeSuite(RewriteMetaTest)) + unittest.main(failfast=False) From 0885303672e2beb4adc5a9fc56bd5a05d1711cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 26 Jul 2019 14:07:22 +0200 Subject: [PATCH 0116/2775] add additional rewritemeta test for yml --- tests/rewritemeta.TestCase | 39 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/tests/rewritemeta.TestCase b/tests/rewritemeta.TestCase index c8b4b236..128c3d9d 100755 --- a/tests/rewritemeta.TestCase +++ b/tests/rewritemeta.TestCase @@ -45,8 +45,7 @@ class RewriteMetaTest(unittest.TestCase): def test_rewrite_scenario_trivial(self): - sys.argv.append('a') - sys.argv.append('b') + sys.argv = ['rewritemeta', 'a', 'b'] with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): os.mkdir('metadata') @@ -81,15 +80,9 @@ class RewriteMetaTest(unittest.TestCase): UpdateCheckMode: None ''')) - # cleanup argv - sys.argv.remove('b') - sys.argv.remove('a') - def test_rewrite_scenario_txt_to_yml(self): - sys.argv.append('--to') - sys.argv.append('yml') - sys.argv.append('a') + sys.argv = ['rewritemeta', '--to', 'yml', 'a'] with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): os.mkdir('metadata') @@ -108,15 +101,9 @@ class RewriteMetaTest(unittest.TestCase): UpdateCheckMode: None ''')) - sys.argv.remove('a') - sys.argv.remove('yml') - sys.argv.remove('--to') - def test_rewrite_scenario_txt_to_yml_no_ruamel(self): - sys.argv.append('--to') - sys.argv.append('yml') - sys.argv.append('a') + sys.argv = ['rewritemeta', '--to', 'yml', 'a'] with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): os.mkdir('metadata') @@ -134,9 +121,23 @@ class RewriteMetaTest(unittest.TestCase): self.assertEqual(f.read(), textwrap.dedent('''\ Auto Name:a''')) - sys.argv.remove('a') - sys.argv.remove('yml') - sys.argv.remove('--to') + def test_rewrite_scenario_yml_no_ruamel(self): + sys.argv = ['rewritemeta', 'a'] + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir('metadata') + with open('metadata/a.yml', 'w') as f: + f.write('AutoName: a') + + def boom(mf, app): + raise FDroidException() + + with mock.patch('fdroidserver.metadata.write_yaml', boom): + with self.assertRaises(FDroidException): + rewritemeta.main() + + with open('metadata/a.yml') as f: + self.assertEqual(f.read(), textwrap.dedent('''\ + AutoName: a''')) if __name__ == "__main__": From 8e5232076f049170ce9698a2739c2d9f3430997e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 29 Jul 2019 17:39:51 +0200 Subject: [PATCH 0117/2775] do not delete yml metadata when raumel not installed --- fdroidserver/metadata.py | 13 +++++++++---- tests/rewritemeta.TestCase | 10 +++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 33c2f5af..d34b824e 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -27,6 +27,7 @@ import logging import textwrap import io import yaml +import importlib from collections import OrderedDict import fdroidserver.common @@ -1584,11 +1585,15 @@ def write_metadata(metadatapath, app): warn_or_exception(_('Cannot write "{path}", not an accepted format, use: {formats}') .format(path=metadatapath, formats=', '.join(accepted))) - with open(metadatapath, 'w') as mf: - if ext == 'txt': + if ext == 'txt': + with open(metadatapath, 'w') as mf: return write_txt(mf, app) - elif ext == 'yml': - return write_yaml(mf, app) + elif ext == 'yml': + if importlib.util.find_spec('ruamel.yaml'): + with open(metadatapath, 'w') as mf: + return write_yaml(mf, app) + else: + raise FDroidException('ruamel.yaml not installed, can not write metadata.') warn_or_exception(_('Unknown metadata format: %s') % metadatapath) diff --git a/tests/rewritemeta.TestCase b/tests/rewritemeta.TestCase index 128c3d9d..664f3c78 100755 --- a/tests/rewritemeta.TestCase +++ b/tests/rewritemeta.TestCase @@ -110,8 +110,8 @@ class RewriteMetaTest(unittest.TestCase): with open('metadata/a.txt', 'w') as f: f.write('Auto Name:a') - def boom(mf, app): - raise FDroidException() + def boom(*args): + raise FDroidException(' '.join((str(x) for x in args))) with mock.patch('fdroidserver.metadata.write_yaml', boom): with self.assertRaises(FDroidException): @@ -128,10 +128,10 @@ class RewriteMetaTest(unittest.TestCase): with open('metadata/a.yml', 'w') as f: f.write('AutoName: a') - def boom(mf, app): - raise FDroidException() + def boom(*args): + raise FDroidException(' '.join((str(x) for x in args))) - with mock.patch('fdroidserver.metadata.write_yaml', boom): + with mock.patch('importlib.util.find_spec', boom): with self.assertRaises(FDroidException): rewritemeta.main() From 9cb43f44b939528fca97b0eafe9b7dfb680a01b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 27 Aug 2019 15:43:20 +0200 Subject: [PATCH 0118/2775] add changelog entry for !658 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3deb6e79..a486c5f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * checkupdates: UpdateCheckIngore gets properly observed now ([!659](https://gitlab.com/fdroid/fdroidserver/merge_requests/659), [!660](https://gitlab.com/fdroid/fdroidserver/merge_requests/660)) +* keep yaml metadata when rewrite failed + ([!658](https://gitlab.com/fdroid/fdroidserver/merge_requests/658)) * import: `template.yml` now supports omitting values ([!657](https://gitlab.com/fdroid/fdroidserver/merge_requests/657)) * build: deploying buildlogs with rsync From f13c41e3ba60349ad18a3422005ab9d9f90ec169 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 28 Aug 2019 15:57:29 +0200 Subject: [PATCH 0119/2775] update: remove Provides: from template.yml test case !654 dcf3837bcbebd0f1d0e77f942c0d867162e3dc71 --- tests/update.TestCase | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/update.TestCase b/tests/update.TestCase index 028d7c43..1baa141e 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -842,7 +842,6 @@ class UpdateTest(unittest.TestCase): with open('template.yml', 'w') as f: f.write(textwrap.dedent('''\ Disabled: - Provides: License: AuthorName: AuthorEmail: @@ -902,7 +901,6 @@ class UpdateTest(unittest.TestCase): 'Litecoin': '', 'Name': 'rocks.janicerand', 'NoSourceSince': '', - 'Provides': '', 'Repo': '', 'RepoType': '', 'RequiresRoot': '', From ce54dbfc11969af7bdf51f9b28687a123db475fb Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 15 Aug 2019 12:19:29 +0200 Subject: [PATCH 0120/2775] setup.py: use officially documented way of including README https://packaging.python.org/tutorials/packaging-projects/ --- setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1f51e157..c255f64e 100755 --- a/setup.py +++ b/setup.py @@ -49,10 +49,14 @@ def get_data_files(): return data_files +with open("README.md", "r") as fh: + long_description = fh.read() + + setup(name='fdroidserver', version='1.2a', description='F-Droid Server Tools', - long_description='README.md', + long_description=long_description, long_description_content_type='text/markdown', author='The F-Droid Project', author_email='team@f-droid.org', From fbdecbceb7caf50fe3335eb599180b2df1e690ec Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 21 Aug 2019 14:40:41 +0200 Subject: [PATCH 0121/2775] setup.py: ruamel.yaml >= 0.15 required for yml rewrites --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c255f64e..f38759dc 100755 --- a/setup.py +++ b/setup.py @@ -84,7 +84,7 @@ setup(name='fdroidserver', 'python-vagrant', 'PyYAML', 'qrcode', - 'ruamel.yaml >= 0.13', + 'ruamel.yaml >= 0.15', 'requests >= 2.5.2, != 2.11.0, != 2.12.2, != 2.18.0', 'docker-py >= 1.9, < 2.0', ], From 508af00e84e3d48aa9f0f018451867eba2336726 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 28 Aug 2019 12:25:53 +0200 Subject: [PATCH 0122/2775] update: only copy graphics and screenshots if mtime/size has changed Instead of copying every time, trust the filesystem to tell us when the file has changed. --- .gitignore | 1 + fdroidserver/update.py | 38 +++++++++++++++++++++++++++----------- tests/update.TestCase | 7 +++++++ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 461fe410..73a13d4c 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ makebuildserver.config.py /tests/archive/index.xml /tests/archive/index-v1.jar /tests/archive/index-v1.json +/tests/metadata/org.videolan.vlc/en-US/icon*.png /tests/repo/index.jar /tests/repo/index_unsigned.jar /tests/repo/index-v1.jar diff --git a/fdroidserver/update.py b/fdroidserver/update.py index f7440786..ce8ab0f4 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -707,33 +707,52 @@ def _set_author_entry(app, key, f): app[key] = text -def _strip_and_copy_image(inpath, outpath): +def _strip_and_copy_image(in_file, outpath): """Remove any metadata from image and copy it to new path Sadly, image metadata like EXIF can be used to exploit devices. It is not used at all in the F-Droid ecosystem, so its much safer just to remove it entirely. - """ + This uses size+mtime to check for a new file since this process + actually modifies the resulting file to strip out the EXIF. + + outpath can be path to either a file or dir. The dir that outpath + refers to must exist before calling this. + + """ + logging.debug('copying ' + in_file + ' ' + outpath) - extension = common.get_extension(inpath)[1] if os.path.isdir(outpath): - outpath = os.path.join(outpath, os.path.basename(inpath)) + out_file = os.path.join(outpath, os.path.basename(in_file)) + else: + out_file = outpath + + if os.path.exists(out_file): + in_stat = os.stat(in_file) + out_stat = os.stat(out_file) + if in_stat.st_size == out_stat.st_size \ + and in_stat.st_mtime == out_stat.st_mtime: + return + + extension = common.get_extension(in_file)[1] if extension == 'png': - with open(inpath, 'rb') as fp: + with open(in_file, 'rb') as fp: in_image = Image.open(fp) - in_image.save(outpath, "PNG", optimize=True, + in_image.save(out_file, "PNG", optimize=True, pnginfo=BLANK_PNG_INFO, icc_profile=None) elif extension == 'jpg' or extension == 'jpeg': - with open(inpath, 'rb') as fp: + with open(in_file, 'rb') as fp: in_image = Image.open(fp) data = list(in_image.getdata()) out_image = Image.new(in_image.mode, in_image.size) out_image.putdata(data) - out_image.save(outpath, "JPEG", optimize=True) + out_image.save(out_file, "JPEG", optimize=True) else: raise FDroidException(_('Unsupported file type "{extension}" for repo graphic') .format(extension=extension)) + stat_result = os.stat(in_file) + os.utime(out_file, times=(stat_result.st_atime, stat_result.st_mtime)) def copy_triple_t_store_metadata(apps): @@ -845,7 +864,6 @@ def copy_triple_t_store_metadata(apps): os.makedirs(destdir, mode=0o755, exist_ok=True) sourcefile = os.path.join(root, f) destfile = os.path.join(destdir, repofilename) - logging.debug('copying ' + sourcefile + ' ' + destfile) _strip_and_copy_image(sourcefile, destfile) @@ -934,7 +952,6 @@ def insert_localized_app_metadata(apps): destdir = os.path.join('repo', packageName, locale) if base in GRAPHIC_NAMES and extension in ALLOWED_EXTENSIONS: os.makedirs(destdir, mode=0o755, exist_ok=True) - logging.debug('copying ' + os.path.join(root, f) + ' ' + destdir) _strip_and_copy_image(os.path.join(root, f), destdir) for d in dirs: if d in SCREENSHOT_DIRS: @@ -946,7 +963,6 @@ def insert_localized_app_metadata(apps): if extension in ALLOWED_EXTENSIONS: screenshotdestdir = os.path.join(destdir, d) os.makedirs(screenshotdestdir, mode=0o755, exist_ok=True) - logging.debug('copying ' + f + ' ' + screenshotdestdir) _strip_and_copy_image(f, screenshotdestdir) repofiles = sorted(glob.glob(os.path.join('repo', '[A-Za-z]*', '[a-z][a-z]*'))) diff --git a/tests/update.TestCase b/tests/update.TestCase index 1baa141e..454780c8 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -66,6 +66,13 @@ class UpdateTest(unittest.TestCase): shutil.copytree(os.path.join('source-files', 'eu.siacs.conversations'), os.path.join('build', 'eu.siacs.conversations')) + testfile = os.path.join('repo', 'org.videolan.vlc', 'en-US', 'icon.png') + cpdir = os.path.join('metadata', 'org.videolan.vlc', 'en-US') + cpfile = os.path.join(cpdir, 'icon.png') + os.makedirs(cpdir, exist_ok=True) + shutil.copy(testfile, cpfile) + shutil.copystat(testfile, cpfile) + apps = dict() for packageName in ('info.guardianproject.urzip', 'org.videolan.vlc', 'obb.mainpatch.current', 'com.nextcloud.client', 'com.nextcloud.client.dev', From 70e7e720b9c2f3cbcf3ae44105abf613fd96767d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 28 Aug 2019 13:42:40 +0200 Subject: [PATCH 0123/2775] update: use graphics filename with hash in index to support caching Using a filename based on the hash of the contents means that the caching algorithms for fdroidclient and browsers can safely cache the file forever using the filename, since this guarantees that the contents will never change for a given filename. This does not cover screenshots, only icon.png, featureGraphic.png, tvBanner.png, and promoGraphic.png. fdroidserver#689 fdroid-website!453 --- .gitignore | 3 +++ CHANGELOG.md | 2 ++ fdroidserver/update.py | 42 ++++++++++++++++++++++++++++++++++++---- tests/repo/index-v1.json | 8 ++++---- tests/update.TestCase | 25 ++++++++++++++++-------- 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 73a13d4c..25aab3b3 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,9 @@ makebuildserver.config.py /tests/repo/info.guardianproject.urzip/ /tests/repo/info.guardianproject.checkey/en-US/phoneScreenshots/checkey-phone.png /tests/repo/info.guardianproject.checkey/en-US/phoneScreenshots/checkey.png +/tests/repo/obb.mainpatch.current/en-US/featureGraphic_ffhLaojxbGAfu9ROe1MJgK5ux8d0OVc6b65nmvOBaTk=.png +/tests/repo/obb.mainpatch.current/en-US/icon_WI0pkO3LsklrsTAnRr-OQSxkkoMY41lYe2-fAvXLiLg=.png +/tests/repo/org.videolan.vlc/en-US/icon_yAfSvPRJukZzMMfUzvbYqwaD1XmHXNtiPBtuPVHW-6s=.png /tests/urzip-πÇÇπÇÇ现代汉语通用字-български-عربي1234.apk /unsigned/ diff --git a/CHANGELOG.md b/CHANGELOG.md index a486c5f8..20f0e850 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ([!663](https://gitlab.com/fdroid/fdroidserver/merge_requests/663)) * added support for gradle 5.5.1 ([!656](https://gitlab.com/fdroid/fdroidserver/merge_requests/656)) +* add SHA256 to filename of repo graphics + ([!669](https://gitlab.com/fdroid/fdroidserver/merge_requests/669)) ### Fixed * checkupdates: UpdateCheckIngore gets properly observed now diff --git a/fdroidserver/update.py b/fdroidserver/update.py index ce8ab0f4..d1dd11bf 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -34,6 +34,7 @@ import time import copy from datetime import datetime from argparse import ArgumentParser +from base64 import urlsafe_b64encode import collections from binascii import hexlify @@ -522,6 +523,18 @@ def sha256sum(filename): return sha.hexdigest() +def sha256base64(filename): + '''Calculate the sha256 of the given file as URL-safe base64''' + hasher = hashlib.sha256() + with open(filename, 'rb') as f: + while True: + t = f.read(16384) + if len(t) == 0: + break + hasher.update(t) + return urlsafe_b64encode(hasher.digest()).decode() + + def has_known_vulnerability(filename): """checks for known vulnerabilities in the APK @@ -755,6 +768,16 @@ def _strip_and_copy_image(in_file, outpath): os.utime(out_file, times=(stat_result.st_atime, stat_result.st_mtime)) +def _get_base_hash_extension(f): + '''split a graphic/screenshot filename into base, sha256, and extension + ''' + base, extension = common.get_extension(f) + sha256_index = base.find('_') + if sha256_index > 0: + return base[:sha256_index], base[sha256_index + 1:], extension + return base, None, extension + + def copy_triple_t_store_metadata(apps): """Include store metadata from the app's source repo @@ -965,8 +988,8 @@ def insert_localized_app_metadata(apps): os.makedirs(screenshotdestdir, mode=0o755, exist_ok=True) _strip_and_copy_image(f, screenshotdestdir) - repofiles = sorted(glob.glob(os.path.join('repo', '[A-Za-z]*', '[a-z][a-z]*'))) - for d in repofiles: + repodirs = sorted(glob.glob(os.path.join('repo', '[A-Za-z]*', '[a-z][a-z]*'))) + for d in repodirs: if not os.path.isdir(d): continue for f in sorted(glob.glob(os.path.join(d, '*.*')) + glob.glob(os.path.join(d, '*Screenshots', '*.*'))): @@ -977,7 +1000,7 @@ def insert_localized_app_metadata(apps): locale = segments[2] screenshotdir = segments[3] filename = os.path.basename(f) - base, extension = common.get_extension(filename) + base, sha256, extension = _get_base_hash_extension(filename) if packageName not in apps: logging.warning(_('Found "{path}" graphic without metadata for app "{name}"!') @@ -989,7 +1012,18 @@ def insert_localized_app_metadata(apps): logging.warning(_('Only PNG and JPEG are supported for graphics, found: {path}').format(path=f)) elif base in GRAPHIC_NAMES: # there can only be zero or one of these per locale - graphics[base] = filename + basename = base + '.' + extension + basepath = os.path.join(os.path.dirname(f), basename) + if sha256: + if not os.path.samefile(f, basepath): + os.unlink(f) + else: + sha256 = sha256base64(f) + filename = base + '_' + sha256 + '.' + extension + index_file = os.path.join(os.path.dirname(f), filename) + if not os.path.exists(index_file): + os.link(f, index_file, follow_symlinks=False) + graphics[base] = filename elif screenshotdir in SCREENSHOT_DIRS: # there can any number of these per locale logging.debug(_('adding to {name}: {path}').format(name=screenshotdir, path=f)) diff --git a/tests/repo/index-v1.json b/tests/repo/index-v1.json index a5a1d1e9..492b6051 100644 --- a/tests/repo/index-v1.json +++ b/tests/repo/index-v1.json @@ -141,8 +141,8 @@ "lastUpdated": 1496275200000, "localized": { "en-US": { - "featureGraphic": "featureGraphic.png", - "icon": "icon.png", + "featureGraphic": "featureGraphic_ffhLaojxbGAfu9ROe1MJgK5ux8d0OVc6b65nmvOBaTk=.png", + "icon": "icon_WI0pkO3LsklrsTAnRr-OQSxkkoMY41lYe2-fAvXLiLg=.png", "phoneScreenshots": [ "screenshot-main.png" ], @@ -196,8 +196,8 @@ "localized": { "en-US": { "description": "full description\n", - "featureGraphic": "featureGraphic.png", - "icon": "icon.png", + "featureGraphic": "featureGraphic_GFRT5BovZsENGpJq1HqPODGWBRPWQsx25B95Ol5w_wU=.png", + "icon": "icon_NJXNzMcyf-v9i5a1ElJi0j9X1LvllibCa48xXYPlOqQ=.png", "name": "title\n", "summary": "short description\n", "video": "video\n" diff --git a/tests/update.TestCase b/tests/update.TestCase index 454780c8..fc5f69bb 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -66,9 +66,10 @@ class UpdateTest(unittest.TestCase): shutil.copytree(os.path.join('source-files', 'eu.siacs.conversations'), os.path.join('build', 'eu.siacs.conversations')) + testfilename = 'icon_yAfSvPRJukZzMMfUzvbYqwaD1XmHXNtiPBtuPVHW-6s=.png' testfile = os.path.join('repo', 'org.videolan.vlc', 'en-US', 'icon.png') cpdir = os.path.join('metadata', 'org.videolan.vlc', 'en-US') - cpfile = os.path.join(cpdir, 'icon.png') + cpfile = os.path.join(cpdir, testfilename) os.makedirs(cpdir, exist_ok=True) shutil.copy(testfile, cpfile) shutil.copystat(testfile, cpfile) @@ -98,8 +99,12 @@ class UpdateTest(unittest.TestCase): fdroidserver.update.insert_localized_app_metadata(apps) appdir = os.path.join('repo', 'info.guardianproject.urzip', 'en-US') - self.assertTrue(os.path.isfile(os.path.join(appdir, 'icon.png'))) - self.assertTrue(os.path.isfile(os.path.join(appdir, 'featureGraphic.png'))) + self.assertTrue(os.path.isfile(os.path.join( + appdir, + 'icon_NJXNzMcyf-v9i5a1ElJi0j9X1LvllibCa48xXYPlOqQ=.png'))) + self.assertTrue(os.path.isfile(os.path.join( + appdir, + 'featureGraphic_GFRT5BovZsENGpJq1HqPODGWBRPWQsx25B95Ol5w_wU=.png'))) self.assertEqual(6, len(apps)) for packageName, app in apps.items(): @@ -112,16 +117,20 @@ class UpdateTest(unittest.TestCase): self.assertEqual('title\n', app['localized']['en-US']['name']) self.assertEqual('short description\n', app['localized']['en-US']['summary']) self.assertEqual('video\n', app['localized']['en-US']['video']) - self.assertEqual('icon.png', app['localized']['en-US']['icon']) - self.assertEqual('featureGraphic.png', app['localized']['en-US']['featureGraphic']) + self.assertEqual('icon_NJXNzMcyf-v9i5a1ElJi0j9X1LvllibCa48xXYPlOqQ=.png', + app['localized']['en-US']['icon']) + self.assertEqual('featureGraphic_GFRT5BovZsENGpJq1HqPODGWBRPWQsx25B95Ol5w_wU=.png', + app['localized']['en-US']['featureGraphic']) self.assertEqual('100\n', app['localized']['en-US']['whatsNew']) elif packageName == 'org.videolan.vlc': - self.assertEqual('icon.png', app['localized']['en-US']['icon']) + self.assertEqual(testfilename, app['localized']['en-US']['icon']) self.assertEqual(9, len(app['localized']['en-US']['phoneScreenshots'])) self.assertEqual(15, len(app['localized']['en-US']['sevenInchScreenshots'])) elif packageName == 'obb.mainpatch.current': - self.assertEqual('icon.png', app['localized']['en-US']['icon']) - self.assertEqual('featureGraphic.png', app['localized']['en-US']['featureGraphic']) + self.assertEqual('icon_WI0pkO3LsklrsTAnRr-OQSxkkoMY41lYe2-fAvXLiLg=.png', + app['localized']['en-US']['icon']) + self.assertEqual('featureGraphic_ffhLaojxbGAfu9ROe1MJgK5ux8d0OVc6b65nmvOBaTk=.png', + app['localized']['en-US']['featureGraphic']) self.assertEqual(1, len(app['localized']['en-US']['phoneScreenshots'])) self.assertEqual(1, len(app['localized']['en-US']['sevenInchScreenshots'])) elif packageName == 'com.nextcloud.client': From 1d5e2417769b799d7ffea8c0ea3945041f35d4af Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 15 Aug 2019 12:22:17 +0200 Subject: [PATCH 0124/2775] add donation links to GitHub FUNDING.yml https://github.blog/2019-05-23-announcing-github-sponsors-a-new-way-to-contribute-to-open-source/ fdroiddata!5041 --- FUNDING.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 FUNDING.yml diff --git a/FUNDING.yml b/FUNDING.yml new file mode 100644 index 00000000..75bb9109 --- /dev/null +++ b/FUNDING.yml @@ -0,0 +1,8 @@ +--- +liberapay: F-Droid-Data +github: + - eighthave +custom: + - https://f-droid.org/about/ + - https://www.hellotux.com/f-droid + - https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=E2FCXCT6837GL From c7cd73183376e0f976a700542420d0bbb3a6ebe9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 29 Aug 2019 10:04:10 +0200 Subject: [PATCH 0125/2775] add Tidelift link to FUNDING.yml [skip ci] --- FUNDING.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/FUNDING.yml b/FUNDING.yml index 75bb9109..83d4c2b7 100644 --- a/FUNDING.yml +++ b/FUNDING.yml @@ -2,6 +2,7 @@ liberapay: F-Droid-Data github: - eighthave +tidelift: pypi/fdroidserver custom: - https://f-droid.org/about/ - https://www.hellotux.com/f-droid From 3a7ad650e311033915db3353227d2b506ea8b642 Mon Sep 17 00:00:00 2001 From: relan Date: Thu, 29 Aug 2019 21:16:17 +0300 Subject: [PATCH 0126/2775] scanner: fix local Debian Maven repo handling The resulting regex was 'https?://file:///usr/share/maven-repo' causing scanner error. --- fdroidserver/scanner.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 866b8032..e4222526 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -110,7 +110,9 @@ def scan_source(build_dir, build=metadata.Build()): 's3.amazonaws.com/repo.commonsware.com', # CommonsWare 'plugins.gradle.org/m2', # Gradle plugin repo 'maven.google.com', # Google Maven Repo, https://developer.android.com/studio/build/dependencies.html#google-maven - 'file:///usr/share/maven-repo', # local repo on Debian installs + ] + ] + [re.compile(r'^file://' + re.escape(repo) + r'/*') for repo in [ + '/usr/share/maven-repo', # local repo on Debian installs ] ] From 079754c56c24c82e9184925602d286acb867bedb Mon Sep 17 00:00:00 2001 From: relan Date: Thu, 29 Aug 2019 21:21:09 +0300 Subject: [PATCH 0127/2775] scanner: add a test for the local Debian Maven repo --- .../info.guardianproject.ripple/build.gradle | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/source-files/info.guardianproject.ripple/build.gradle diff --git a/tests/source-files/info.guardianproject.ripple/build.gradle b/tests/source-files/info.guardianproject.ripple/build.gradle new file mode 100644 index 00000000..5062b208 --- /dev/null +++ b/tests/source-files/info.guardianproject.ripple/build.gradle @@ -0,0 +1,18 @@ +buildscript { + repositories { + maven { url 'file:///usr/share/maven-repo' } + maven { url 'https://maven.google.com' } + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.2.2' + } +} + +allprojects { + repositories { + maven { url 'file:///usr/share/maven-repo' } + maven { url 'https://maven.google.com' } + jcenter() + } +} From 4ec6958e33bc6448a28566081cc4300c3dca4cc6 Mon Sep 17 00:00:00 2001 From: Pablo Castellano Date: Fri, 30 Aug 2019 19:45:23 +0200 Subject: [PATCH 0128/2775] do not crash when returned system encoding is None --- fdroid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroid b/fdroid index b316346a..59fc69a0 100755 --- a/fdroid +++ b/fdroid @@ -137,7 +137,7 @@ def main(): mod = __import__('fdroidserver.' + command, None, None, [command]) system_langcode, system_encoding = locale.getdefaultlocale() - if system_encoding.lower() not in ('utf-8', 'utf8'): + if system_encoding is None or system_encoding.lower() not in ('utf-8', 'utf8'): logging.warn(_("Encoding is set to '{enc}' fdroid might run " "into encoding issues. Please set it to 'UTF-8' " "for best results.".format(enc=system_encoding))) From 79d470934dcf230ca03fff7305d50e364ae52978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 30 Aug 2019 19:08:43 +0000 Subject: [PATCH 0129/2775] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f0e850..4fb6fbf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ([!669](https://gitlab.com/fdroid/fdroidserver/merge_requests/669)) ### Fixed +* do not crash when system encoding can not be retrieved + ([!671](https://gitlab.com/fdroid/fdroidserver/merge_requests/671)) * checkupdates: UpdateCheckIngore gets properly observed now ([!659](https://gitlab.com/fdroid/fdroidserver/merge_requests/659), [!660](https://gitlab.com/fdroid/fdroidserver/merge_requests/660)) From ce5a25811a662d41cf13cf04947b1cd2a1d10b30 Mon Sep 17 00:00:00 2001 From: osscontrib Date: Sun, 8 Sep 2019 23:22:18 -0400 Subject: [PATCH 0130/2775] Add Gradle 5.6.1 and 5.6.2 --- gradlew-fdroid | 4 +++- makebuildserver | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 4d1e453b..d9872bc5 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -123,6 +123,8 @@ get_sha() { ["5.5"]="8d78b2ed63e7f07ad169c1186d119761c4773e681f332cfe1901045b1b0141bc" \ ["5.5.1"]="222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00" \ ["5.6"]="15c02ef5dd3631ec02ac52e8725703e0285d9a7eecbf4e5939aa9e924604d01d" \ + ["5.6.1"]="0986244820e4a35d32d91df2ec4b768b5ba5d6c8246753794f85159f9963ec12" \ + ["5.6.2"]="32fce6628848f799b0ad3205ae8db67d0d828c10ffe62b748a7c0d9f4a5d9ee0" \ ) [ ! ${gradle_hashes[$1]+abc} ] && exit 1 echo "${gradle_hashes["$1"]}" @@ -144,7 +146,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index d0583284..cf689af4 100755 --- a/makebuildserver +++ b/makebuildserver @@ -344,7 +344,7 @@ CACHE_FILES = [ 'b49c6da1b2cb67a0caf6c7480630b51c70a11ca2016ff2f555eaeda863143a29'), ('https://downloads.gradle.org/distributions/gradle-4.10.3-bin.zip', '8626cbf206b4e201ade7b87779090690447054bc93f052954c78480fa6ed186e'), - # Only add the latest point released of gradle to the default install. + # Only add the latest point release of gradle to the default install. # Other versions will be downloaded on demand. ('https://downloads.gradle.org/distributions/gradle-5.0-bin.zip', '6157ac9f3410bc63644625b3b3e9e96c963afd7910ae0697792db57813ee79a6'), @@ -358,8 +358,8 @@ CACHE_FILES = [ '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc'), ('https://services.gradle.org/distributions/gradle-5.5.1-bin.zip', '222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00'), - ('https://services.gradle.org/distributions/gradle-5.6-bin.zip', - '15c02ef5dd3631ec02ac52e8725703e0285d9a7eecbf4e5939aa9e924604d01d'), + ('https://services.gradle.org/distributions/gradle-5.6.2-bin.zip', + '32fce6628848f799b0ad3205ae8db67d0d828c10ffe62b748a7c0d9f4a5d9ee0'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 25548023e064e47a082f7ebcd2da03c4f01de0cf Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 9 Sep 2019 12:09:01 +0200 Subject: [PATCH 0131/2775] gitlab-ci: check gradle checksums against official list --- .gitlab-ci.yml | 18 ++++++++++ tests/gradle-release-checksums.py | 58 +++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100755 tests/gradle-release-checksums.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cbc87721..46ce6d56 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -198,3 +198,21 @@ fedora_latest: - cd tests - su testuser --login --command "cd `pwd`; export ANDROID_HOME=$ANDROID_HOME; fdroid=~testuser/.local/bin/fdroid ./run-tests" + +gradle: + image: alpine:3.7 + variables: + LANG: C.UTF-8 + script: + - apk add --no-cache ca-certificates git python3 + # if this is a merge request fork, then only check if makebuildserver changed + - if [ "$CI_PROJECT_NAMESPACE" != "fdroid" ]; then + git fetch https://gitlab.com/fdroid/fdroidserver.git; + for f in `git diff --name-only --diff-filter=d FETCH_HEAD...HEAD`; do + test "$f" == "makebuildserver" && export CHANGED="yes"; + done; + test -z "$CHANGED" && exit; + fi + - python3 -m ensurepip + - pip3 install beautifulsoup4 requests + - ./tests/gradle-release-checksums.py diff --git a/tests/gradle-release-checksums.py b/tests/gradle-release-checksums.py new file mode 100755 index 00000000..165c56da --- /dev/null +++ b/tests/gradle-release-checksums.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import os +import re +import requests +import sys +from bs4 import BeautifulSoup +from distutils.version import LooseVersion + +while True: + r = requests.get('https://gradle.org/release-checksums/') + if r.status_code == 200: + break + +soup = BeautifulSoup(r.text, 'html.parser') + +version_pat = re.compile(r'[0-9]+(\.[0-9]+)+') + +versions = dict() +for a in soup.find_all('a'): + if a.parent.name != 'p': + continue + name = a.get('name') + if not name: + continue + m = version_pat.search(name) + if m: + ul = a.parent.find_next_sibling('ul') + versions[m.group()] = a.parent.find_next_sibling('ul').find('li').find('code').text.strip() + +errors = 0 +makebuildserver = os.path.join(os.path.dirname(__file__), os.pardir, 'makebuildserver') +with open(makebuildserver) as fp: + contents = fp.read() +to_compile = re.search(r'CACHE_FILES = [^\]]+\]', contents, flags=re.DOTALL | re.MULTILINE).group() +code = compile(to_compile, makebuildserver, 'exec') +config = {} +exec(code, None, config) # nosec this is just a CI script +makebuildserver_versions = [] +for url, checksum in config['CACHE_FILES']: + if 'gradle.org' in url: + m = version_pat.search(url.split('/')[-1]) + if m: + makebuildserver_versions.append(m.group()) + if checksum != versions[m.group()]: + print('ERROR: checksum mismatch:', checksum, versions[m.group()]) + errors += 1 + +# error if makebuildserver is missing the latest version +for version in sorted(versions.keys()): + if version not in makebuildserver_versions \ + and LooseVersion(version) > LooseVersion(sorted(makebuildserver_versions)[-1]): + errors += 1 + print(" ('https://services.gradle.org/distributions/gradle-" + version + "-bin.zip',\n" + " '" + versions[version] + "'),") + +print('makebuildserver has gradle v' + sorted(makebuildserver_versions)[-1]) +sys.exit(errors) From 944046b70b172b787a15743c78e7be94429d1eb3 Mon Sep 17 00:00:00 2001 From: relan Date: Sun, 22 Sep 2019 08:52:01 +0300 Subject: [PATCH 0132/2775] gradlew-fdroid: avoid associative arrays macOS is shipped with bash-3.2 that does not support associative arrays. --- gradlew-fdroid | 143 ++++++++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 72 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index d9872bc5..dc60cb1a 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -56,78 +56,77 @@ download_gradle() { } get_sha() { - declare -A gradle_hashes - gradle_hashes=( ["1.4"]="cd99e85fbcd0ae8b99e81c9992a2f10cceb7b5f009c3720ef3a0078f4f92e94e" \ - ["1.6"]="de3e89d2113923dcc2e0def62d69be0947ceac910abd38b75ec333230183fac4" \ - ["1.7"]="360c97d51621b5a1ecf66748c718594e5f790ae4fbc1499543e0c006033c9d30" \ - ["1.8"]="a342bbfa15fd18e2482287da4959588f45a41b60910970a16e6d97959aea5703" \ - ["1.9"]="097ddc2bcbc9da2bb08cbf6bf8079585e35ad088bafd42e8716bc96405db98e9" \ - ["1.10"]="6e6db4fc595f27ceda059d23693b6f6848583950606112b37dfd0e97a0a0a4fe" \ - ["1.11"]="07e235df824964f0e19e73ea2327ce345c44bcd06d44a0123d29ab287fc34091" \ - ["1.12"]="8734b13a401f4311ee418173ed6ca8662d2b0a535be8ff2a43ecb1c13cd406ea" \ - ["2.1"]="3eee4f9ea2ab0221b89f8e4747a96d4554d00ae46d8d633f11cfda60988bf878" \ - ["2.2"]="91e5655fe11ef414449f218c4fa2985b3a49b7903c57556da109c84fa26e1dfb" \ - ["2.2.1"]="420aa50738299327b611c10b8304b749e8d3a579407ee9e755b15921d95ff418" \ - ["2.3"]="010dd9f31849abc3d5644e282943b1c1c355f8e2635c5789833979ce590a3774" \ - ["2.4"]="c4eaecc621a81f567ded1aede4a5ddb281cc02a03a6a87c4f5502add8fc2f16f" \ - ["2.5"]="3f953e0cb14bb3f9ebbe11946e84071547bf5dfd575d90cfe9cc4e788da38555" \ - ["2.6"]="18a98c560af231dfa0d3f8e0802c20103ae986f12428bb0a6f5396e8f14e9c83" \ - ["2.7"]="cde43b90945b5304c43ee36e58aab4cc6fb3a3d5f9bd9449bb1709a68371cb06" \ - ["2.8"]="a88db9c2f104defdaa8011c58cf6cda6c114298ae3695ecfb8beb30da3a903cb" \ - ["2.9"]="c9159ec4362284c0a38d73237e224deae6139cbde0db4f0f44e1c7691dd3de2f" \ - ["2.10"]="66406247f745fc6f05ab382d3f8d3e120c339f34ef54b86f6dc5f6efc18fbb13" \ - ["2.11"]="8d7437082356c9fd6309a4479c8db307673965546daea445c6c72759cd6b1ed6" \ - ["2.12"]="e77064981906cd0476ff1e0de3e6fef747bd18e140960f1915cca8ff6c33ab5c" \ - ["2.13"]="0f665ec6a5a67865faf7ba0d825afb19c26705ea0597cec80dd191b0f2cbb664" \ - ["2.14"]="993b4f33b652c689e9721917d8e021cab6bbd3eae81b39ab2fd46fdb19a928d5" \ - ["2.14.1"]="cfc61eda71f2d12a572822644ce13d2919407595c2aec3e3566d2aab6f97ef39" \ - ["3.0"]="39c906941a474444afbddc38144ed44166825acb0a57b0551dddb04bbf157f80" \ - ["3.1"]="c7de3442432253525902f7e8d7eac8b5fd6ce1623f96d76916af6d0e383010fc" \ - ["3.2"]="5321b36837226dc0377047a328f12010f42c7bf88ee4a3b1cee0c11040082935" \ - ["3.2.1"]="9843a3654d3e57dce54db06d05f18b664b95c22bf90c6becccb61fc63ce60689" \ - ["3.3"]="c58650c278d8cf0696cab65108ae3c8d95eea9c1938e0eb8b997095d5ca9a292" \ - ["3.4"]="72d0cd4dcdd5e3be165eb7cd7bbd25cf8968baf400323d9ab1bba622c3f72205" \ - ["3.4.1"]="db1db193d479cc1202be843f17e4526660cfb0b21b57d62f3a87f88c878af9b2" \ - ["3.5"]="0b7450798c190ff76b9f9a3d02e18b33d94553f708ebc08ebe09bdf99111d110" \ - ["3.5.1"]="8dce35f52d4c7b4a4946df73aa2830e76ba7148850753d8b5e94c5dc325ceef8" \ - ["4.0"]="56bd2dde29ba2a93903c557da1745cafd72cdd8b6b0b83c05a40ed7896b79dfe" \ - ["4.0.1"]="d717e46200d1359893f891dab047fdab98784143ac76861b53c50dbd03b44fd4" \ - ["4.0.2"]="79ac421342bd11f6a4f404e0988baa9c1f5fabf07e3c6fa65b0c15c1c31dda22" \ - ["4.1"]="d55dfa9cfb5a3da86a1c9e75bb0b9507f9a8c8c100793ccec7beb6e259f9ed43" \ - ["4.2"]="515dd63d32e55a9c05667809c5e40a947529de3054444ad274b3b75af5582eae" \ - ["4.2.1"]="b551cc04f2ca51c78dd14edb060621f0e5439bdfafa6fd167032a09ac708fbc0" \ - ["4.3"]="8dcbf44eef92575b475dcb1ce12b5f19d38dc79e84c662670248dc8b8247654c" \ - ["4.3.1"]="15ebe098ce0392a2d06d252bff24143cc88c4e963346582c8d88814758d93ac7" \ - ["4.4"]="fa4873ae2c7f5e8c02ec6948ba95848cedced6134772a0169718eadcb39e0a2f" \ - ["4.4.1"]="e7cf7d1853dfc30c1c44f571d3919eeeedef002823b66b6a988d27e919686389" \ - ["4.5"]="03f2a43a314ff0fb843a85ef68078e06d181c4549c1e5fb983f289382b59b5e3" \ - ["4.5.1"]="3e2ea0d8b96605b7c528768f646e0975bd9822f06df1f04a64fd279b1a17805e" \ - ["4.6"]="98bd5fd2b30e070517e03c51cbb32beee3e2ee1a84003a5a5d748996d4b1b915" \ - ["4.7"]="fca5087dc8b50c64655c000989635664a73b11b9bd3703c7d6cabd31b7dcdb04" \ - ["4.8"]="f3e29692a8faa94eb0b02ebf36fa263a642b3ae8694ef806c45c345b8683f1ba" \ - ["4.8.1"]="af334d994b5e69e439ab55b5d2b7d086da5ea6763d78054f49f147b06370ed71" \ - ["4.9"]="e66e69dce8173dd2004b39ba93586a184628bc6c28461bc771d6835f7f9b0d28" \ - ["4.10"]="248cfd92104ce12c5431ddb8309cf713fe58de8e330c63176543320022f59f18" \ - ["4.10.1"]="e53ce3a01cf016b5d294eef20977ad4e3c13e761ac1e475f1ffad4c6141a92bd" \ - ["4.10.2"]="b49c6da1b2cb67a0caf6c7480630b51c70a11ca2016ff2f555eaeda863143a29" \ - ["4.10.3"]="8626cbf206b4e201ade7b87779090690447054bc93f052954c78480fa6ed186e" \ - ["5.0"]="6157ac9f3410bc63644625b3b3e9e96c963afd7910ae0697792db57813ee79a6" \ - ["5.1"]="7506638a380092a0406364c79d6c87d03d23017fc25a5770379d1ce23c3fcd4d" \ - ["5.1.1"]="4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798" \ - ["5.2"]="ff322863250159595e93b5a4d17a6f0d21c59a1a0497c1e1cf1d53826485503f" \ - ["5.2.1"]="748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357" \ - ["5.3"]="bed2bdd3955be5a09ca7e0201e9d131f194f7f6c466e1795a733733ccfb09f25" \ - ["5.3.1"]="1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436" \ - ["5.4"]="c8c17574245ecee9ed7fe4f6b593b696d1692d1adbfef425bef9b333e3a0e8de" \ - ["5.4.1"]="7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc" \ - ["5.5"]="8d78b2ed63e7f07ad169c1186d119761c4773e681f332cfe1901045b1b0141bc" \ - ["5.5.1"]="222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00" \ - ["5.6"]="15c02ef5dd3631ec02ac52e8725703e0285d9a7eecbf4e5939aa9e924604d01d" \ - ["5.6.1"]="0986244820e4a35d32d91df2ec4b768b5ba5d6c8246753794f85159f9963ec12" \ - ["5.6.2"]="32fce6628848f799b0ad3205ae8db67d0d828c10ffe62b748a7c0d9f4a5d9ee0" \ - ) - [ ! ${gradle_hashes[$1]+abc} ] && exit 1 - echo "${gradle_hashes["$1"]}" + case $1 in + '1.4') echo 'cd99e85fbcd0ae8b99e81c9992a2f10cceb7b5f009c3720ef3a0078f4f92e94e' ;; + '1.6') echo 'de3e89d2113923dcc2e0def62d69be0947ceac910abd38b75ec333230183fac4' ;; + '1.7') echo '360c97d51621b5a1ecf66748c718594e5f790ae4fbc1499543e0c006033c9d30' ;; + '1.8') echo 'a342bbfa15fd18e2482287da4959588f45a41b60910970a16e6d97959aea5703' ;; + '1.9') echo '097ddc2bcbc9da2bb08cbf6bf8079585e35ad088bafd42e8716bc96405db98e9' ;; + '1.10') echo '6e6db4fc595f27ceda059d23693b6f6848583950606112b37dfd0e97a0a0a4fe' ;; + '1.11') echo '07e235df824964f0e19e73ea2327ce345c44bcd06d44a0123d29ab287fc34091' ;; + '1.12') echo '8734b13a401f4311ee418173ed6ca8662d2b0a535be8ff2a43ecb1c13cd406ea' ;; + '2.1') echo '3eee4f9ea2ab0221b89f8e4747a96d4554d00ae46d8d633f11cfda60988bf878' ;; + '2.2') echo '91e5655fe11ef414449f218c4fa2985b3a49b7903c57556da109c84fa26e1dfb' ;; + '2.2.1') echo '420aa50738299327b611c10b8304b749e8d3a579407ee9e755b15921d95ff418' ;; + '2.3') echo '010dd9f31849abc3d5644e282943b1c1c355f8e2635c5789833979ce590a3774' ;; + '2.4') echo 'c4eaecc621a81f567ded1aede4a5ddb281cc02a03a6a87c4f5502add8fc2f16f' ;; + '2.5') echo '3f953e0cb14bb3f9ebbe11946e84071547bf5dfd575d90cfe9cc4e788da38555' ;; + '2.6') echo '18a98c560af231dfa0d3f8e0802c20103ae986f12428bb0a6f5396e8f14e9c83' ;; + '2.7') echo 'cde43b90945b5304c43ee36e58aab4cc6fb3a3d5f9bd9449bb1709a68371cb06' ;; + '2.8') echo 'a88db9c2f104defdaa8011c58cf6cda6c114298ae3695ecfb8beb30da3a903cb' ;; + '2.9') echo 'c9159ec4362284c0a38d73237e224deae6139cbde0db4f0f44e1c7691dd3de2f' ;; + '2.10') echo '66406247f745fc6f05ab382d3f8d3e120c339f34ef54b86f6dc5f6efc18fbb13' ;; + '2.11') echo '8d7437082356c9fd6309a4479c8db307673965546daea445c6c72759cd6b1ed6' ;; + '2.12') echo 'e77064981906cd0476ff1e0de3e6fef747bd18e140960f1915cca8ff6c33ab5c' ;; + '2.13') echo '0f665ec6a5a67865faf7ba0d825afb19c26705ea0597cec80dd191b0f2cbb664' ;; + '2.14') echo '993b4f33b652c689e9721917d8e021cab6bbd3eae81b39ab2fd46fdb19a928d5' ;; + '2.14.1') echo 'cfc61eda71f2d12a572822644ce13d2919407595c2aec3e3566d2aab6f97ef39' ;; + '3.0') echo '39c906941a474444afbddc38144ed44166825acb0a57b0551dddb04bbf157f80' ;; + '3.1') echo 'c7de3442432253525902f7e8d7eac8b5fd6ce1623f96d76916af6d0e383010fc' ;; + '3.2') echo '5321b36837226dc0377047a328f12010f42c7bf88ee4a3b1cee0c11040082935' ;; + '3.2.1') echo '9843a3654d3e57dce54db06d05f18b664b95c22bf90c6becccb61fc63ce60689' ;; + '3.3') echo 'c58650c278d8cf0696cab65108ae3c8d95eea9c1938e0eb8b997095d5ca9a292' ;; + '3.4') echo '72d0cd4dcdd5e3be165eb7cd7bbd25cf8968baf400323d9ab1bba622c3f72205' ;; + '3.4.1') echo 'db1db193d479cc1202be843f17e4526660cfb0b21b57d62f3a87f88c878af9b2' ;; + '3.5') echo '0b7450798c190ff76b9f9a3d02e18b33d94553f708ebc08ebe09bdf99111d110' ;; + '3.5.1') echo '8dce35f52d4c7b4a4946df73aa2830e76ba7148850753d8b5e94c5dc325ceef8' ;; + '4.0') echo '56bd2dde29ba2a93903c557da1745cafd72cdd8b6b0b83c05a40ed7896b79dfe' ;; + '4.0.1') echo 'd717e46200d1359893f891dab047fdab98784143ac76861b53c50dbd03b44fd4' ;; + '4.0.2') echo '79ac421342bd11f6a4f404e0988baa9c1f5fabf07e3c6fa65b0c15c1c31dda22' ;; + '4.1') echo 'd55dfa9cfb5a3da86a1c9e75bb0b9507f9a8c8c100793ccec7beb6e259f9ed43' ;; + '4.2') echo '515dd63d32e55a9c05667809c5e40a947529de3054444ad274b3b75af5582eae' ;; + '4.2.1') echo 'b551cc04f2ca51c78dd14edb060621f0e5439bdfafa6fd167032a09ac708fbc0' ;; + '4.3') echo '8dcbf44eef92575b475dcb1ce12b5f19d38dc79e84c662670248dc8b8247654c' ;; + '4.3.1') echo '15ebe098ce0392a2d06d252bff24143cc88c4e963346582c8d88814758d93ac7' ;; + '4.4') echo 'fa4873ae2c7f5e8c02ec6948ba95848cedced6134772a0169718eadcb39e0a2f' ;; + '4.4.1') echo 'e7cf7d1853dfc30c1c44f571d3919eeeedef002823b66b6a988d27e919686389' ;; + '4.5') echo '03f2a43a314ff0fb843a85ef68078e06d181c4549c1e5fb983f289382b59b5e3' ;; + '4.5.1') echo '3e2ea0d8b96605b7c528768f646e0975bd9822f06df1f04a64fd279b1a17805e' ;; + '4.6') echo '98bd5fd2b30e070517e03c51cbb32beee3e2ee1a84003a5a5d748996d4b1b915' ;; + '4.7') echo 'fca5087dc8b50c64655c000989635664a73b11b9bd3703c7d6cabd31b7dcdb04' ;; + '4.8') echo 'f3e29692a8faa94eb0b02ebf36fa263a642b3ae8694ef806c45c345b8683f1ba' ;; + '4.8.1') echo 'af334d994b5e69e439ab55b5d2b7d086da5ea6763d78054f49f147b06370ed71' ;; + '4.9') echo 'e66e69dce8173dd2004b39ba93586a184628bc6c28461bc771d6835f7f9b0d28' ;; + '4.10') echo '248cfd92104ce12c5431ddb8309cf713fe58de8e330c63176543320022f59f18' ;; + '4.10.1') echo 'e53ce3a01cf016b5d294eef20977ad4e3c13e761ac1e475f1ffad4c6141a92bd' ;; + '4.10.2') echo 'b49c6da1b2cb67a0caf6c7480630b51c70a11ca2016ff2f555eaeda863143a29' ;; + '4.10.3') echo '8626cbf206b4e201ade7b87779090690447054bc93f052954c78480fa6ed186e' ;; + '5.0') echo '6157ac9f3410bc63644625b3b3e9e96c963afd7910ae0697792db57813ee79a6' ;; + '5.1') echo '7506638a380092a0406364c79d6c87d03d23017fc25a5770379d1ce23c3fcd4d' ;; + '5.1.1') echo '4953323605c5d7b89e97d0dc7779e275bccedefcdac090aec123375eae0cc798' ;; + '5.2') echo 'ff322863250159595e93b5a4d17a6f0d21c59a1a0497c1e1cf1d53826485503f' ;; + '5.2.1') echo '748c33ff8d216736723be4037085b8dc342c6a0f309081acf682c9803e407357' ;; + '5.3') echo 'bed2bdd3955be5a09ca7e0201e9d131f194f7f6c466e1795a733733ccfb09f25' ;; + '5.3.1') echo '1c59a17a054e9c82f0dd881871c9646e943ec4c71dd52ebc6137d17f82337436' ;; + '5.4') echo 'c8c17574245ecee9ed7fe4f6b593b696d1692d1adbfef425bef9b333e3a0e8de' ;; + '5.4.1') echo '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc' ;; + '5.5') echo '8d78b2ed63e7f07ad169c1186d119761c4773e681f332cfe1901045b1b0141bc' ;; + '5.5.1') echo '222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00' ;; + '5.6') echo '15c02ef5dd3631ec02ac52e8725703e0285d9a7eecbf4e5939aa9e924604d01d' ;; + '5.6.1') echo '0986244820e4a35d32d91df2ec4b768b5ba5d6c8246753794f85159f9963ec12' ;; + '5.6.2') echo '32fce6628848f799b0ad3205ae8db67d0d828c10ffe62b748a7c0d9f4a5d9ee0' ;; + *) exit 1 + esac } contains() { From 932ab4a3c1b963de714f9881b93147a5b7d798eb Mon Sep 17 00:00:00 2001 From: relan Date: Sun, 22 Sep 2019 08:56:39 +0300 Subject: [PATCH 0133/2775] gradlew-fdroid: avoid sed sed implementations (GNU sed vs. BSD sed) have variations in regex syntax causing distributionUrl parsing to fail on macOS. --- gradlew-fdroid | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index dc60cb1a..ee1698ad 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -152,9 +152,10 @@ v_all=${plugin_v[@]} # Earliest takes priority for f in {.,..}/gradle/wrapper/gradle-wrapper.properties; do [[ -f $f ]] || continue - while read l; do - if [[ $l == 'distributionUrl='* ]]; then - wrapper_ver=$(echo -n "$l" | sed "s/.*gradle-\\([0-9\\.\\+]\\+\\).*/\\1/") + while read -r line; do + if [[ $line == 'distributionUrl='* ]]; then + wrapper_ver=${line#*/gradle-} + wrapper_ver=${wrapper_ver%-*.zip} break 2 fi done < $f @@ -169,11 +170,13 @@ fi # Earliest takes priority for f in {.,..}/build.gradle; do [[ -f $f ]] || continue - while read l; do - if [[ -z "$plugin_pver" && $l == *'com.android.tools.build:gradle:'* ]]; then - plugin_pver=$(echo -n "$l" | sed "s/.*com.android.tools.build:gradle:\\([0-9\\.\\+]\\+\\).*/\\1/") - elif [[ -z "$wrapper_ver" && $l == *'gradleVersion = '* ]]; then - wrapper_ver=$(echo -n "$l" | sed "s/.*gradleVersion *=* *[\"']\\([0-9\\.]\\+\\)[\"'].*/\\1/") + while read -r line; do + if [[ -z "$plugin_pver" && $line == *'com.android.tools.build:gradle:'* ]]; then + plugin_pver=${line#*[\'\"]com.android.tools.build:gradle:} + plugin_pver=${plugin_pver%[\'\"]*} + elif [[ -z "$wrapper_ver" && $line == *'gradleVersion = '* ]]; then + wrapper_ver=${line#*gradleVersion*=*[\'\"]} + wrapper_ver=${wrapper_ver%[\'\"]*} fi done < $f done From 0da93f9a7d9d4910326ecdedfa4a2446f281efba Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 23 Sep 2019 10:52:13 +0200 Subject: [PATCH 0134/2775] travis: test bash script syntax with macOS's bash version !676 --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index c9cb33eb..2b6c5703 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,7 +82,12 @@ install: # The OSX tests seem to run slower, they often timeout. So only run # the test suite with the installed version of fdroid. +# +# macOS sticks with bash 3.x because of licenses, so avoid use new bash syntax script: + - /bin/bash --version + - /bin/bash -n gradlew-fdroid tests/run-tests + - ./tests/run-tests after_failure: From 7142a3b89f8462918e3f1267c16b22df719ef07d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 23 Sep 2019 11:31:14 +0200 Subject: [PATCH 0135/2775] travis: retry `brew install`, it randomly fails on downloads $ brew tap adoptopenjdk/openjdk Updating Homebrew... ==> Tapping adoptopenjdk/openjdk Cloning into '/usr/local/Homebrew/Library/Taps/adoptopenjdk/homebrew-openjdk'... fatal: unable to access 'https://github.com/adoptopenjdk/homebrew-openjdk/': Could not resolve host: github.com Error: Failure while executing; `git clone https://github.com/adoptopenjdk/homebrew-openjdk /usr/local/Homebrew/Library/Taps/adoptopenjdk/homebrew-openjdk --depth=1` exited with 128. The command "brew tap adoptopenjdk/openjdk" failed and exited with 1 during . --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2b6c5703..0a10bcb0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,8 +46,8 @@ install: - brew uninstall java --force || true - brew cask uninstall java --force || true - brew tap adoptopenjdk/openjdk - - brew cask install adoptopenjdk8 - - brew cask install android-sdk + - travis_retry brew cask install adoptopenjdk8 + - travis_retry brew cask install android-sdk - export AAPT_VERSION=`sed -n "s,^MINIMUM_AAPT_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py` - mkdir -p "$ANDROID_HOME/licenses" From 9b5f452f5d67c198bd0a5c14edde98137c870b9a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 23 Sep 2019 10:53:19 +0200 Subject: [PATCH 0136/2775] switch official Travis test badge back to https://github.com/f-droid The repos in this group are now setup as mirrors. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b0a1c02..00ddb3bc 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ | CI Builds | fdroidserver | buildserver | fdroid build --all | publishing tools | |--------------------------|:-------------:|:-----------:|:------------------:|:----------------:| | GNU/Linux | [![fdroidserver status on GNU/Linux](https://gitlab.com/fdroid/fdroidserver/badges/master/build.svg)](https://gitlab.com/fdroid/fdroidserver/builds) | [![buildserver status](https://jenkins.debian.net/job/reproducible_setup_fdroid_build_environment/badge/icon)](https://jenkins.debian.net/job/reproducible_setup_fdroid_build_environment) | [![fdroid build all status](https://jenkins.debian.net/job/reproducible_fdroid_build_apps/badge/icon)](https://jenkins.debian.net/job/reproducible_fdroid_build_apps/) | [![fdroid test status](https://jenkins.debian.net/job/reproducible_fdroid_test/badge/icon)](https://jenkins.debian.net/job/reproducible_fdroid_test/) | -| macOS | [![fdroidserver status on macOS](https://travis-ci.org/fdroidtravis/fdroidserver.svg?branch=master)](https://travis-ci.org/fdroidtravis/fdroidserver) | | | | +| macOS | [![fdroidserver status on macOS](https://travis-ci.org/f-droid/fdroidserver.svg?branch=master)](https://travis-ci.org/f-droid/fdroidserver) | | | | # F-Droid Server From 0e403878059e8a4034efa9861ad220173212a06e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 23 Sep 2019 11:08:25 +0200 Subject: [PATCH 0137/2775] gitlab-ci: switch debian/testing back to pure testing, no sid The sid packages were needed as a temporary workaround while the new androguard packages were settling into Debian. --- .gitlab-ci.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 46ce6d56..bde998ee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -45,10 +45,14 @@ debian_testing: - apt-get -qy update - apt-get -qy dist-upgrade - apt-get -qy install --no-install-recommends - fdroidserver git gnupg python3-defusedxml python3-setuptools - - sed -i -e 's,testing,sid,g' -e 's,testing,sid,g' /etc/apt/sources.list - - apt-get -qy update - - apt-get install -y --no-install-recommends aapt androguard android-platform-tools-base zipalign + aapt + androguard + fdroidserver + git + gnupg + python3-defusedxml + python3-setuptools + zipalign - python3 -c 'import fdroidserver' - python3 -c 'import androguard' - export ANDROID_HOME=/usr/lib/android-sdk From 8d3512763db6d52ed20def8025f6f3351ad1d24e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 23 Sep 2019 11:50:51 +0200 Subject: [PATCH 0138/2775] gitlab-ci: use a template for a complete apt CI setup # Conflicts: # .gitlab-ci.yml --- .gitlab-ci.yml | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bde998ee..96fc53a9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,14 +37,29 @@ metadata_v0: metadata/dump_*/*.yaml - diff -uw metadata/dump_* +.apt-template: &apt-template + variables: + DEBIAN_FRONTEND: noninteractive + LANG: C.UTF-8 + before_script: + - echo Etc/UTC > /etc/timezone + - echo 'APT::Install-Recommends "0";' + 'APT::Install-Suggests "0";' + 'APT::Acquire::Retries "20";' + 'APT::Get::Assume-Yes "true";' + 'Dpkg::Use-Pty "0";' + 'quiet "1";' + >> /etc/apt/apt.conf.d/99gitlab + - apt-get update + - apt-get dist-upgrade + debian_testing: image: debian:testing + <<: *apt-template only: - master@fdroid/fdroidserver script: - - apt-get -qy update - - apt-get -qy dist-upgrade - - apt-get -qy install --no-install-recommends + - apt-get install aapt androguard fdroidserver @@ -55,30 +70,24 @@ debian_testing: zipalign - python3 -c 'import fdroidserver' - python3 -c 'import androguard' - - export ANDROID_HOME=/usr/lib/android-sdk - - export LANG=C.UTF-8 - cd tests - ./run-tests # test using LTS set up with the PPA, including Recommends ubuntu_lts_ppa: image: ubuntu:latest + <<: *apt-template only: - master@fdroid/fdroidserver - variables: - ANDROID_HOME: /usr/lib/android-sdk - DEBIAN_FRONTEND: noninteractive - LANG: C.UTF-8 script: - - echo Etc/UTC > /etc/timezone - - apt-get -qy update - - apt-get -qy install gnupg + - export ANDROID_HOME=/usr/lib/android-sdk + - apt-get install gnupg - while ! apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 9AAC253193B65D4DF1D0A13EEC4632C79C5E0151; do sleep 15; done - export RELEASE=`sed -n 's,^deb [^ ][^ ]* \([a-z]*\).*,\1,p' /etc/apt/sources.list | head -1` - echo "deb http://ppa.launchpad.net/fdroid/fdroidserver/ubuntu $RELEASE main" >> /etc/apt/sources.list - - apt-get -qy update - - apt-get -qy dist-upgrade - - apt-get -qy install --install-recommends binfmt-support fdroidserver git python3-defusedxml python3-setuptools + - apt-get update + - apt-get dist-upgrade + - apt-get install --install-recommends binfmt-support fdroidserver git python3-defusedxml python3-setuptools - grep binfmt /proc/modules || apt -qy purge apksigner - cd tests - ./run-tests @@ -87,16 +96,11 @@ ubuntu_lts_ppa: # apksigner is recommended, but requires binfmt support in the kernel ubuntu_xenial_pip: image: ubuntu:xenial + <<: *apt-template only: - master@fdroid/fdroidserver - variables: - DEBIAN_FRONTEND: noninteractive - LANG: C.UTF-8 script: - - echo Etc/UTC > /etc/timezone - - apt-get -qy update - - apt-get -qy dist-upgrade - - apt-get -qy install --no-install-recommends git default-jdk-headless python3-pip python3-venv rsync zipalign + - apt-get install git default-jdk-headless python3-pip python3-venv rsync zipalign - rm -rf env - pyvenv env - . env/bin/activate From cf2c1d0270c6f8de66520ed251f90f57f78767b5 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 25 Sep 2019 12:21:04 +0200 Subject: [PATCH 0139/2775] run-tests needs a source of APKs to function The test runs on jenkins.debian.net were failing because they specified a dir that did not exist. --- tests/run-tests | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/run-tests b/tests/run-tests index c6248954..8a7b31a8 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -99,6 +99,10 @@ if [ -z "$1" ]; then else APKDIR=$1 fi +if [ ! -d "$APKDIR" ]; then + echo "ERROR: '$APKDIR' does not exist!" + exit 1 +fi if [ -z $WORKSPACE ]; then WORKSPACE=`dirname $(pwd)` From 41904811429faf69e61648114dcf7144a29afa82 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 25 Sep 2019 12:41:07 +0200 Subject: [PATCH 0140/2775] jenkins-test: make source APK source exists --- jenkins-test | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jenkins-test b/jenkins-test index 4914a455..a48d6525 100755 --- a/jenkins-test +++ b/jenkins-test @@ -34,6 +34,11 @@ export ANDROID_HOME=/usr/lib/android-sdk rm -rf "$WORKSPACE/.testfiles" cd tests +if [ ! -e $WORKSPACE/fdroiddata/repo ]; then + echo "WARNING: $WORKSPACE/fdroiddata/repo does not exist, making placeholder!" + mkdir $WORKSPACE/fdroiddata/repo + cp $WORKSPACE/tests/repo/*.apk $WORKSPACE/fdroiddata/repo/ +fi ./run-tests $WORKSPACE/fdroiddata/repo # this is set up and managed by jenkins-build-all From c738ad54ec6c03866c7ad8adc4774a705e6378d0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 25 Sep 2019 14:34:47 +0200 Subject: [PATCH 0141/2775] jenkins-test: only use APKs that'll never be in fdroiddata --- jenkins-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins-test b/jenkins-test index a48d6525..d6ce9659 100755 --- a/jenkins-test +++ b/jenkins-test @@ -37,7 +37,7 @@ cd tests if [ ! -e $WORKSPACE/fdroiddata/repo ]; then echo "WARNING: $WORKSPACE/fdroiddata/repo does not exist, making placeholder!" mkdir $WORKSPACE/fdroiddata/repo - cp $WORKSPACE/tests/repo/*.apk $WORKSPACE/fdroiddata/repo/ + cp $WORKSPACE/tests/repo/*obb.*.apk $WORKSPACE/fdroiddata/repo/ fi ./run-tests $WORKSPACE/fdroiddata/repo From c7048f2c39b51dc55b1ed7681262d7b31c1ab446 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 26 Sep 2019 19:38:24 +0200 Subject: [PATCH 0142/2775] update: log errors on bad graphics, and then ignore the file Python PIL is not so tolerant, so bad EXIF causes crashes: File "/var/lib/jenkins/userContent/reproducible/reproducible_fdroid_build_apps/fdroidserver/update.py", line 2088, in main insert_localized_app_metadata(apps) File "/var/lib/jenkins/userContent/reproducible/reproducible_fdroid_build_apps/fdroidserver/update.py", line 978, in insert_localized_app_metadata _strip_and_copy_image(os.path.join(root, f), destdir) File "/var/lib/jenkins/userContent/reproducible/reproducible_fdroid_build_apps/fdroidserver/update.py", line 754, in _strip_and_copy_image in_image = Image.open(fp) File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2687, in open % (filename if filename else fp)) OSError: cannot identify image file <_io.BufferedReader name='build/org.sw24softwares.starkeverben/fastlane/metadata/android/en-US/images/featureGraphic.png'> --- fdroidserver/update.py | 30 ++++++++++++++++++++---------- tests/corrupt-featureGraphic.png | Bin 0 -> 443812 bytes tests/update.TestCase | 14 ++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 tests/corrupt-featureGraphic.png diff --git a/fdroidserver/update.py b/fdroidserver/update.py index d1dd11bf..7529dbff 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -733,6 +733,8 @@ def _strip_and_copy_image(in_file, outpath): outpath can be path to either a file or dir. The dir that outpath refers to must exist before calling this. + Potential source of Python code to strip JPEGs without dependencies: + http://www.fetidcascade.com/public/minimal_exif_writer.py """ logging.debug('copying ' + in_file + ' ' + outpath) @@ -750,17 +752,25 @@ def _strip_and_copy_image(in_file, outpath): extension = common.get_extension(in_file)[1] if extension == 'png': - with open(in_file, 'rb') as fp: - in_image = Image.open(fp) - in_image.save(out_file, "PNG", optimize=True, - pnginfo=BLANK_PNG_INFO, icc_profile=None) + try: + with open(in_file, 'rb') as fp: + in_image = Image.open(fp) + in_image.save(out_file, "PNG", optimize=True, + pnginfo=BLANK_PNG_INFO, icc_profile=None) + except Exception as e: + logging.error(_("Failed copying {path}: {error}".format(path=in_file, error=e))) + return elif extension == 'jpg' or extension == 'jpeg': - with open(in_file, 'rb') as fp: - in_image = Image.open(fp) - data = list(in_image.getdata()) - out_image = Image.new(in_image.mode, in_image.size) - out_image.putdata(data) - out_image.save(out_file, "JPEG", optimize=True) + try: + with open(in_file, 'rb') as fp: + in_image = Image.open(fp) + data = list(in_image.getdata()) + out_image = Image.new(in_image.mode, in_image.size) + out_image.putdata(data) + out_image.save(out_file, "JPEG", optimize=True) + except Exception as e: + logging.error(_("Failed copying {path}: {error}".format(path=in_file, error=e))) + return else: raise FDroidException(_('Unsupported file type "{extension}" for repo graphic') .format(extension=extension)) diff --git a/tests/corrupt-featureGraphic.png b/tests/corrupt-featureGraphic.png new file mode 100644 index 0000000000000000000000000000000000000000..f2adec129fd943be473166ec764c84b7f0a014eb GIT binary patch literal 443812 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%0DFS*STWq_9EFYX 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%0Ah8*h0J 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ÚL(K0nMbi=k{$T&I^di}N!%D4W(guiu+xMXO)pF$ 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%0D3~WL9 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%0Dv$i8y!JClytWzZVpnClJK(l90VfVy2<{Mq_` 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�E5t*8FVCGp$p22LIuz7f& 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 Date: Sat, 28 Sep 2019 07:49:02 +0300 Subject: [PATCH 0143/2775] scanner: blacklist Bugly The artifact is licensed under "The Bugly Software License, Version 1.0" [1], but link to the full text [2] is broken. LICENSE file in the source code repository is empty. I guess this library is non-free. [1] https://mvnrepository.com/artifact/com.tencent.bugly/crashreport/2.8.6.0 [2] http://bugly.qq.com/licenses/LICENSE-1.0.txt [3] https://github.com/BuglyDevTeam/Bugly-Android --- fdroidserver/scanner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index e4222526..bc07f8a9 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -77,6 +77,7 @@ def scan_source(build_dir, build=metadata.Build()): r'firebase', r'''["']com.facebook.android['":]''', r'cloudrail', + r'com.tencent.bugly', ] } From 3c9535d64b5d26fb75dfc70d1a1e72fc497a1b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 2 Oct 2019 12:15:02 +0200 Subject: [PATCH 0144/2775] lint: fsf approved licenses only --- fdroidserver/lint.py | 388 ++++--------------------------------------- 1 file changed, 35 insertions(+), 353 deletions(-) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 465954cc..81794840 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -441,9 +441,9 @@ def check_format(app): def check_license_tag(app): '''Ensure all license tags are in https://spdx.org/license-list''' - if app.License.rstrip('+') not in SPDX: - yield _('Invalid license tag "%s"! Use only tags from https://spdx.org/license-list') \ - % (app.License) + if app.License.rstrip('+') not in FSF_APPROVED_SPDX: + yield _('Unexpected license tag "{}"! Use only FSF approved tags ' + 'from https://spdx.org/license-list').format(app.License) def check_extlib_dir(apps): @@ -622,356 +622,38 @@ def main(): sys.exit(1) -# A compiled, public domain list of official SPDX license tags from: -# https://github.com/sindresorhus/spdx-license-list/blob/v4.0.0/spdx-simple.json -# The deprecated license tags have been removed from the list, they are at the -# bottom, starting after the last license tags that start with Z. -# This is at the bottom, since its a long list of data -SPDX = [ - "PublicDomain", # an F-Droid addition, until we can enforce a better option - "0BSD", - "AAL", - "Abstyles", - "Adobe-2006", - "Adobe-Glyph", - "ADSL", - "AFL-1.1", - "AFL-1.2", - "AFL-2.0", - "AFL-2.1", - "AFL-3.0", - "Afmparse", - "AGPL-1.0", - "AGPL-3.0-only", - "AGPL-3.0-or-later", - "Aladdin", - "AMDPLPA", - "AML", - "AMPAS", - "ANTLR-PD", - "Apache-1.0", - "Apache-1.1", - "Apache-2.0", - "APAFML", - "APL-1.0", - "APSL-1.0", - "APSL-1.1", - "APSL-1.2", - "APSL-2.0", - "Artistic-1.0-cl8", - "Artistic-1.0-Perl", - "Artistic-1.0", - "Artistic-2.0", - "Bahyph", - "Barr", - "Beerware", - "BitTorrent-1.0", - "BitTorrent-1.1", - "Borceux", - "BSD-1-Clause", - "BSD-2-Clause-FreeBSD", - "BSD-2-Clause-NetBSD", - "BSD-2-Clause-Patent", - "BSD-2-Clause", - "BSD-3-Clause-Attribution", - "BSD-3-Clause-Clear", - "BSD-3-Clause-LBNL", - "BSD-3-Clause-No-Nuclear-License-2014", - "BSD-3-Clause-No-Nuclear-License", - "BSD-3-Clause-No-Nuclear-Warranty", - "BSD-3-Clause", - "BSD-4-Clause-UC", - "BSD-4-Clause", - "BSD-Protection", - "BSD-Source-Code", - "BSL-1.0", - "bzip2-1.0.5", - "bzip2-1.0.6", - "Caldera", - "CATOSL-1.1", - "CC-BY-1.0", - "CC-BY-2.0", - "CC-BY-2.5", - "CC-BY-3.0", - "CC-BY-4.0", - "CC-BY-NC-1.0", - "CC-BY-NC-2.0", - "CC-BY-NC-2.5", - "CC-BY-NC-3.0", - "CC-BY-NC-4.0", - "CC-BY-NC-ND-1.0", - "CC-BY-NC-ND-2.0", - "CC-BY-NC-ND-2.5", - "CC-BY-NC-ND-3.0", - "CC-BY-NC-ND-4.0", - "CC-BY-NC-SA-1.0", - "CC-BY-NC-SA-2.0", - "CC-BY-NC-SA-2.5", - "CC-BY-NC-SA-3.0", - "CC-BY-NC-SA-4.0", - "CC-BY-ND-1.0", - "CC-BY-ND-2.0", - "CC-BY-ND-2.5", - "CC-BY-ND-3.0", - "CC-BY-ND-4.0", - "CC-BY-SA-1.0", - "CC-BY-SA-2.0", - "CC-BY-SA-2.5", - "CC-BY-SA-3.0", - "CC-BY-SA-4.0", - "CC0-1.0", - "CDDL-1.0", - "CDDL-1.1", - "CDLA-Permissive-1.0", - "CDLA-Sharing-1.0", - "CECILL-1.0", - "CECILL-1.1", - "CECILL-2.0", - "CECILL-2.1", - "CECILL-B", - "CECILL-C", - "ClArtistic", - "CNRI-Jython", - "CNRI-Python-GPL-Compatible", - "CNRI-Python", - "Condor-1.1", - "CPAL-1.0", - "CPL-1.0", - "CPOL-1.02", - "Crossword", - "CrystalStacker", - "CUA-OPL-1.0", - "Cube", - "curl", - "D-FSL-1.0", - "diffmark", - "DOC", - "Dotseqn", - "DSDP", - "dvipdfm", - "ECL-1.0", - "ECL-2.0", - "EFL-1.0", - "EFL-2.0", - "eGenix", - "Entessa", - "EPL-1.0", - "EPL-2.0", - "ErlPL-1.1", - "EUDatagrid", - "EUPL-1.0", - "EUPL-1.1", - "EUPL-1.2", - "Eurosym", - "Fair", - "Frameworx-1.0", - "FreeImage", - "FSFAP", - "FSFUL", - "FSFULLR", - "FTL", - "GFDL-1.1-only", - "GFDL-1.1-or-later", - "GFDL-1.2-only", - "GFDL-1.2-or-later", - "GFDL-1.3-only", - "GFDL-1.3-or-later", - "Giftware", - "GL2PS", - "Glide", - "Glulxe", - "gnuplot", - "GPL-1.0-only", - "GPL-1.0-or-later", - "GPL-2.0-only", - "GPL-2.0-or-later", - "GPL-3.0-only", - "GPL-3.0-or-later", - "gSOAP-1.3b", - "HaskellReport", - "HPND", - "IBM-pibs", - "ICU", - "IJG", - "ImageMagick", - "iMatix", - "Imlib2", - "Info-ZIP", - "Intel-ACPI", - "Intel", - "Interbase-1.0", - "IPA", - "IPL-1.0", - "ISC", - "JasPer-2.0", - "JSON", - "LAL-1.2", - "LAL-1.3", - "Latex2e", - "Leptonica", - "LGPL-2.0-only", - "LGPL-2.0-or-later", - "LGPL-2.1-only", - "LGPL-2.1-or-later", - "LGPL-3.0-only", - "LGPL-3.0-or-later", - "LGPLLR", - "Libpng", - "libtiff", - "LiLiQ-P-1.1", - "LiLiQ-R-1.1", - "LiLiQ-Rplus-1.1", - "LPL-1.0", - "LPL-1.02", - "LPPL-1.0", - "LPPL-1.1", - "LPPL-1.2", - "LPPL-1.3a", - "LPPL-1.3c", - "MakeIndex", - "MirOS", - "MIT-advertising", - "MIT-CMU", - "MIT-enna", - "MIT-feh", - "MIT", - "MITNFA", - "Motosoto", - "mpich2", - "MPL-1.0", - "MPL-1.1", - "MPL-2.0-no-copyleft-exception", - "MPL-2.0", - "MS-PL", - "MS-RL", - "MTLL", - "Multics", - "Mup", - "NASA-1.3", - "Naumen", - "NBPL-1.0", - "NCSA", - "Net-SNMP", - "NetCDF", - "Newsletr", - "NGPL", - "NLOD-1.0", - "NLPL", - "Nokia", - "NOSL", - "Noweb", - "NPL-1.0", - "NPL-1.1", - "NPOSL-3.0", - "NRL", - "NTP", - "OCCT-PL", - "OCLC-2.0", - "ODbL-1.0", - "OFL-1.0", - "OFL-1.1", - "OGTSL", - "OLDAP-1.1", - "OLDAP-1.2", - "OLDAP-1.3", - "OLDAP-1.4", - "OLDAP-2.0.1", - "OLDAP-2.0", - "OLDAP-2.1", - "OLDAP-2.2.1", - "OLDAP-2.2.2", - "OLDAP-2.2", - "OLDAP-2.3", - "OLDAP-2.4", - "OLDAP-2.5", - "OLDAP-2.6", - "OLDAP-2.7", - "OLDAP-2.8", - "OML", - "OpenSSL", - "OPL-1.0", - "OSET-PL-2.1", - "OSL-1.0", - "OSL-1.1", - "OSL-2.0", - "OSL-2.1", - "OSL-3.0", - "PDDL-1.0", - "PHP-3.0", - "PHP-3.01", - "Plexus", - "PostgreSQL", - "psfrag", - "psutils", - "Python-2.0", - "Qhull", - "QPL-1.0", - "Rdisc", - "RHeCos-1.1", - "RPL-1.1", - "RPL-1.5", - "RPSL-1.0", - "RSA-MD", - "RSCPL", - "Ruby", - "SAX-PD", - "Saxpath", - "SCEA", - "Sendmail", - "SGI-B-1.0", - "SGI-B-1.1", - "SGI-B-2.0", - "SimPL-2.0", - "SISSL-1.2", - "SISSL", - "Sleepycat", - "SMLNJ", - "SMPPL", - "SNIA", - "Spencer-86", - "Spencer-94", - "Spencer-99", - "SPL-1.0", - "SugarCRM-1.1.3", - "SWL", - "TCL", - "TCP-wrappers", - "TMate", - "TORQUE-1.1", - "TOSL", - "Unicode-DFS-2015", - "Unicode-DFS-2016", - "Unicode-TOU", - "Unlicense", - "UPL-1.0", - "Vim", - "VOSTROM", - "VSL-1.0", - "W3C-19980720", - "W3C-20150513", - "W3C", - "Watcom-1.0", - "Wsuipa", - "WTFPL", - "X11", - "Xerox", - "XFree86-1.1", - "xinetd", - "Xnet", - "xpp", - "XSkat", - "YPL-1.0", - "YPL-1.1", - "Zed", - "Zend-2.0", - "Zimbra-1.3", - "Zimbra-1.4", - "zlib-acknowledgement", - "Zlib", - "ZPL-1.1", - "ZPL-2.0", - "ZPL-2.1", -] +# A compiled, public domain list of official SPDX license tags. +# generated using: `python3 -m spdx_license_list print --filter-fsf` +# Only contains licenes approved by FSF to be libre/free software +FSF_APPROVED_SPDX = ['AFL-1.1', 'AFL-1.2', 'AFL-2.0', 'AFL-2.1', 'AFL-3.0', + 'AGPL-3.0-only', 'AGPL-3.0-or-later', 'APSL-2.0', + 'Apache-1.0', 'Apache-1.1', 'Apache-2.0', 'Artistic-2.0', + 'BSD-2-Clause-FreeBSD', 'BSD-3-Clause', + 'BSD-3-Clause-Clear', 'BSD-4-Clause', 'BSL-1.0', + 'BitTorrent-1.1', 'CC-BY-4.0', 'CC-BY-SA-4.0', 'CC0-1.0', + 'CDDL-1.0', 'CECILL-2.0', 'CECILL-B', 'CECILL-C', + 'CPAL-1.0', 'CPL-1.0', 'ClArtistic', 'Condor-1.1', + 'ECL-2.0', 'EFL-2.0', 'EPL-1.0', 'EPL-2.0', 'EUDatagrid', + 'EUPL-1.1', 'EUPL-1.2', 'FSFAP', 'FTL', 'GFDL-1.1-only', + 'GFDL-1.1-or-later', 'GFDL-1.2-only', 'GFDL-1.2-or-later', + 'GFDL-1.3-only', 'GFDL-1.3-or-later', 'GPL-2.0-only', + 'GPL-2.0-or-later', 'GPL-3.0-only', 'GPL-3.0-or-later', + 'HPND', 'IJG', 'IPA', 'IPL-1.0', 'ISC', 'Imlib2', 'Intel', + 'LGPL-2.1-only', 'LGPL-2.1-or-later', 'LGPL-3.0-only', + 'LGPL-3.0-or-later', 'LPL-1.02', 'LPPL-1.2', 'LPPL-1.3a', + 'MIT', 'MPL-1.1', 'MPL-2.0', 'MS-PL', 'MS-RL', 'NCSA', + 'NOSL', 'NPL-1.0', 'NPL-1.1', 'Nokia', 'ODbL-1.0', + 'OFL-1.0', 'OFL-1.1', 'OLDAP-2.3', 'OLDAP-2.7', 'OSL-1.0', + 'OSL-1.1', 'OSL-2.0', 'OSL-2.1', 'OSL-3.0', 'OpenSSL', + 'PHP-3.01', 'Python-2.0', 'QPL-1.0', 'RPSL-1.0', 'Ruby', + 'SGI-B-2.0', 'SISSL', 'SMLNJ', 'SPL-1.0', 'Sleepycat', + 'UPL-1.0', 'Unlicense', 'Vim', 'W3C', 'WTFPL', 'X11', + 'XFree86-1.1', 'YPL-1.1', 'ZPL-2.0', 'ZPL-2.1', + 'Zend-2.0', 'Zimbra-1.3', 'Zlib', 'gnuplot', 'iMatix', + 'xinetd'] + +# an F-Droid addition, until we can enforce a better option +FSF_APPROVED_SPDX.append("PublicDomain") if __name__ == "__main__": main() From d5ab303d832edb5658b499e450c0f3dd305ff883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 2 Oct 2019 22:14:09 +0200 Subject: [PATCH 0145/2775] lint: license override config option + require FSF/OSI approved licenses by default --- examples/config.py | 17 ++++ fdroidserver/common.py | 2 + fdroidserver/lint.py | 212 ++++++++++++++++++++++++++++++++++------- tests/lint.TestCase | 94 ++++++++++++++++++ 4 files changed, 291 insertions(+), 34 deletions(-) diff --git a/examples/config.py b/examples/config.py index b5793eeb..c766eab2 100644 --- a/examples/config.py +++ b/examples/config.py @@ -330,3 +330,20 @@ The repository of older versions of applications from the main demo repository. # 'com.facebook.orca', # 'com.android.vending', # ) + +# `fdroid lint` checks licenses in metadata against a built white list. By +# default we will require license metadata to be present and only allow +# licenses approved either by FSF or OSI. We're using the standardized SPDX +# license IDs. (https://spdx.org/licenses/) +# +# We use `python3 -m spdx-license-list print --filter-fsf-or-osi` for +# generating our default list. (https://pypi.org/project/spdx-license-list) +# +# You can override our default list of allowed licenes by setting this option. +# Just supply a custom list of licene names you would like to allow. Setting +# this to `None` disables this lint check. +# +# lint_licenses = ( +# 'Custom-License-A', +# 'Another-License', +# ) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 55052355..059a641f 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -57,6 +57,7 @@ from pyasn1_modules import rfc2315 from pyasn1.error import PyAsn1Error import fdroidserver.metadata +import fdroidserver.lint from fdroidserver import _ from fdroidserver.exception import FDroidException, VCSException, NoSubmodulesException,\ BuildException, VerificationException @@ -145,6 +146,7 @@ default_config = { using the tools on https://gitlab.com/u/fdroid. ''', 'archive_older': 0, + 'lint_licenses': fdroidserver.lint.APPROVED_LICENSES, } diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 81794840..86246d36 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -440,10 +440,17 @@ def check_format(app): def check_license_tag(app): - '''Ensure all license tags are in https://spdx.org/license-list''' - if app.License.rstrip('+') not in FSF_APPROVED_SPDX: - yield _('Unexpected license tag "{}"! Use only FSF approved tags ' - 'from https://spdx.org/license-list').format(app.License) + '''Ensure all license tags contain only valid/approved values''' + if config['lint_licenses'] is None: + return + if app.License not in config['lint_licenses']: + if config['lint_licenses'] == APPROVED_LICENSES: + yield _('Unexpected license tag "{}"! Only use FSF or OSI ' + 'approved tags from https://spdx.org/license-list') \ + .format(app.License) + else: + yield _('Unexpected license tag "{}"! Only use license tags ' + 'configured in your config file').format(app.License) def check_extlib_dir(apps): @@ -622,38 +629,175 @@ def main(): sys.exit(1) -# A compiled, public domain list of official SPDX license tags. -# generated using: `python3 -m spdx_license_list print --filter-fsf` -# Only contains licenes approved by FSF to be libre/free software -FSF_APPROVED_SPDX = ['AFL-1.1', 'AFL-1.2', 'AFL-2.0', 'AFL-2.1', 'AFL-3.0', - 'AGPL-3.0-only', 'AGPL-3.0-or-later', 'APSL-2.0', - 'Apache-1.0', 'Apache-1.1', 'Apache-2.0', 'Artistic-2.0', - 'BSD-2-Clause-FreeBSD', 'BSD-3-Clause', - 'BSD-3-Clause-Clear', 'BSD-4-Clause', 'BSL-1.0', - 'BitTorrent-1.1', 'CC-BY-4.0', 'CC-BY-SA-4.0', 'CC0-1.0', - 'CDDL-1.0', 'CECILL-2.0', 'CECILL-B', 'CECILL-C', - 'CPAL-1.0', 'CPL-1.0', 'ClArtistic', 'Condor-1.1', - 'ECL-2.0', 'EFL-2.0', 'EPL-1.0', 'EPL-2.0', 'EUDatagrid', - 'EUPL-1.1', 'EUPL-1.2', 'FSFAP', 'FTL', 'GFDL-1.1-only', - 'GFDL-1.1-or-later', 'GFDL-1.2-only', 'GFDL-1.2-or-later', - 'GFDL-1.3-only', 'GFDL-1.3-or-later', 'GPL-2.0-only', - 'GPL-2.0-or-later', 'GPL-3.0-only', 'GPL-3.0-or-later', - 'HPND', 'IJG', 'IPA', 'IPL-1.0', 'ISC', 'Imlib2', 'Intel', - 'LGPL-2.1-only', 'LGPL-2.1-or-later', 'LGPL-3.0-only', - 'LGPL-3.0-or-later', 'LPL-1.02', 'LPPL-1.2', 'LPPL-1.3a', - 'MIT', 'MPL-1.1', 'MPL-2.0', 'MS-PL', 'MS-RL', 'NCSA', - 'NOSL', 'NPL-1.0', 'NPL-1.1', 'Nokia', 'ODbL-1.0', - 'OFL-1.0', 'OFL-1.1', 'OLDAP-2.3', 'OLDAP-2.7', 'OSL-1.0', - 'OSL-1.1', 'OSL-2.0', 'OSL-2.1', 'OSL-3.0', 'OpenSSL', - 'PHP-3.01', 'Python-2.0', 'QPL-1.0', 'RPSL-1.0', 'Ruby', - 'SGI-B-2.0', 'SISSL', 'SMLNJ', 'SPL-1.0', 'Sleepycat', - 'UPL-1.0', 'Unlicense', 'Vim', 'W3C', 'WTFPL', 'X11', - 'XFree86-1.1', 'YPL-1.1', 'ZPL-2.0', 'ZPL-2.1', - 'Zend-2.0', 'Zimbra-1.3', 'Zlib', 'gnuplot', 'iMatix', - 'xinetd'] +# A compiled, public domain list of official SPDX license tags. generated +# using: `python3 -m spdx_license_list print --filter-fsf-or-osi` Only contains +# licenes approved by either FSF to be free/libre software or OSI to be open +# source +APPROVED_LICENSES = [ + '0BSD', + 'AAL', + 'AFL-1.1', + 'AFL-1.2', + 'AFL-2.0', + 'AFL-2.1', + 'AFL-3.0', + 'AGPL-3.0-only', + 'AGPL-3.0-or-later', + 'APL-1.0', + 'APSL-1.0', + 'APSL-1.1', + 'APSL-1.2', + 'APSL-2.0', + 'Apache-1.0', + 'Apache-1.1', + 'Apache-2.0', + 'Artistic-1.0', + 'Artistic-1.0-Perl', + 'Artistic-1.0-cl8', + 'Artistic-2.0', + 'BSD-2-Clause', + 'BSD-2-Clause-FreeBSD', + 'BSD-2-Clause-Patent', + 'BSD-3-Clause', + 'BSD-3-Clause-Clear', + 'BSD-3-Clause-LBNL', + 'BSD-4-Clause', + 'BSL-1.0', + 'BitTorrent-1.1', + 'CATOSL-1.1', + 'CC-BY-4.0', + 'CC-BY-SA-4.0', + 'CC0-1.0', + 'CDDL-1.0', + 'CECILL-2.0', + 'CECILL-2.1', + 'CECILL-B', + 'CECILL-C', + 'CNRI-Python', + 'CPAL-1.0', + 'CPL-1.0', + 'CUA-OPL-1.0', + 'ClArtistic', + 'Condor-1.1', + 'ECL-1.0', + 'ECL-2.0', + 'EFL-1.0', + 'EFL-2.0', + 'EPL-1.0', + 'EPL-2.0', + 'EUDatagrid', + 'EUPL-1.1', + 'EUPL-1.2', + 'Entessa', + 'FSFAP', + 'FTL', + 'Fair', + 'Frameworx-1.0', + 'GFDL-1.1-only', + 'GFDL-1.1-or-later', + 'GFDL-1.2-only', + 'GFDL-1.2-or-later', + 'GFDL-1.3-only', + 'GFDL-1.3-or-later', + 'GPL-2.0-only', + 'GPL-2.0-or-later', + 'GPL-3.0-only', + 'GPL-3.0-or-later', + 'HPND', + 'IJG', + 'IPA', + 'IPL-1.0', + 'ISC', + 'Imlib2', + 'Intel', + 'LGPL-2.0-only', + 'LGPL-2.0-or-later', + 'LGPL-2.1-only', + 'LGPL-2.1-or-later', + 'LGPL-3.0-only', + 'LGPL-3.0-or-later', + 'LPL-1.0', + 'LPL-1.02', + 'LPPL-1.2', + 'LPPL-1.3a', + 'LPPL-1.3c', + 'LiLiQ-P-1.1', + 'LiLiQ-R-1.1', + 'LiLiQ-Rplus-1.1', + 'MIT', + 'MIT-0', + 'MPL-1.0', + 'MPL-1.1', + 'MPL-2.0', + 'MPL-2.0-no-copyleft-exception', + 'MS-PL', + 'MS-RL', + 'MirOS', + 'Motosoto', + 'Multics', + 'NASA-1.3', + 'NCSA', + 'NGPL', + 'NOSL', + 'NPL-1.0', + 'NPL-1.1', + 'NPOSL-3.0', + 'NTP', + 'Naumen', + 'Nokia', + 'OCLC-2.0', + 'ODbL-1.0', + 'OFL-1.0', + 'OFL-1.1', + 'OGTSL', + 'OLDAP-2.3', + 'OLDAP-2.7', + 'OSET-PL-2.1', + 'OSL-1.0', + 'OSL-1.1', + 'OSL-2.0', + 'OSL-2.1', + 'OSL-3.0', + 'OpenSSL', + 'PHP-3.0', + 'PHP-3.01', + 'PostgreSQL', + 'Python-2.0', + 'QPL-1.0', + 'RPL-1.1', + 'RPL-1.5', + 'RPSL-1.0', + 'RSCPL', + 'Ruby', + 'SGI-B-2.0', + 'SISSL', + 'SMLNJ', + 'SPL-1.0', + 'SimPL-2.0', + 'Sleepycat', + 'UPL-1.0', + 'Unlicense', + 'VSL-1.0', + 'Vim', + 'W3C', + 'WTFPL', + 'Watcom-1.0', + 'X11', + 'XFree86-1.1', + 'Xnet', + 'YPL-1.1', + 'ZPL-2.0', + 'ZPL-2.1', + 'Zend-2.0', + 'Zimbra-1.3', + 'Zlib', + 'gnuplot', + 'iMatix', + 'xinetd', +] # an F-Droid addition, until we can enforce a better option -FSF_APPROVED_SPDX.append("PublicDomain") +APPROVED_LICENSES.append("PublicDomain") if __name__ == "__main__": main() diff --git a/tests/lint.TestCase b/tests/lint.TestCase index 4bdee948..f5dd2c30 100755 --- a/tests/lint.TestCase +++ b/tests/lint.TestCase @@ -179,6 +179,100 @@ class LintTest(unittest.TestCase): logging.debug(warn) self.assertTrue(anywarns) + def test_check_license_tag_no_custom_pass(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.lint.config = config + + app = fdroidserver.metadata.App() + app.License = "GPL-3.0-or-later" + + anywarns = False + for warn in fdroidserver.lint.check_license_tag(app): + anywarns = True + logging.debug(warn) + self.assertFalse(anywarns) + + def test_check_license_tag_no_custom_fail(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.lint.config = config + + app = fdroidserver.metadata.App() + app.License = "Adobe-2006" + + anywarns = False + for warn in fdroidserver.lint.check_license_tag(app): + anywarns = True + logging.debug(warn) + self.assertTrue(anywarns) + + def test_check_license_tag_with_custom_pass(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.lint.config = config + config['lint_licenses'] = ['fancy-license', 'GPL-3.0-or-later'] + + app = fdroidserver.metadata.App() + app.License = "fancy-license" + + anywarns = False + for warn in fdroidserver.lint.check_license_tag(app): + anywarns = True + logging.debug(warn) + self.assertFalse(anywarns) + + def test_check_license_tag_with_custom_fail(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.lint.config = config + config['lint_licenses'] = ['fancy-license', 'GPL-3.0-or-later'] + + app = fdroidserver.metadata.App() + app.License = "Apache-2.0" + + anywarns = False + for warn in fdroidserver.lint.check_license_tag(app): + anywarns = True + logging.debug(warn) + self.assertTrue(anywarns) + + def test_check_license_tag_with_custom_empty(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.lint.config = config + config['lint_licenses'] = [] + + app = fdroidserver.metadata.App() + app.License = "Apache-2.0" + + anywarns = False + for warn in fdroidserver.lint.check_license_tag(app): + anywarns = True + logging.debug(warn) + self.assertTrue(anywarns) + + def test_check_license_tag_disabled(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.lint.config = config + config['lint_licenses'] = None + + app = fdroidserver.metadata.App() + app.License = "Apache-2.0" + + anywarns = False + for warn in fdroidserver.lint.check_license_tag(app): + anywarns = True + logging.debug(warn) + self.assertFalse(anywarns) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 17320c23f4f7be1c71abdc5f0ea36f778ff25fcb Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 30 Sep 2019 13:07:49 +0200 Subject: [PATCH 0146/2775] lint: don't trip up on projects with 'master' in the name https://gitlab.com/fdroid/fdroiddata/merge_requests/5557#note_223283359 --- fdroidserver/lint.py | 2 +- tests/lint.TestCase | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 86246d36..ba6fd442 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -122,7 +122,7 @@ http_url_shorteners = [ http_checks = https_enforcings + http_url_shorteners + [ (re.compile(r'.*github\.com/[^/]+/[^/]+\.git'), _("Appending .git is not necessary")), - (re.compile(r'.*://[^/]*(github|gitlab|bitbucket|rawgit)[^/]*/([^/]+/){1,3}master'), + (re.compile(r'^https://[^/]*(github|gitlab|bitbucket|rawgit)\.[a-zA-Z]+/([^/]+/){2,3}master/'), _("Use /HEAD instead of /master to point at a file in the default branch")), ] diff --git a/tests/lint.TestCase b/tests/lint.TestCase index f5dd2c30..12285431 100755 --- a/tests/lint.TestCase +++ b/tests/lint.TestCase @@ -70,6 +70,49 @@ class LintTest(unittest.TestCase): logging.debug(warn) self.assertTrue(anywarns) + def test_source_urls(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.lint.config = config + + app = { + 'Name': 'My App', + 'Summary': 'just a placeholder', + 'Description': 'This app does all sorts of useful stuff', + } + good_urls = [ + 'https://github.com/Matteljay/mastermindy-android', + 'https://gitlab.com/origin/master', + 'https://gitlab.com/group/subgroup/masterthing', + 'https://raw.githubusercontent.com/Seva-coder/Finder/HEAD/ChangeLog.txt', + 'https://github.com/scoutant/blokish/blob/HEAD/README.md#changelog', + 'https://git.ieval.ro/?p=fonbot.git;a=blob;f=Changes;hb=HEAD', + 'https://htmlpreview.github.io/?https://github.com/YasuakiHonda/Maxima-on-Android-AS/blob/HEAD/app/src/main/assets/About_MoA/index.html', + '', + ] + + anywarns = False + for url in good_urls: + app['SourceCode'] = url + for warn in fdroidserver.lint.check_regexes(app): + anywarns = True + logging.debug(warn) + self.assertFalse(anywarns) + + bad_urls = [ + 'https://raw.githubusercontent.com/Seva-coder/Finder/master/ChangeLog.txt', + 'https://github.com/scoutant/blokish/blob/master/README.md#changelog', + ] + anywarns = False + logging.debug('bad urls:') + for url in bad_urls: + app['SourceCode'] = url + for warn in fdroidserver.lint.check_regexes(app): + anywarns = True + logging.debug(warn) + self.assertTrue(anywarns) + def test_check_app_field_types(self): config = dict() fdroidserver.common.fill_config_defaults(config) From af4e231f7dde885fd0db2a730ec419dbad3b099a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 30 Sep 2019 13:08:58 +0200 Subject: [PATCH 0147/2775] lint: enforce HTTPS on GitHub and GitLab pages The always provide HTTPS, so let's enforce it. --- fdroidserver/lint.py | 6 +++++- tests/lint.TestCase | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index ba6fd442..e8881a84 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -120,7 +120,11 @@ http_url_shorteners = [ ] http_checks = https_enforcings + http_url_shorteners + [ - (re.compile(r'.*github\.com/[^/]+/[^/]+\.git'), + (re.compile(r'^(?!https?://)[^/]+'), + _("URL must start with https:// or http://")), + (re.compile(r'^http://[^.]+\.(github|gitlab)\.io/'), + _("URL must start with https://")), + (re.compile(r'^https://(github|gitlab)\.com(/[^/]+){2,3}\.git'), _("Appending .git is not necessary")), (re.compile(r'^https://[^/]*(github|gitlab|bitbucket|rawgit)\.[a-zA-Z]+/([^/]+/){2,3}master/'), _("Use /HEAD instead of /master to point at a file in the default branch")), diff --git a/tests/lint.TestCase b/tests/lint.TestCase index 12285431..65f351c0 100755 --- a/tests/lint.TestCase +++ b/tests/lint.TestCase @@ -101,8 +101,12 @@ class LintTest(unittest.TestCase): self.assertFalse(anywarns) bad_urls = [ + 'github.com/my/proj', + 'https://github.com/foo/bar.git', + 'https://gitlab.com/group/subgroup/project.git', 'https://raw.githubusercontent.com/Seva-coder/Finder/master/ChangeLog.txt', 'https://github.com/scoutant/blokish/blob/master/README.md#changelog', + 'http://htmlpreview.github.io/?https://github.com/my/project/blob/HEAD/index.html', ] anywarns = False logging.debug('bad urls:') From a8b7342e4c8d2bea119635f719c935368ae3d8df Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 30 Sep 2019 13:12:27 +0200 Subject: [PATCH 0148/2775] jenkins-build-all: enable deploy_process_logs for CI test fdroidserver!515 --- jenkins-build-all | 1 + 1 file changed, 1 insertion(+) diff --git a/jenkins-build-all b/jenkins-build-all index 2765ab63..34b6dfd7 100755 --- a/jenkins-build-all +++ b/jenkins-build-all @@ -82,6 +82,7 @@ else fi echo "build_server_always = True" > config.py +echo "deploy_process_logs = True" >> config.py # if the local mediawiki is available, then use it if nc -z -w1 localhost 32445; then wikiflag="--wiki" From 3801db064a4f5a9910e03a9c47b5986d03812cf9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 3 Oct 2019 23:46:34 +0200 Subject: [PATCH 0149/2775] lint: improve HTTPS check It was missing some domains, so I added another rule. @IzzySoft pointed out it was redudnant, so this removes the redudant rule and fixes the original. https://gitlab.com/fdroid/fdroidserver/merge_requests/681/diffs#note_225263464 --- fdroidserver/lint.py | 6 ++---- tests/lint.TestCase | 6 ++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index e8881a84..bc3a2388 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -33,7 +33,7 @@ options = None def enforce_https(domain): - return (re.compile(r'^[^h][^t][^t][^p][^s]://[^/]*' + re.escape(domain) + r'(/.*)?', re.IGNORECASE), + return (re.compile(r'^http://([^/]*\.)?' + re.escape(domain) + r'(/.*)?', re.IGNORECASE), domain + " URLs should always use https://") @@ -122,11 +122,9 @@ http_url_shorteners = [ http_checks = https_enforcings + http_url_shorteners + [ (re.compile(r'^(?!https?://)[^/]+'), _("URL must start with https:// or http://")), - (re.compile(r'^http://[^.]+\.(github|gitlab)\.io/'), - _("URL must start with https://")), (re.compile(r'^https://(github|gitlab)\.com(/[^/]+){2,3}\.git'), _("Appending .git is not necessary")), - (re.compile(r'^https://[^/]*(github|gitlab|bitbucket|rawgit)\.[a-zA-Z]+/([^/]+/){2,3}master/'), + (re.compile(r'^https://[^/]*(github|gitlab|bitbucket|rawgit|githubusercontent)\.[a-zA-Z]+/([^/]+/){2,3}master/'), _("Use /HEAD instead of /master to point at a file in the default branch")), ] diff --git a/tests/lint.TestCase b/tests/lint.TestCase index 65f351c0..54cfc365 100755 --- a/tests/lint.TestCase +++ b/tests/lint.TestCase @@ -102,20 +102,22 @@ class LintTest(unittest.TestCase): bad_urls = [ 'github.com/my/proj', + 'http://github.com/not/secure', 'https://github.com/foo/bar.git', 'https://gitlab.com/group/subgroup/project.git', 'https://raw.githubusercontent.com/Seva-coder/Finder/master/ChangeLog.txt', 'https://github.com/scoutant/blokish/blob/master/README.md#changelog', 'http://htmlpreview.github.io/?https://github.com/my/project/blob/HEAD/index.html', + 'http://fdroid.gitlab.io/fdroid-website', ] - anywarns = False logging.debug('bad urls:') for url in bad_urls: + anywarns = False app['SourceCode'] = url for warn in fdroidserver.lint.check_regexes(app): anywarns = True logging.debug(warn) - self.assertTrue(anywarns) + self.assertTrue(anywarns, url + " does not fail lint!") def test_check_app_field_types(self): config = dict() From 1ef4f74affb5d24038d5643000c3741a1115328a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 4 Oct 2019 11:26:52 +0200 Subject: [PATCH 0150/2775] lint: include MIT-CMU, it is so close to FSF/OSI-free MIT fdroidserver!682 https://github.com/spdx/license-list-data/issues/53 * FSF lists two closely related variants as X11 or Expat, search for "MIT license" in https://www.gnu.org/licenses/license-list.html * X11 is considered free: https://directory.fsf.org/wiki/License:X11 * Expat is considered free: https://directory.fsf.org/wiki/License:Expat * It is included in Debian, so it is DFSG-free: https://metadata.ftp-master.debian.org/changelogs//main/f/flite/flite_2.1-release-3_copyright * Fedora considers it free https://fedoraproject.org/wiki/Licensing:MIT#CMU_Style --- fdroidserver/lint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index bc3a2388..1dfc00fa 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -728,6 +728,7 @@ APPROVED_LICENSES = [ 'LiLiQ-Rplus-1.1', 'MIT', 'MIT-0', + 'MIT-CMU', 'MPL-1.0', 'MPL-1.1', 'MPL-2.0', From a7dd7a812fd217522929fd7956b17090fac3f61c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 4 Oct 2019 11:08:52 +0200 Subject: [PATCH 0151/2775] update: strip leading/tailing whitespace on author contact fields Whitespace is not valid in email addresses, URLs, or phone numbers, and the triple-t/fastlane file format generally has a newline at the end. --- fdroidserver/update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 7529dbff..c536e840 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -717,7 +717,7 @@ def _set_author_entry(app, key, f): with open(f, errors='replace') as fp: text = fp.read()[:limit] if len(text) > 0: - app[key] = text + app[key] = text.strip() def _strip_and_copy_image(in_file, outpath): From 5904aef5a7f2e03b53d92a9b56bd0d514f613af3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 4 Oct 2019 11:06:42 +0200 Subject: [PATCH 0152/2775] update: parse Triple-T v2.x layout Thanks to the very nice example from Piwigo, included here under the GPLv3+ https://github.com/Piwigo/Piwigo-Android https://gitlab.com/fdroid/fdroiddata/merge_requests/5579#note_225834868 --- fdroidserver/update.py | 10 +- .../build/org.piwigo.android/app/.gitignore | 1 + .../build/org.piwigo.android/app/build.gradle | 151 ++++++++++++++++++ .../app/src/debug/res/values/constants.xml | 5 + .../app/src/debug/res/values/strings.xml | 3 + .../java/org/piwigo/PiwigoApplication.java | 115 +++++++++++++ .../app/src/main/play/contact-email.txt | 1 + .../app/src/main/play/contact-website.txt | 1 + .../app/src/main/play/default-language.txt | 1 + .../play/listings/de-DE/full-description.txt | 5 + .../play/listings/de-DE/short-description.txt | 1 + .../src/main/play/listings/de-DE/title.txt | 1 + .../play/listings/en-US/full-description.txt | 5 + .../graphics/feature-graphic/piwigo-full.png | Bin 0 -> 1221 bytes .../en-US/graphics/icon/piwigo-icon.png | Bin 0 -> 1110 bytes .../graphics/phone-screenshots/01_Login.jpg | Bin 0 -> 964 bytes .../graphics/phone-screenshots/02_Albums.jpg | Bin 0 -> 1108 bytes .../graphics/phone-screenshots/03_Photos.jpg | Bin 0 -> 1131 bytes .../04_Albums_horizontal.jpg | Bin 0 -> 1052 bytes .../graphics/phone-screenshots/05_Menu.jpg | Bin 0 -> 985 bytes .../graphics/tablet-screenshots/01_Login.png | Bin 0 -> 748 bytes .../play/listings/en-US/short-description.txt | 1 + .../src/main/play/listings/en-US/title.txt | 1 + .../play/listings/fr-FR/full-description.txt | 5 + .../play/listings/fr-FR/short-description.txt | 1 + .../src/main/play/listings/fr-FR/title.txt | 1 + .../play/listings/kn-IN/full-description.txt | 5 + .../play/listings/kn-IN/short-description.txt | 1 + .../src/main/play/listings/kn-IN/title.txt | 1 + .../main/play/release-notes/de-DE/default.txt | 7 + .../main/play/release-notes/en-US/default.txt | 9 ++ .../main/play/release-notes/fr-FR/default.txt | 9 ++ .../main/play/release-notes/kn-IN/default.txt | 9 ++ .../build/org.piwigo.android/build.gradle | 21 +++ .../build/org.piwigo.android/settings.gradle | 2 + .../metadata/org.piwigo.android.yml | 29 ++++ tests/update.TestCase | 41 +++++ 37 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/.gitignore create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/build.gradle create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/constants.xml create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/strings.xml create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/java/org/piwigo/PiwigoApplication.java create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-email.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-website.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/default-language.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/full-description.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/short-description.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/title.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/full-description.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/feature-graphic/piwigo-full.png create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/icon/piwigo-icon.png create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/01_Login.jpg create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/02_Albums.jpg create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/03_Photos.jpg create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/04_Albums_horizontal.jpg create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/05_Menu.jpg create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/tablet-screenshots/01_Login.png create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/short-description.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/title.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/full-description.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/short-description.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/title.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/full-description.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/short-description.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/title.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/de-DE/default.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/en-US/default.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/fr-FR/default.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/kn-IN/default.txt create mode 100644 tests/triple-t-2/build/org.piwigo.android/build.gradle create mode 100644 tests/triple-t-2/build/org.piwigo.android/settings.gradle create mode 100644 tests/triple-t-2/metadata/org.piwigo.android.yml diff --git a/fdroidserver/update.py b/fdroidserver/update.py index c536e840..0d817477 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -843,7 +843,11 @@ def copy_triple_t_store_metadata(apps): logging.debug('Triple-T Gradle Play Publisher: ' + d) for root, dirs, files in os.walk(d): segments = root.split('/') - locale = segments[-2] + if segments[-2] == 'listings' or segments[-2] == 'release-notes': + locale = segments[-1] + else: + locale = segments[-2] + for f in files: if f == 'fulldescription' or f == 'full-description.txt': _set_localized_text_entry(app, locale, 'description', @@ -865,6 +869,10 @@ def copy_triple_t_store_metadata(apps): _set_localized_text_entry(app, segments[-1], 'whatsNew', os.path.join(root, f)) continue + elif f == 'default.txt' and segments[-2] == 'release-notes': + _set_localized_text_entry(app, locale, 'whatsNew', + os.path.join(root, f)) + continue elif f == 'contactEmail' or f == 'contact-email.txt': _set_author_entry(app, 'authorEmail', os.path.join(root, f)) continue diff --git a/tests/triple-t-2/build/org.piwigo.android/app/.gitignore b/tests/triple-t-2/build/org.piwigo.android/app/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/tests/triple-t-2/build/org.piwigo.android/app/build.gradle b/tests/triple-t-2/build/org.piwigo.android/app/build.gradle new file mode 100644 index 00000000..6b8dd5de --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/build.gradle @@ -0,0 +1,151 @@ +plugins { + id("com.android.application") + id("com.github.triplet.play") version "2.0.0" +} + +def isCi = "true" == System.getenv("CI") +def preDexEnabled = "true" == System.getProperty("pre-dex", "true") + + +if (project.file('../PiwigoSigning.properties').exists()) { + Properties props = new Properties() + props.load(new FileInputStream(file('../PiwigoSigning.properties'))) + + android { + signingConfigs { + release { + storeFile file("../piwigo_android_keystore.jks") + storePassword props['keystore.password'] + keyAlias 'publishing' + keyPassword props['key.password'] + } + localRelease { + storeFile file("${System.properties['user.home']}${File.separator}/.android_keystore_default") + storePassword props['keystore_default.password'] + keyAlias 'defaultRelease' + keyPassword props['key_default.password'] + } + + } + + buildTypes { + release { + signingConfig signingConfigs.release + } + localRelease { + signingConfig signingConfigs.localRelease + } + } + } + play { + defaultToAppBundles = true + track = 'beta' + } +} + +android { + compileSdkVersion 29 + defaultConfig { + applicationId "org.piwigo.android" + minSdkVersion 16 + targetSdkVersion 29 + versionCode 95 + versionName "0.9.5-beta" + multiDexEnabled true + } + buildTypes { + debug { + applicationIdSuffix ".debug" + versionNameSuffix "-debug" + } + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + flavorDimensions "default" + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + lintOptions { + disable 'InvalidPackage' + abortOnError false + } + dexOptions { + preDexLibraries = preDexEnabled && !isCi + + } + dataBinding { + enabled = true + } + testOptions { + unitTests { + returnDefaultValues = true + includeAndroidResources = true + } + } + /* Triple-T GPP is applied as plugin in all cases, so we need to configure it always */ + play { + serviceAccountCredentials = file("../upload_key.json") + } +} + +def daggerVersion = '2.23.2' +def okhttpVersion = '3.11.0' +def retrofitVersion = '2.6.1' +def assertjVersion = '1.2.0' +def acraVersion = '5.4.0' + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.annotation:annotation:1.1.0' + implementation 'com.google.android.material:material:1.0.0' + implementation 'androidx.cardview:cardview:1.0.0' + implementation 'com.android.support:multidex:1.0.3' + implementation "com.google.dagger:dagger:${daggerVersion}" + implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' + annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.1.0' + + annotationProcessor "com.google.dagger:dagger-compiler:${daggerVersion}" + implementation "com.google.dagger:dagger-android:${daggerVersion}" + implementation "com.google.dagger:dagger-android-support:${daggerVersion}" + annotationProcessor "com.google.dagger:dagger-android-processor:${daggerVersion}" + implementation "com.squareup.okhttp3:okhttp:${okhttpVersion}" + implementation "com.squareup.okhttp3:logging-interceptor:${okhttpVersion}" + implementation "com.squareup.retrofit2:retrofit:${retrofitVersion}" + implementation "com.squareup.retrofit2:converter-gson:${retrofitVersion}" + implementation "com.squareup.retrofit2:adapter-rxjava:${retrofitVersion}" + implementation 'com.squareup.picasso:picasso:2.5.2' + implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' + implementation 'io.reactivex:rxjava:1.3.2' + implementation 'io.reactivex:rxandroid:1.2.1' + implementation 'com.google.guava:guava:24.1-jre' + annotationProcessor 'com.google.guava:guava:24.1-jre' + implementation 'org.apache.commons:commons-lang3:3.8.1' + + implementation "ch.acra:acra-mail:$acraVersion" + implementation "ch.acra:acra-dialog:$acraVersion" + + implementation 'com.github.jorgecastilloprz:fabprogresscircle:1.01@aar' + implementation "com.leinardi.android:speed-dial:3.0.0" + implementation 'com.github.tingyik90:snackprogressbar:6.1.1' + implementation 'org.greenrobot:eventbus:3.1.1' + /* Don't forget to add to string libraries if you add a library here. */ + + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-beta-3' + + testImplementation 'junit:junit:4.12' + testImplementation 'org.robolectric:robolectric:4.3' + testImplementation("com.squareup.assertj:assertj-android:${assertjVersion}") { + exclude group: 'com.android.support' + } + testAnnotationProcessor "com.google.dagger:dagger-compiler:${daggerVersion}" + testImplementation 'androidx.arch.core:core-testing:2.1.0' + testImplementation 'org.mockito:mockito-core:2.19.0' + testImplementation 'com.google.guava:guava:24.1-jre' + testImplementation 'androidx.appcompat:appcompat:1.1.0' + testAnnotationProcessor 'com.google.guava:guava:24.1-jre' + testImplementation 'com.google.code.findbugs:jsr305:3.0.2' +} diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/constants.xml b/tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/constants.xml new file mode 100644 index 00000000..fe7ac7bd --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/constants.xml @@ -0,0 +1,5 @@ + + + org.piwigo.account_debug + + diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/strings.xml b/tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/strings.xml new file mode 100644 index 00000000..093dda0e --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/strings.xml @@ -0,0 +1,3 @@ + + Piwigo Debug + diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/java/org/piwigo/PiwigoApplication.java b/tests/triple-t-2/build/org.piwigo.android/app/src/main/java/org/piwigo/PiwigoApplication.java new file mode 100644 index 00000000..6037e1fb --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/java/org/piwigo/PiwigoApplication.java @@ -0,0 +1,115 @@ +/* + * Piwigo for Android + * Copyright (C) 2016-2017 Piwigo Team http://piwigo.org + * Copyright (C) 2018 Raphael Mack http://www.raphael-mack.de + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.piwigo; + +import android.app.Activity; +import android.app.Application; +import android.app.Service; +import android.content.Context; +import androidx.databinding.DataBindingUtil; +import androidx.multidex.MultiDex; + +import org.acra.ACRA; +import org.acra.ReportField; +import org.acra.annotation.AcraCore; +import org.acra.annotation.AcraDialog; +import org.acra.annotation.AcraMailSender; +import org.acra.data.StringFormat; +import org.piwigo.helper.DialogHelper; +import org.piwigo.helper.NetworkHelper; +import org.piwigo.helper.NotificationHelper; +import org.piwigo.internal.di.component.ApplicationComponent; +import org.piwigo.internal.di.component.BindingComponent; +import org.piwigo.internal.di.component.DaggerApplicationComponent; +import org.piwigo.internal.di.component.DaggerBindingComponent; +import org.piwigo.internal.di.module.ApplicationModule; + +import javax.inject.Inject; + +import dagger.android.AndroidInjector; +import dagger.android.DispatchingAndroidInjector; +import dagger.android.HasActivityInjector; +import dagger.android.HasServiceInjector; + +@AcraCore(reportContent = { ReportField.APP_VERSION_CODE, + ReportField.APP_VERSION_NAME, + ReportField.USER_COMMENT, + ReportField.SHARED_PREFERENCES, + ReportField.ANDROID_VERSION, + ReportField.CUSTOM_DATA, + ReportField.STACK_TRACE, + ReportField.BUILD, + ReportField.BUILD_CONFIG, + ReportField.CRASH_CONFIGURATION, + ReportField.DISPLAY + }, + alsoReportToAndroidFramework = true, + reportFormat = StringFormat.KEY_VALUE_LIST +) +@AcraMailSender(mailTo = "android@piwigo.org") +@AcraDialog(resCommentPrompt = R.string.crash_dialog_comment_prompt, + resText = R.string.crash_dialog_text) +public class PiwigoApplication extends Application implements HasActivityInjector, HasServiceInjector { + + @Inject DispatchingAndroidInjector dispatchingAndroidInjector; + @Inject DispatchingAndroidInjector dispatchingAndroidServiceInjector; + + private ApplicationComponent applicationComponent; + + @Override public void onCreate() { + super.onCreate(); + + new NetworkHelper(); + new NotificationHelper(getApplicationContext()); + new DialogHelper() +; initializeDependencyInjection(); + } + + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + MultiDex.install(base); + ACRA.init(this); + } + + @Override public AndroidInjector activityInjector() { + return dispatchingAndroidInjector; + } + + private void initializeDependencyInjection() { + applicationComponent = DaggerApplicationComponent.builder() + .applicationModule(new ApplicationModule(this)) + .build(); + applicationComponent.inject(this); + + BindingComponent bindingComponent = DaggerBindingComponent.builder() + .applicationComponent(applicationComponent) + .build(); + DataBindingUtil.setDefaultComponent(bindingComponent); + } + + /** + * Returns an {@link AndroidInjector} of {@link Service}s. + */ + @Override + public AndroidInjector serviceInjector() { + return dispatchingAndroidServiceInjector; + } +} \ No newline at end of file diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-email.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-email.txt new file mode 100644 index 00000000..f0291ce8 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-email.txt @@ -0,0 +1 @@ +android@piwigo.org diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-website.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-website.txt new file mode 100644 index 00000000..40046686 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-website.txt @@ -0,0 +1 @@ +https://www.piwigo.org diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/default-language.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/default-language.txt new file mode 100644 index 00000000..beb9970b --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/default-language.txt @@ -0,0 +1 @@ +en-US diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/full-description.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/full-description.txt new file mode 100644 index 00000000..69efe2c6 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/full-description.txt @@ -0,0 +1,5 @@ +Piwigo ist eine Android-APP für die freie Open Source-Foto-Hosting-Plattform Piwigo. Mit dieser App können Sie sich selbst gehostete Galerie ansehen und Fotos von Ihrem Smart-Gerät hochladen. + +Piwigo wird von einer aktiven Community von Benutzern und Entwicklern bereitgestellt. + +Piwigo ermöglicht eine eigene Fotogalerie im Internet zu erstellen und bietet viele leistungsstarke Funktionen wie Alben, Tags, Geolokalisierung, viele Anpassungsstufen, Upload von Besuchern, Privatsphäre, Kalender oder Statistiken. diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/short-description.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/short-description.txt new file mode 100644 index 00000000..4ea23371 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/short-description.txt @@ -0,0 +1 @@ +Greifen Sie auf die Bilder Ihrer Piwigo-Foto-Gallerie zu. diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/title.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/title.txt new file mode 100644 index 00000000..e0394ea1 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/title.txt @@ -0,0 +1 @@ +Piwigo diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/full-description.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/full-description.txt new file mode 100644 index 00000000..2d3e92ec --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/full-description.txt @@ -0,0 +1,5 @@ +Piwigo is a native Android Application for the free and open source photo hosting platform Piwigo. With this app you can browse you self-hosted gallery and upload photos from your smart device. + +Piwigo is built by an active community of users and developers. + +Piwigo empowers you to create your own photo gallery on the web and includes many powerful features such as albums, tags, geolocation, many levels of customization, upload by visitors, privacy, calendar or statistics. diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/feature-graphic/piwigo-full.png b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/feature-graphic/piwigo-full.png new file mode 100644 index 0000000000000000000000000000000000000000..e2d5035ae32ca14cafd6ea2fef09b59583d79d1b GIT binary patch literal 1221 zcmeAS@N?(olHy`uVBq!ia0vp^azM<_!3-pir1Y-?QY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fI+v_e9hGm8>7zwZGR2L5#(v5l!6FH=sM(@P89&x;%UX zCr4?1o9X_)oDt1HWG>L~orxk}XSn~Lp#Q&u30Vr0?d}uU5^3_kQTYE%d$=snglX}5 z{~LvVPcr>q!}Y(O|9_L{{|3STvzx9Df9mv22h9w*mF*ZV&~@7&zN`l^!tmg?toWByMv{J$vh|2)tC3;q88|Ihhh7BDd|w3P(; z1p{dYMpia97L9OkK`~|_P8Ml-d0ChB+qTct;dj78>C{mg=okyUkrrIVf*FX39KR4qtagWLrv+`887yl|G)U>pX zbX62}3SB#2{}UE*3JiPn01WP@F*32p1A!b*u;ToSAcrJ*ySpsgzCn5_ki%Kv5m^jO z``1C3(Me-=1yGQ^#M9T6{V^8{5378_W*=Z4U}W@kaSV~ToSd-0J|QJBHTii$Qp$rT zkDetydz#F~Y4n-fz}SF`i?h3YuZEBkoX{oM11bQm9Fp;t{`$fd1YyPCaf&BDMPD_8DZI(1niH$$STUB|3H595L1 zqgvt`QIe8al4_M)lnSI6j0_Adbqx)44NO7|4Xg~ztPD-H4UDV|3=W=?0hSa<8glbf zGSe#2HJDl%8$vX^J!dlqs6i5BLvVgtNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~)E N44$rjF6*2UngG%{*}?z- literal 0 HcmV?d00001 diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/icon/piwigo-icon.png b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/icon/piwigo-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..02f745b92402a2ac17c498d29455468130f93fde GIT binary patch literal 1110 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TGEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$Ysfr0T*fKP}kP{IFlhW~X8 z|Erk7^g(tBakCyt;s6T%Dq%Q0v*g01D;Fgw(7+q7lN zzrD@>H|4BdyVlp&*U!(-$H%9wt*yJK_sNBQ|J&vM9GlkK-s$b_-PzT3;?SP|GwuEy zo8Hpa5f&C!TUYmgmi_-Ng)3LCiin6PudI4};lTe+h5tQjFRmUbDk%#M4O_it-M<6f z|0@{(FAKkav0tSq@Jw9=v<*(7VgK|Lv;# z-y-q9itT^9?EfCs|Bb@`%NYOv|F5-rvKBDfOiP0Nf`K$66B84o_`RIUD-E;Md$I6PyDZcD#-upoD&Y0xw?lP4lp{g0k;VkfoEC!~# z>mbbNq%pe!D9B#o>Fdh=n2UvnRX$;}&pMzUF;5rA5RLQ62@-M*6DQ7W73H{bW2VH$ zlSKtZg`Yos`1Fz6;LsCE*4CERR#%s!M_OA|ea@cI)zMkIMs;b+(o~6qQ7KQKJb5B2 zGIh$+(2(4mw{PCQm6f@A<*KQP;-x4*zjJ!)^4`hKi#z9c?w-SgH!Li-tPC>K<>T%D zHyl{-Kwtw4%YmhHoev*UR$9C$IqC774Ib6U)m79~)zp_RS+>+V*~>aLB~29w+)|!D zsY;%B?lilnx~RxAk;IAL^z=O0Uh3&;uRoBqqc}CRG%P8p$Tv6ER&2SYrMZcj>Gmz# zww5P+o-sK%J-ndYKRb~=ubhxKqWBoj5ZlKECIbXggUSiwS7SS+q zBd7A=4Xg~iccw2?>vk;%2AXP#YeY#(Vo9o1a#1RfVlXl=wA3{;&^0g#F*L9;Ftai= z)iyA)GB7xJP6n8Dku>Dyr(~v8qH8d z<-p*J6DMB+Di#G=fouu`11k$qSW%FH8E6V4D_jz21|zGW2t#7y!iyh-{@-HYVP*un zhgp!pp5aQU+0w(4vp<}jS~hjN?Q1uW+PwXd#e4x}&88eIdme7(Ntt6Vw)wW{&8Ru7 zLVM5jIV<^WxLRW!l2KM<+WR_h=Ds7n!5>7~SKBRW{V`R?JE`HZ)S4Dm_uxA}&TB7{ z%m<6Z-!743><_TY+~vHL+?_;hQpTSoQ99)B{UU20r5#VIRnz9+IS$o1kQ&oh;Vf3HMrvfem7 z%13u`!J4iarq$u= za_)}zMj}@{pV)a!YF~5Zi|3QrTTXJz`W#nQ$=4jU)n!u1n#H!QQNX~%+v4O==FMAT z4;MEXc6Hufbx8H~u5A~MgEwjw&HJ#cRP%Ee)5M95fg4wvtySaTU2$yV#57US)+D*L z%i_c2Iz?@@%66z7-YBRxZKufOb46?26?FAjwjRhTzb?Pe{+yLnVx67*ZS}w2{~6}> LP5SWO{{Kw?n6+UH literal 0 HcmV?d00001 diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/02_Albums.jpg b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/02_Albums.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c21b517bdf944abff086fd6490e4480e0664f3f8 GIT binary patch literal 1108 zcmex=_9m!0iYZc6C)!VJ5-*9m6?r+osokFveN-{DqF$4XJ0PGwL%q(m`DMLX9MivGpb~aX4s4NpBGYc!5AUlVUu!v(K zgP5YaTdH$lNa%;8DGN7V`G1Rn2WS+NAhRHYJwws96LaGhl-1@(i$`C4t5%i}vAOA? z-vgyNnr*v-^sXizxwTQ~kviKNr={J87S8=?IL)T;)OMT4^9&xPd|w`Hx;_3C>l=1! zH3`!-o|?Rqa*VI*`Uhp$o_Jy-wt0TR(aT$N!&YzXO>EEI4hqs7wVanzYN)bAmX_GRpxd<{JRM_DY@FbZd``P3U zgLyWavIE{GUh($Zk)yIRWX%iHQ!>gqCyW;O%B{^hyEa0jAmNf-QkY=xOeg1>vjWSs zmI>egbR?jaPqnc$_(H}Gy}s^flOPer_hFWa4uMC*xieQEF?X37c*LkO=A?joN}y53 zlI+0ctT|3VPcv8lKd(ok_mfQ+@xn>s%9%x)rv|06X($u#7zOo|! zN-x+2Jbz_lugKjr>;SvKXw(ZdYv%i z+UDqEJQH0dT^=5uu!lYTTs51~OqPWkn>#q3vA0JBmA>-!J5#vzOWWF7XZwmbSz9x_ ze5Y4vZvGtg&~RI+`rh7um-3p-XPgLb$!(HizA7TjBhjreiCgMi`EK#Rub1`)-hQ`Y zSJtMZOF6zDI>Y$!{qlZYPw}BlDuE(veg**2%d)m0EwGHuPWrKD+lHKKH%+f+4oM)Mlu8S^JBUTE{V^ccJkJerJIlY=Uv^qs6t@+2KRP6^A^HTXj!7I-4E=6}P zKaJk%t4ps}@gDno`>u254fE|e9_zAa@4Ikhm-ocd;Hs8|=WACRInO%!{-yoAg0Cz| z8nb0)OgsAGsPSn|l|G)ly0cboD_9hkA6=C+E9++5&ZleNm7R)Mn{#bN*R0*9Z1-lZ z&CUL~ZE-}C;fGU)QYCwTw0%~UPw3uyZTs3B)-LYHPg>fpp8FLg_;Jw*$Cg!|x=Kye zHd(IPzyH&GF{XOQr3`GdIq@ z9ldYv-mn{StEEo8-nqVi(yOeee4o>=mvCvXDcHX`G=5v?)o5;$qSv|&;qfAq*Z45@ z@+os1zrh!rS$xdhdAhpCwtOGG=9ujBS=;(HW`7U;t-WZCzL-?(aSI7^i^fw1JBtoo zZn^mTqEf%1fuoMoS(Tbp6`9ZH;=8x6iw%5zKJeA~m$rphPi*y#x|s4e=BF03{0wbr zelBsvgFQ2E$XF@KJoH(bb%IT-f=R}py^V44WBzy7r#@szV_avMW3amYoRQ)|UfTw- zCn6^wDygsCA>5U{s4bAaMt8#W5^de?hwX+>T7$Y$YLg;{1=>>d%_iFP-`K_2ILDA3n?vkXrje k*u1=1@!_jE;(uesOJA>fFE3yIVB_CA_q{*;e)<0<0Q+aQJpcdz literal 0 HcmV?d00001 diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/04_Albums_horizontal.jpg b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/04_Albums_horizontal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..27a60e30f7036306a8e9a82b12591a90de8dc191 GIT binary patch literal 1052 zcmex=PlTNqeaSlD5bOw5cdtb#(q3~cNiMkSlJ zh$t$Xm=+fQzs11A%m{QIvmk>#LyT4UtyOAIUifw|SKGO3HmiJ)bh6#uIoumv&wF_U zF9{A`?Y>RshTz4Fv&)Y8Xa~Lida}mN$EG1VcUwSP!A|*GP3PT9^Hx2V7Pq?ma^v^E zi{%}rY;lb{Ia5zTSZVnaQ6qsTS7-L<`f7sXH*|_zPPJ%iJ{MQEEx!3Bg;)P zeAd?erq_Q*dz`zr{ahPMM6}P%oMR5zetlXVdyZs#Kg<_l`LnD?%*f5PIpgJWeSpAxHz_>xYzT4kp7xGj4zu}{dRnm1L?+`+t>7|Jc~PELeX+{q&7*p+6e>h5s|`{B^wl|4jf*r-z&X literal 0 HcmV?d00001 diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/05_Menu.jpg b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/05_Menu.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6dc4cdf1a0bed98ee04d25152a4c0f95c289dc64 GIT binary patch literal 985 zcmex=^c; ziHIw?CMFdIh9;*tE&TBR76T8^MNERsf(-TyXN<0Xv|pig?(t!1i@tkVaz&xv-6PhA zI@5)>8(4I(ugeJlJqJsiDXstxzrDZ>a4}*@?v_hw4}#Zdhp%lW^wm zmVTiN)BZC=T)uE^uC8vYyrSJFov2B-Pfsmg6Sl~$dFFBU6Rh^~ZIZv8PCnF1 zw^n|_7O1>NN9?%kl$~B{&)xKWbyCc0pV5P6MH$2Mif!7wCIK-nJDJ|UzPe%UV`H-q zZ6}V;$v$fxrdj8c8a-{5sdeG4zL=7qT5VbS+6S5wi4_&yc-%f%T48`8V42jZXcld;i;iuKauDb@jD2d-jXI{c9ii z_ix3Q@6Pd)`@)jWN3Cp9kUOcy_HXXW(+4Ntk2q_=xYdkX==#|Y5@E$%U(a=2QZ?ST zbmjKKRbQunzBOa{wfJ{uuUx+I>aWwpxN9lYr6K40Hc-@$4xfqoDgQ< z*wbct%xRvIzFyAMOK*SsedW3PJ?FB@qAC3HpRJE9?b@vsRJUYf+uBnS^LQlOTzWoA zJ~vSK_~@^ZW%_BAUt6~86kOY=v&km#I8Wat_w9QaL*`Do`=fd1MS)kVBpb_JZY2tH zCh9~Bc1Bk;D6?plCYUBFhH5Q7a$s(m&2YF4V{Jx2?bO;#K)Y??1NnPx!z7 nvU(`K@ZquZ`pdU}`qf+K@9QXI;e7hX{QSpXrT)yD|NkZce41|$ literal 0 HcmV?d00001 diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/tablet-screenshots/01_Login.png b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/tablet-screenshots/01_Login.png new file mode 100644 index 0000000000000000000000000000000000000000..c86cd9fde148a3b9cfb8050fb8d8ab860cef0f6d GIT binary patch literal 748 zcmeAS@N?(olHy`uVBq!ia0vp^azHG~!3-qRG}i?KDVB6cUq=Rpjs4tz5?O(Kg=CK) zUj~LMH3o);76yi2K%s^g3=E|P3=FRl7#OT(FffQ0%-I!a!@$5O72p%%>g((4uy?Sl;?%fy8ocQ+s<=^k0 z|Ns1Y=jOHW@bDYgumAk<{rk7CzkdGs^ZVDWn>R0Ay7d12hj;JZy?y)k%a(;N&Z+?AxbNlw~ zzkmP!1}fUycJk!O=g*%%d-m+{`Mo|qK9P};u|N6`Zf?%P z!ottb&(6-y$H&LW$S5c%$i~L@|NsBckd@WI;A2ekc6W)Ld*6T&$YC$>^mS!_%*DdP zDxa{~XB|-Jyr+v}h{pNkgaj8>A0GoTV{UC}W^18@RolB>h>fJTlR`!k0qSQJn(#kSA%JR{Kvcl5h z^77)+gYSw8`Th0t^Y#7t*ZfQS{_*SQ&)>g){`~cz)CwNPfCCMoQql@4vK`_EEUfJ; z><<|hD)J;g6r31n;ZVZEz~ErNQ`upP2heM(C9V-ADTyViR>?)FK#IZ0z|d0H&_LI~ zB*f6b%D~LZ&{W&N$jZRr;5iv!szcI{o1c=IR*9~`)XLZpqT%g1n>j!Y44$rjF6*2U FngAOVLJj}` literal 0 HcmV?d00001 diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/short-description.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/short-description.txt new file mode 100644 index 00000000..bd96f636 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/short-description.txt @@ -0,0 +1 @@ +Access photos in your Piwigo photo gallery. diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/title.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/title.txt new file mode 100644 index 00000000..e0394ea1 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/title.txt @@ -0,0 +1 @@ +Piwigo diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/full-description.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/full-description.txt new file mode 100644 index 00000000..65654165 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/full-description.txt @@ -0,0 +1,5 @@ +Piwigo est une application Android native pour la plate-forme d'hébergement photo gratuite et open source Piwigo. Avec cette application, vous pouvez parcourir votre galerie auto-hébergée et télécharger des photos depuis votre smartphone. + +Piwigo est développé par une communauté active d'utilisateurs et de développeurs. + +Piwigo vous permet de créer votre propre galerie de photos sur le Web et comprend de nombreuses fonctionnalités puissantes telles que des albums, des tags, la géolocalisation, de nombreux niveaux de personnalisation, le téléchargement par les visiteurs, la confidentialité, un calendrier ou de statistiques. diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/short-description.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/short-description.txt new file mode 100644 index 00000000..90d5f1f5 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/short-description.txt @@ -0,0 +1 @@ +Accédez aux photos dans votre galerie de photos Piwigo. diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/title.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/title.txt new file mode 100644 index 00000000..e0394ea1 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/title.txt @@ -0,0 +1 @@ +Piwigo diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/full-description.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/full-description.txt new file mode 100644 index 00000000..2d3e92ec --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/full-description.txt @@ -0,0 +1,5 @@ +Piwigo is a native Android Application for the free and open source photo hosting platform Piwigo. With this app you can browse you self-hosted gallery and upload photos from your smart device. + +Piwigo is built by an active community of users and developers. + +Piwigo empowers you to create your own photo gallery on the web and includes many powerful features such as albums, tags, geolocation, many levels of customization, upload by visitors, privacy, calendar or statistics. diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/short-description.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/short-description.txt new file mode 100644 index 00000000..bd96f636 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/short-description.txt @@ -0,0 +1 @@ +Access photos in your Piwigo photo gallery. diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/title.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/title.txt new file mode 100644 index 00000000..e0394ea1 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/title.txt @@ -0,0 +1 @@ +Piwigo diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/de-DE/default.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/de-DE/default.txt new file mode 100644 index 00000000..84d85227 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/de-DE/default.txt @@ -0,0 +1,7 @@ +Dies ist eine Beta-Version, mit großen Verbesserungen, aber noch nicht für den produktiven Einsatz vorgesehen. Seien Sie vorsichtig und stellen Sie sicher, ein vollständiges Backup zu haben. + +In dieser Version haben wir +- die Unterstützung für Android 4.0 und 4.1 entfernt +- neues Design und weitere Sprachen hinzugefügt +- Unterstützung der Erstellung von Alben +- automatische Korrektur der Galerie-Seite hinzugefügt (falls möglich wird automatisch HTTPS verwendet) diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/en-US/default.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/en-US/default.txt new file mode 100644 index 00000000..e2f915ca --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/en-US/default.txt @@ -0,0 +1,9 @@ +This is a beta version, with major improvements but still not intended for production use. Please be careful and ensure you have proper backups of your gallery data. + +In this version we +- dropped support for Android 4.0 "Ice Cream Sandwich" and 4.1 "Jelly Bean" +- adjusted the UI to new Piwigo style +- added German, French and initial Kannada translation +- support creation of albums +- added auto detection correction of the gallery site (automatically choosing HTTPS if possible) + diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/fr-FR/default.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/fr-FR/default.txt new file mode 100644 index 00000000..699a1549 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/fr-FR/default.txt @@ -0,0 +1,9 @@ +This is a beta version, with major improvements but still not intended for production use. Please be careful and ensure you have proper backups of your gallery data. + +Dans cette version nous avons : +- dropped support for Android 4.0 "Ice Cream Sandwich" and 4.1 "Jelly Bean" +- adjusted the UI to new Piwigo style +- added German, French and initial Kannada translation +- support creation of albums +- added auto detection correction of the gallery site (automatically choosing HTTPS if possible) + diff --git a/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/kn-IN/default.txt b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/kn-IN/default.txt new file mode 100644 index 00000000..e2f915ca --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/kn-IN/default.txt @@ -0,0 +1,9 @@ +This is a beta version, with major improvements but still not intended for production use. Please be careful and ensure you have proper backups of your gallery data. + +In this version we +- dropped support for Android 4.0 "Ice Cream Sandwich" and 4.1 "Jelly Bean" +- adjusted the UI to new Piwigo style +- added German, French and initial Kannada translation +- support creation of albums +- added auto detection correction of the gallery site (automatically choosing HTTPS if possible) + diff --git a/tests/triple-t-2/build/org.piwigo.android/build.gradle b/tests/triple-t-2/build/org.piwigo.android/build.gradle new file mode 100644 index 00000000..450ccbe8 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/build.gradle @@ -0,0 +1,21 @@ +buildscript { + repositories { + jcenter() + mavenCentral() + maven { url 'https://maven.google.com' } + google() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + } +} + +allprojects { + repositories { + google() + jcenter() + mavenCentral() + maven { url 'https://maven.google.com' } + maven { url "https://jitpack.io" } + } +} diff --git a/tests/triple-t-2/build/org.piwigo.android/settings.gradle b/tests/triple-t-2/build/org.piwigo.android/settings.gradle new file mode 100644 index 00000000..3cc36ec2 --- /dev/null +++ b/tests/triple-t-2/build/org.piwigo.android/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'Piwigo-Android' +include ':app' diff --git a/tests/triple-t-2/metadata/org.piwigo.android.yml b/tests/triple-t-2/metadata/org.piwigo.android.yml new file mode 100644 index 00000000..77aaa3eb --- /dev/null +++ b/tests/triple-t-2/metadata/org.piwigo.android.yml @@ -0,0 +1,29 @@ +Categories: + - Graphics + - Multimedia +License: GPL-3.0-or-later +AuthorName: Piwigo Mobile Apps Team +AuthorEmail: android@piwigo.org +WebSite: https://piwigo.org/ +SourceCode: https://github.com/Piwigo/Piwigo-Android +IssueTracker: https://github.com/Piwigo/Piwigo-Android/issues +Translation: https://crowdin.com/project/piwigo-android + +AutoName: Piwigo + +RepoType: git +Repo: https://github.com/Piwigo/Piwigo-Android + +Builds: + - versionName: 0.9.5-beta + versionCode: 95 + commit: v0.9.5 + subdir: app + gradle: + - yes + +AutoUpdateMode: Version v%v +UpdateCheckMode: Tags +UpdateCheckIgnore: (alpha|beta|rc|RC|dev) +CurrentVersion: 0.9.5-beta +CurrentVersionCode: 95 diff --git a/tests/update.TestCase b/tests/update.TestCase index 1b06e458..61658292 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -193,6 +193,47 @@ class UpdateTest(unittest.TestCase): locales = sorted(list(apps['org.fdroid.ci.test.app']['localized'].keys())) self.assertEqual(correctlocales, locales) + def test_insert_triple_t_2_metadata(self): + packageName = 'org.piwigo.android' + tmptestsdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, + dir=self.tmpdir) + os.rmdir(tmptestsdir) + shutil.copytree(os.path.join(self.basedir, 'triple-t-2'), tmptestsdir) + os.chdir(tmptestsdir) + + config = dict() + fdroidserver.common.fill_config_defaults(config) + config['accepted_formats'] = ('yml') + fdroidserver.common.config = config + fdroidserver.update.config = config + fdroidserver.update.options = fdroidserver.common.options + + apps = fdroidserver.metadata.read_metadata(xref=True) + self.assertTrue(packageName in apps) + fdroidserver.update.copy_triple_t_store_metadata(apps) + correctlocales = ['de-DE', 'en-US', 'fr-FR', 'kn-IN'] + app = apps[packageName] + self.assertEqual('android@piwigo.org', app['authorEmail']) + self.assertEqual('https://www.piwigo.org', app['authorWebSite']) + locales = sorted(list(app['localized'].keys())) + self.assertEqual(correctlocales, locales) + kn_IN = app['localized']['kn-IN'] + self.assertTrue('description' in kn_IN) + self.assertTrue('name' in kn_IN) + self.assertTrue('summary' in kn_IN) + en_US = app['localized']['en-US'] + self.assertTrue('whatsNew' in en_US) + + os.chdir(os.path.join('repo', packageName)) + self.assertTrue(os.path.exists(os.path.join('en-US', 'icon.png'))) + self.assertTrue(os.path.exists(os.path.join('en-US', 'featureGraphic.png'))) + self.assertTrue(os.path.exists(os.path.join('en-US', 'phoneScreenshots', '01_Login.jpg'))) + self.assertTrue(os.path.exists(os.path.join('en-US', 'sevenInchScreenshots', '01_Login.png'))) + self.assertFalse(os.path.exists(os.path.join('de-DE', 'icon.png'))) + self.assertFalse(os.path.exists(os.path.join('de-DE', 'featureGraphic.png'))) + self.assertFalse(os.path.exists(os.path.join('de-DE', 'phoneScreenshots', '01_Login.jpg'))) + self.assertFalse(os.path.exists(os.path.join('de-DE', 'sevenInchScreenshots', '01_Login.png'))) + def javagetsig(self, apkfile): getsig_dir = 'getsig' if not os.path.exists(getsig_dir + "/getsig.class"): From a72904ee23d0dcaece1402bfc19988b53e3a13da Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 7 Oct 2019 12:02:57 +0200 Subject: [PATCH 0153/2775] lint: allow Beerware and XSkat licenses These licenses were already in our repo. The are not FSF- or OSI-approved, but they are included in Debian. So for now at least, we should maintain them in our list until we have a clearer picture of how we should make the list of licenses we support. * fdroidserver!682 * https://github.com/spdx/license-list-XML/issues/876 * Beerware in Debian: https://metadata.ftp-master.debian.org/changelogs//main/libm/libmd/libmd_1.0.1-3_copyright * XSkat in Debian: https://metadata.ftp-master.debian.org/changelogs//main/x/xskat/xskat_4.0-7_copyright --- fdroidserver/lint.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 1dfc00fa..276bf555 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -657,6 +657,7 @@ APPROVED_LICENSES = [ 'Artistic-1.0-Perl', 'Artistic-1.0-cl8', 'Artistic-2.0', + 'Beerware', 'BSD-2-Clause', 'BSD-2-Clause-FreeBSD', 'BSD-2-Clause-Patent', @@ -788,6 +789,7 @@ APPROVED_LICENSES = [ 'X11', 'XFree86-1.1', 'Xnet', + 'XSkat', 'YPL-1.1', 'ZPL-2.0', 'ZPL-2.1', From d6651068136d5bf54908fb49aea94764885e187e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 15 Oct 2019 14:28:45 +0200 Subject: [PATCH 0154/2775] fix disappearing build logs when deploying --- fdroidserver/common.py | 64 +++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 059a641f..5429d924 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3253,42 +3253,41 @@ def deploy_build_log_with_rsync(appid, vercode, log_content): logging.warning(_('skip deploying full build logs: log content is empty')) return - with tempfile.TemporaryDirectory() as tmpdir: - # gzip compress log file - log_gz_path = os.path.join( - tmpdir, '{pkg}_{ver}.log.gz'.format(pkg=appid, - ver=vercode)) - with gzip.open(log_gz_path, 'wb') as f: - if isinstance(log_content, str): - f.write(bytes(log_content, 'utf-8')) - else: - f.write(log_content) + # gzip compress log file + log_gz_path = os.path.join('repo', + '{pkg}_{ver}.log.gz'.format(pkg=appid, + ver=vercode)) + with gzip.open(log_gz_path, 'wb') as f: + if isinstance(log_content, str): + f.write(bytes(log_content, 'utf-8')) + else: + f.write(log_content) - # TODO: sign compressed log file, if a signing key is configured + # TODO: sign compressed log file, if a signing key is configured - for webroot in config.get('serverwebroot', []): - dest_path = os.path.join(webroot, "repo") - if not dest_path.endswith('/'): - dest_path += '/' # make sure rsync knows this is a directory - cmd = ['rsync', - '--archive', - '--delete-after', - '--safe-links'] - if options.verbose: - cmd += ['--verbose'] - if options.quiet: - cmd += ['--quiet'] - if 'identity_file' in config: - cmd += ['-e', 'ssh -oBatchMode=yes -oIdentitiesOnly=yes -i ' + config['identity_file']] - cmd += [log_gz_path, dest_path] + for webroot in config.get('serverwebroot', []): + dest_path = os.path.join(webroot, "repo") + if not dest_path.endswith('/'): + dest_path += '/' # make sure rsync knows this is a directory + cmd = ['rsync', + '--archive', + '--delete-after', + '--safe-links'] + if options.verbose: + cmd += ['--verbose'] + if options.quiet: + cmd += ['--quiet'] + if 'identity_file' in config: + cmd += ['-e', 'ssh -oBatchMode=yes -oIdentitiesOnly=yes -i ' + config['identity_file']] + cmd += [log_gz_path, dest_path] - # TODO: also deploy signature file if present + # TODO: also deploy signature file if present - retcode = subprocess.call(cmd) - if retcode: - logging.warning(_("failed deploying build logs to '{path}'").format(path=webroot)) - else: - logging.info(_("deployed build logs to '{path}'").format(path=webroot)) + retcode = subprocess.call(cmd) + if retcode: + logging.warning(_("failed deploying build logs to '{path}'").format(path=webroot)) + else: + logging.info(_("deployed build logs to '{path}'").format(path=webroot)) def get_per_app_repos(): @@ -3321,6 +3320,7 @@ def is_repo_file(filename): return os.path.isfile(filename) \ and not filename.endswith(b'.asc') \ and not filename.endswith(b'.sig') \ + and not filename.endswith(b'.log.gz') \ and os.path.basename(filename) not in [ b'index.jar', b'index_unsigned.jar', From 7fa3c34e5b4db3b47e3571b62aae016cca3dda86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 15 Oct 2019 15:19:18 +0200 Subject: [PATCH 0155/2775] update tests for fixed log deployment+changelog --- CHANGELOG.md | 2 ++ fdroidserver/common.py | 3 +++ tests/common.TestCase | 10 ++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fb6fbf0..10cf3c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ([!669](https://gitlab.com/fdroid/fdroidserver/merge_requests/669)) ### Fixed +* fix build-logs dissapearing when deploying + ([!685](https://gitlab.com/fdroid/fdroidserver/merge_requests/685)) * do not crash when system encoding can not be retrieved ([!671](https://gitlab.com/fdroid/fdroidserver/merge_requests/671)) * checkupdates: UpdateCheckIngore gets properly observed now diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 5429d924..e63320db 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3253,6 +3253,9 @@ def deploy_build_log_with_rsync(appid, vercode, log_content): logging.warning(_('skip deploying full build logs: log content is empty')) return + if not os.path.exists('repo'): + os.mkdir('repo') + # gzip compress log file log_gz_path = os.path.join('repo', '{pkg}_{ver}.log.gz'.format(pkg=appid, diff --git a/tests/common.TestCase b/tests/common.TestCase index f99150ea..45e43f6f 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1008,8 +1008,14 @@ class CommonTest(unittest.TestCase): with mock.patch('subprocess.call', side_effect=assert_subprocess_call): - fdroidserver.common.deploy_build_log_with_rsync( - 'com.example.app', '4711', mocklogcontent) + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + fdroidserver.common.deploy_build_log_with_rsync( + 'com.example.app', '4711', mocklogcontent) + + expected_log_path = os.path.join(tmpdir, 'repo', 'com.example.app_4711.log.gz') + self.assertTrue(os.path.isfile(expected_log_path)) + with gzip.open(expected_log_path, 'r') as f: + self.assertEqual(f.read(), mocklogcontent) if __name__ == "__main__": From c954a14139578ed1656707ccfb9618cc2a38e4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 23 Oct 2019 11:04:07 +0200 Subject: [PATCH 0156/2775] update.py: fix archiving .log.gz files --- fdroidserver/update.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 0d817477..463a1c7d 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -361,6 +361,7 @@ def delete_disabled_builds(apps, apkcache, repodirs): os.path.join(repodir, apkfilename), os.path.join(repodir, apkfilename + '.asc'), os.path.join(repodir, apkfilename[:-4] + "_src.tar.gz"), + os.path.join(repodir, apkfilename[:-4] + ".log.gz"), ] for density in all_screen_densities: repo_dir = get_icon_dir(repodir, density) @@ -1879,6 +1880,7 @@ def move_apk_between_sections(from_dir, to_dir, apk): logging.info("Moving %s from %s to %s" % (apk['apkName'], from_dir, to_dir)) _move_file(from_dir, to_dir, apk['apkName'], False) _move_file(from_dir, to_dir, apk['apkName'] + '.asc', True) + _move_file(from_dir, to_dir, apk['apkName'][:-4] + '.log.gz', True) for density in all_screen_densities: from_icon_dir = get_icon_dir(from_dir, density) to_icon_dir = get_icon_dir(to_dir, density) From afaa24f2fd5888d1f10425339319ce292c5ae86e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 23 Oct 2019 12:23:37 +0200 Subject: [PATCH 0157/2775] build: fix bad regexs when removing signingConfig from srclibs I went through the source of all apps in fdroiddata for examples, and found some that use readLine() for things totally unrelated to signingConfigs. https://gitlab.com/fdroid/fdroiddata/merge_requests/4775#note_234132902 --- fdroidserver/common.py | 2 +- tests/common.TestCase | 59 +++ tests/scanner.TestCase | 9 +- .../com.seafile.seadroid2/app/build.gradle | 122 ++++++ .../org.mozilla.rocket/app/build.gradle | 414 ++++++++++++++++++ .../realm/react-native/android/build.gradle | 409 +++++++++++++++++ .../ut.ewh.audiometrytest/app/build.gradle | 41 ++ 7 files changed, 1052 insertions(+), 4 deletions(-) create mode 100644 tests/source-files/com.seafile.seadroid2/app/build.gradle create mode 100644 tests/source-files/org.mozilla.rocket/app/build.gradle create mode 100644 tests/source-files/realm/react-native/android/build.gradle create mode 100644 tests/source-files/ut.ewh.audiometrytest/app/build.gradle diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 059a641f..2a6a0dbe 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2342,7 +2342,7 @@ gradle_signing_configs = re.compile(r'^[\t ]*signingConfigs[ \t]*{[ \t]*$') gradle_line_matches = [ re.compile(r'^[\t ]*signingConfig [^ ]*$'), re.compile(r'.*android\.signingConfigs\.[^{]*$'), - re.compile(r'.*\.readLine\(.*'), + re.compile(r'.*release\.signingConfig *= *'), ] diff --git a/tests/common.TestCase b/tests/common.TestCase index f99150ea..45bae81f 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -2,6 +2,7 @@ # http://www.drdobbs.com/testing/unit-testing-with-python/240165163 +import difflib import glob import inspect import logging @@ -925,6 +926,64 @@ class CommonTest(unittest.TestCase): self.assertEqual(('1.0-free', '1', 'com.kunzisoft.fdroidtest.applicationidsuffix'), fdroidserver.common.parse_androidmanifests(paths, app)) + def test_remove_signing_keys(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + print(testdir) + shutil.copytree(os.path.join(self.basedir, 'source-files'), + os.path.join(testdir, 'source-files')) + os.chdir(testdir) + with_signingConfigs = [ + 'source-files/com.seafile.seadroid2/app/build.gradle', + 'source-files/eu.siacs.conversations/build.gradle', + 'source-files/info.guardianproject.ripple/build.gradle', + 'source-files/open-keychain/open-keychain/build.gradle', + 'source-files/open-keychain/open-keychain/OpenKeychain/build.gradle', + 'source-files/osmandapp/osmand/build.gradle', + 'source-files/ut.ewh.audiometrytest/app/build.gradle', + ] + for f in with_signingConfigs: + build_dir = os.path.join(*f.split(os.sep)[:2]) + if not os.path.isdir(build_dir): + continue + fdroidserver.common.remove_signing_keys(build_dir) + fromfile = os.path.join(self.basedir, f) + with open(f) as fp: + content = fp.read() + if 'signingConfig' in content: + with open(f) as fp: + b = fp.readlines() + with open(fromfile) as fp: + a = fp.readlines() + diff = difflib.unified_diff(a, b, fromfile, f) + sys.stdout.writelines(diff) + self.assertFalse(True) + do_not_modify = [ + 'source-files/Zillode/syncthing-silk/build.gradle', + 'source-files/at.bitfire.davdroid/build.gradle', + 'source-files/com.kunzisoft.testcase/build.gradle', + 'source-files/com.nextcloud.client/build.gradle', + 'source-files/fdroid/fdroidclient/build.gradle', + 'source-files/firebase-suspect/app/build.gradle', + 'source-files/firebase-suspect/build.gradle', + 'source-files/firebase-whitelisted/app/build.gradle', + 'source-files/firebase-whitelisted/build.gradle', + 'source-files/org.mozilla.rocket/app/build.gradle', + 'source-files/realm/react-native/android/build.gradle', + 'triple-t-2/build/org.piwigo.android/app/build.gradle', + ] + for f in do_not_modify: + build_dir = os.path.join(*f.split(os.sep)[:2]) + if not os.path.isdir(build_dir): + continue + fdroidserver.common.remove_signing_keys(build_dir) + fromfile = os.path.join(self.basedir, f) + with open(fromfile) as fp: + a = fp.readlines() + with open(f) as fp: + b = fp.readlines() + diff = list(difflib.unified_diff(a, b, fromfile, f)) + self.assertEqual(0, len(diff), 'This file should not have been modified:\n' + ''.join(diff)) + def test_calculate_math_string(self): self.assertEqual(1234, fdroidserver.common.calculate_math_string('1234')) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 6e41b905..22f9417b 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -29,13 +29,16 @@ class ScannerTest(unittest.TestCase): source_files = os.path.join(self.basedir, 'source-files') projects = { 'Zillode': 1, - 'firebase-suspect': 1 + 'firebase-suspect': 1, + 'org.mozilla.rocket': 4, + 'realm': 1, } for d in glob.glob(os.path.join(source_files, '*')): build = fdroidserver.metadata.Build() fatal_problems = fdroidserver.scanner.scan_source(d, build) - self.assertEqual(projects.get(os.path.basename(d), 0), - fatal_problems) + should = projects.get(os.path.basename(d), 0) + self.assertEqual(should, fatal_problems, + "%s should have %d errors!" % (d, should)) if __name__ == "__main__": diff --git a/tests/source-files/com.seafile.seadroid2/app/build.gradle b/tests/source-files/com.seafile.seadroid2/app/build.gradle new file mode 100644 index 00000000..55813267 --- /dev/null +++ b/tests/source-files/com.seafile.seadroid2/app/build.gradle @@ -0,0 +1,122 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + + defaultConfig { + applicationId 'com.seafile.seadroid2' + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 93 + versionName "2.2.18" + multiDexEnabled true + resValue "string", "authorities", applicationId + '.cameraupload.provider' + resValue "string", "account_type", "com.seafile.seadroid2.account.api2" + buildConfigField "String", "ACCOUNT_TYPE", '"com.seafile.seadroid2.account.api2"' + ndk { + abiFilters 'armeabi', 'armeabi-v7a', 'x86' + } + } + + lintOptions { + abortOnError false + disable 'MissingTranslation' + } + + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + signingConfigs { + debug { +// def props = new Properties() +// props.load(new FileInputStream(project.file("debugkey.properties"))) +// storeFile project.file(props.keyStore) +// storePassword props.keyStorePassword +// keyAlias props.keyAlias +// keyPassword props.keyAliasPassword + } + release { +// Signing code for manual signing +// storeFile file(System.console().readLine("\n\$ Enter keystore path: ")) +// storePassword System.console().readPassword("\n\$ Enter keystore password: ").toString() +// keyAlias System.console().readLine("\n\$ Enter key alias: ") +// keyPassword System.console().readPassword("\n\$ Enter key password: ").toString() + + def props = new Properties() + props.load(new FileInputStream(project.file("key.properties"))) + storeFile project.file(props.keyStore) + storePassword props.keyStorePassword + keyAlias props.keyAlias + keyPassword props.keyAliasPassword + } + } + + buildTypes { + debug { + debuggable true + applicationIdSuffix ".debug" + resValue "string", "authorities", defaultConfig.applicationId + '.debug.cameraupload.provider' + resValue "string", "account_type", "com.seafile.seadroid2.debug.account.api2" + buildConfigField "String", "ACCOUNT_TYPE", '"com.seafile.seadroid2.debug.account.api2"' + signingConfig signingConfigs.debug + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt' + applicationVariants.all { variant -> + variant.outputs.all { output -> + if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) { + if (variant.name == "debug") + outputFileName = "seafile-debug-" + defaultConfig.versionName + ".apk" + } + } + } + } + release { + signingConfig signingConfigs.release + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt' + applicationVariants.all { variant -> + variant.outputs.all { output -> + if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) { + if (variant.name == "release") { + outputFileName = "seafile-" + defaultConfig.versionName + ".apk" + } + } + } + } + } + } + + allprojects { + repositories { + maven { url 'https://jitpack.io' } + } + } + dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" + implementation "com.android.support:design:${rootProject.ext.supportLibVersion}" + implementation 'com.github.JakeWharton:ViewPagerIndicator:2.4.1' + implementation 'com.github.kevinsawicki:http-request:6.0' + implementation 'commons-io:commons-io:2.4' + implementation 'com.google.guava:guava:18.0' + implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.3' + implementation 'com.cocosw:bottomsheet:1.3.1' + implementation 'com.commit451:PhotoView:1.2.4' + implementation 'com.joanzapata.iconify:android-iconify-material-community:2.2.1' + testImplementation 'junit:junit:4.12' + testImplementation 'org.robolectric:robolectric:3.0' + implementation 'com.madgag.spongycastle:core:1.54.0.0' + implementation 'com.madgag.spongycastle:prov:1.54.0.0' + implementation 'com.shuyu:gsyVideoPlayer-java:2.1.0' + implementation 'com.shuyu:gsyVideoPlayer-ex_so:2.1.0' + implementation 'com.squareup.okhttp3:okhttp:3.9.1' + + implementation 'com.yydcdut:markdown-processor:0.1.3' + implementation 'ren.qinc.edit:lib:0.0.5'//editor undo redo + implementation 'com.github.tiagohm.MarkdownView:library:0.19.0' + } +} + diff --git a/tests/source-files/org.mozilla.rocket/app/build.gradle b/tests/source-files/org.mozilla.rocket/app/build.gradle new file mode 100644 index 00000000..f05d2899 --- /dev/null +++ b/tests/source-files/org.mozilla.rocket/app/build.gradle @@ -0,0 +1,414 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' +apply plugin: 'com.google.android.gms.oss-licenses-plugin' +apply from: '../buildSrc/pmd.gradle' +apply from: '../buildSrc/checkstyle.gradle' +apply from: '../buildSrc/findbugs.gradle' +apply from: 'buildscripts/l10n.gradle' + + +android { + compileSdkVersion Versions.compile_sdk + buildToolsVersion Versions.build_tools + defaultConfig { + applicationId "org.mozilla" + minSdkVersion Versions.min_sdk + targetSdkVersion Versions.target_sdk + versionCode Versions.version_code + versionName Versions.version_name + if (SystemEnv.auto_screenshot == "1") { + testInstrumentationRunner "org.mozilla.focus.test.runner.ScreenshotTestRunner" + testInstrumentationRunnerArguments clearPackageData: 'true' + } else { + // general UI test, using notAnnotation to filter out auto screenshot classes + testInstrumentationRunner "org.mozilla.focus.test.runner.CustomTestRunner" + testInstrumentationRunnerArguments clearPackageData: 'true', notAnnotation: 'org.mozilla.focus.annotation.ScreengrabOnly,android.support.test.filters.FlakyTest' + } + testInstrumentationRunnerArgument 'disableAnalytics', 'true' + + multiDexEnabled true + + vectorDrawables { + useSupportLibrary false + generatedDensities = [] + } + + def bitrise_build_number = System.getenv("BITRISE_BUILD_NUMBER") + if (bitrise_build_number?.trim()) { + versionCode bitrise_build_number.toInteger() + versionNameSuffix "(" + bitrise_build_number + ")" + } + + // used by Room, to test migrations + javaCompileOptions { + annotationProcessorOptions { + arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + } + + dexOptions { + preDexLibraries true + } + + bundle { + language { + enableSplit = false + } + density { + enableSplit = false + } + abi { + enableSplit = true + } + } + + // We have a three dimensional build configuration: + // BUILD TYPE (debug, release) + + buildTypes { + release { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + matchingFallbacks = ["firebase"] + } + debug { + def userName = System.getenv("USER") + applicationIdSuffix ".debug." + userName + versionNameSuffix applicationIdSuffix + matchingFallbacks = ["firebase_no_op"] + } + // Use a separate buildType for coverage: testCoverageEnabled produces slower code (4-5x slower + // in places that I've benchmarked), and more importantly seems to break debugging with Android Studio + // for some developers (i.e. variables can't be inspected or seen). + coverage { + initWith debug + applicationIdSuffix ".coverage" + testCoverageEnabled true + matchingFallbacks = ["debug", "firebase_no_op"] + } + // special build type to develop Firebase related stuff + firebase { + initWith debug + applicationIdSuffix ".debug.firebase" + + versionNameSuffix applicationIdSuffix + matchingFallbacks = ["debug", "firebase"] + } + } + + testBuildType "firebase" + + testOptions { + animationsDisabled = true + unitTests.returnDefaultValues = true + unitTests.includeAndroidResources = true + execution 'ANDROID_TEST_ORCHESTRATOR' + } + + // used by Room, to test migrations + sourceSets { + androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) + } + + flavorDimensions "product", "engine" + + productFlavors { + focus { + resConfigs Localization.KEPT_LOCALE + dimension "product" + + applicationIdSuffix ".rocket" + } + + preview { + dimension "product" + applicationId "gro.allizom.zelda.beta" + applicationIdSuffix "" + versionNameSuffix ".nightly" + } + + // We can build with two engines: webkit or gecko + webkit { + dimension "engine" + } + + } + + variantFilter { variant -> + def flavors = variant.flavors*.name + // We only need a nightly release for now + if (flavors.contains("preview") && variant.buildType.name != "release") { + setIgnore(true) + } + } + + sourceSets { + test { + resources { + // Make the default asset folder available as test resource folder. Robolectric seems + // to fail to read assets for our setup. With this we can just read the files directly + // and do not need to rely on Robolectric. + srcDir "${projectDir}/src/main/assets/" + } + } + + preview { + res.srcDir 'src/preview/res' + } + + // used by Room, to test migrations + androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) + } +} + +repositories { + flatDir { + dirs 'libs' + } + mavenCentral() +} + +dependencies { + implementation project(':telemetry-annotation') + kapt project(':telemetry-compiler') + + implementation project(':third_party:subsampling-scale-image-view') + implementation project(':third_party:glide:annotation') + implementation project(':third_party:glide:library') + kapt "com.github.bumptech.glide:compiler:${Versions.glide}" + + implementation project(':firebase') + implementation project(':feature-tabs') + implementation project(':HttpRequest') + implementation project(':httptask') + implementation project(':urlutils') + implementation project(':fileutils') + implementation project(':icon') + implementation project(':logger') + implementation project(':threadutils') + implementation project(':cachedrequestloader') + implementation project(':permissionhandler') + + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Versions.kotlin}" + + // We didn't use CustomTabs so far. This is a build hack to force Android-Components to use + // same version of support library as we are. Android-Components depends on CustomTabs which + // version will be override by this. + // We can get rid of this once Android-Components' issue #404 has been resolve. + implementation "com.android.support:customtabs:${Versions.support}" + implementation "com.android.support:support-v4:${Versions.support}" + implementation "com.android.support:appcompat-v7:${Versions.support}" + implementation "com.android.support:design:${Versions.support}" + implementation "com.android.support:cardview-v7:${Versions.support}" + implementation "com.android.support:recyclerview-v7:${Versions.support}" + implementation "com.android.support.constraint:constraint-layout:${Versions.constraint}" + implementation "android.arch.work:work-runtime:${Versions.arch_work}" + + + // Architecture components + implementation "android.arch.lifecycle:extensions:${Versions.lifecycle}" + implementation "android.arch.lifecycle:common-java8:${Versions.lifecycle}" + implementation "android.arch.persistence.room:runtime:${Versions.room}" + implementation "android.arch.navigation:navigation-fragment:${Versions.navigation}" + kapt "android.arch.persistence.room:compiler:${Versions.room}" + + implementation("com.google.code.findbugs:annotations:${Versions.findbugs}", { + // We really only need the SuppressFBWarnings annotation, everything else can be ignored. + // Without this we get weird failures due to dependencies. + transitive = false + }) + + implementation "org.mozilla.components:browser-session:${Versions.android_components}" + implementation "org.mozilla.components:service-telemetry:${Versions.android_components}" + implementation "org.mozilla.components:browser-domains:${Versions.android_components}" + implementation "org.mozilla.components:ui-autocomplete:${Versions.android_components}" + + implementation "com.adjust.sdk:adjust-android:${Versions.adjust}" + implementation "com.google.android.gms:play-services-analytics:${Versions.firebase}" // Required by Adjust + // Required by Adjust + + implementation "com.airbnb.android:lottie:${Versions.lottie}" + + testImplementation "junit:junit:${Versions.junit}" + testImplementation "org.robolectric:robolectric:${Versions.robolectric}" + testImplementation "org.mockito:mockito-core:${Versions.mockito}" + + androidTestImplementation("com.android.support.test.espresso:espresso-core:${Versions.espresso}", { + exclude group: 'com.android.support', module: 'support-annotations' + }) + androidTestImplementation "com.android.support.test:runner:${Versions.test_runner}" + androidTestImplementation "com.android.support.test.espresso:espresso-idling-resource:${Versions.espresso}" + androidTestImplementation "com.android.support:support-annotations:${Versions.support}" + androidTestImplementation "com.android.support.test.uiautomator:uiautomator-v18:${Versions.uiautomator}" + androidTestImplementation "com.squareup.okhttp3:mockwebserver:${Versions.mockwebserver}" + androidTestImplementation "android.arch.persistence.room:testing:${Versions.room}" + androidTestImplementation "android.arch.core:core-testing:${Versions.arch_core}" + androidTestImplementation("com.android.support.test.espresso:espresso-contrib:${Versions.espresso}", { + exclude group: 'com.android.support', module: 'appcompat' + exclude group: 'com.android.support', module: 'support-v4' + exclude module: 'recyclerview-v7' + }) + androidTestImplementation "com.android.support.test.espresso:espresso-web:${Versions.espresso}" + androidTestImplementation "com.android.support.test.espresso:espresso-intents:${Versions.espresso}" + androidTestImplementation "tools.fastlane:screengrab:${Versions.fastlane_screengrab}" + androidTestImplementation "com.jraska:falcon:${Versions.jraska_falcon}" + androidTestUtil "com.android.support.test:orchestrator:${Versions.test_runner}" + + // LeakCanary + debugImplementation "com.squareup.leakcanary:leakcanary-android:${Versions.leakcanary}" + coverageImplementation "com.squareup.leakcanary:leakcanary-android-no-op:${Versions.leakcanary}" + releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:${Versions.leakcanary}" + firebaseImplementation "com.squareup.leakcanary:leakcanary-android:${Versions.leakcanary}" + + implementation project(':bhaskar') + implementation project(':newspoint') + implementation project(':partnerrepository') +} + +// ------------------------------------------------------------------------------------------------- +// LeakCanary - Ensure the no-op dependency is always used in JVM tests. +// ------------------------------------------------------------------------------------------------- + +configurations.all { config -> + if (config.name.contains('UnitTest') || config.name.contains('AndroidTest')) { + config.resolutionStrategy.eachDependency { details -> + if (details.requested.group == 'com.squareup.leakcanary' && details.requested.name == 'leakcanary-android') { + details.useTarget(group: details.requested.group, name: 'leakcanary-android-no-op', version: details.requested.version) + } + } + } +} + +// ------------------------------------------------------------------------------------------------- +// Generate blocklists +// ------------------------------------------------------------------------------------------------- + +def blockListOutputDir = 'src/webkit/res/raw' + +task buildBlocklists(type: Copy) { + from('../shavar-prod-lists') { + include '*.json' + } + into blockListOutputDir + + // Android can't handle dashes in the filename, so we need to rename: + rename 'disconnect-blacklist.json', 'blocklist.json' + rename 'disconnect-entitylist.json', 'entitylist.json' + // google_mapping.json already has an expected name +} + +clean.doLast { + file(blockListOutputDir).deleteDir() +} + +tasks.whenTaskAdded { task -> + def name = task.name + if (name.contains("generate") && name.contains("Webkit") && name.contains("Resources")) { + task.dependsOn buildBlocklists + } +} + +// ------------------------------------------------------------------------------------------------- +// Adjust: Read token from environment variable (Only release builds) +// ------------------------------------------------------------------------------------------------- + +android.applicationVariants.all { variant -> + def variantName = variant.getName() + + print(variantName + ": ") + + // release and nightly will have Adjust. just nightly will use sandbox environment. + if (variantName.contains("Release")) { + def token = System.getenv("ADJUST_TOKEN_FOCUS") ?: null + + if (token != null) { + buildConfigField 'String', 'ADJUST_TOKEN', '"' + token + '"' + if (variantName.contains("preview")) { + buildConfigField 'String', 'ADJUST_ENVIRONMENT', 'com.adjust.sdk.AdjustConfig.ENVIRONMENT_SANDBOX' + } else if (variantName.contains("focus")) { + buildConfigField 'String', 'ADJUST_ENVIRONMENT', 'com.adjust.sdk.AdjustConfig.ENVIRONMENT_PRODUCTION' + } else { + buildConfigField 'String', 'ADJUST_ENVIRONMENT', 'null' + } + println "Added adjust token set from environment variable" + + def tracker = System.getenv("ADJUST_SIDELOAD_TRACKER") ?: null + if (tracker != null) { + buildConfigField 'String', 'ADJUST_DEFAULT_TRACKER', '"' + tracker + '"' + } else { + buildConfigField 'String', 'ADJUST_DEFAULT_TRACKER', 'null' + logger.error(variant.getName() + ": Not setting adjust default tracker (environment variable not set)") + } + } else { + buildConfigField 'String', 'ADJUST_TOKEN', 'null' + buildConfigField 'String', 'ADJUST_ENVIRONMENT', 'null' + buildConfigField 'String', 'ADJUST_DEFAULT_TRACKER', 'null' + println("Not setting adjust token (environment variable not set)") + } + } else { + buildConfigField 'String', 'ADJUST_TOKEN', 'null' + buildConfigField 'String', 'ADJUST_ENVIRONMENT', 'null' + buildConfigField 'String', 'ADJUST_DEFAULT_TRACKER', 'null' + + println("Not setting adjust token (Not a focus release build)") + } + if (variant.buildType.name == "release" || variant.buildType.name == "firebase") { + variant.assemble.doFirst { + if (SystemEnv.google_app_id == null || SystemEnv.default_web_client_id == null || + SystemEnv.firebase_database_url == null || SystemEnv.gcm_defaultSenderId == null || + SystemEnv.google_api_key == null || SystemEnv.google_crash_reporting_api_key == null || + SystemEnv.project_id == null) { + logger.warn("If you want to enable Firebase, please follow the steps:") + logger.warn("1. Download google-services.json and put it in the folder where you run below command.") + logger.warn("2. Run 'python./tools/firebase/firebase_setup.py' and follow the steps.\n") + } + } + } +} + +tasks.whenTaskAdded { task -> + if (name.contains("compile")) { + task.dependsOn generatePreviewLocaleList + task.dependsOn generateFocusLocaleList + } +} + +tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { + kotlinOptions { + kotlinOptions.allWarningsAsErrors = true + } +} + + + +afterEvaluate { + check.dependsOn 'findbugs', 'pmd', 'checkstyle', 'checkTelemetryDocDirty', 'ktlint' +} + +task checkTelemetryDocDirty() { + + doLast { + Process p = Runtime.getRuntime().exec("git diff ./docs/events.md"); + p.waitFor(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); + + StringBuilder sb = new StringBuilder(); + String line = ""; + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + if (sb.length() > 0) { + throw new GradleException("events.md is drity, please commit the change first.\n" + sb.toString()) + } + } +} diff --git a/tests/source-files/realm/react-native/android/build.gradle b/tests/source-files/realm/react-native/android/build.gradle new file mode 100644 index 00000000..d6244d2b --- /dev/null +++ b/tests/source-files/realm/react-native/android/build.gradle @@ -0,0 +1,409 @@ +buildscript { + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'de.undercouch:gradle-download-task:1.2' + } +} + +allprojects { + repositories { + google() + jcenter() + mavenLocal() + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url "$projectDir/../../tests/react-test-app/node_modules/react-native/android" + } + } +} + +apply plugin: 'com.android.library' +apply plugin: 'maven' +apply plugin: 'signing' +apply plugin: 'de.undercouch.download' + +import de.undercouch.gradle.tasks.download.Download +import org.apache.tools.ant.taskdefs.condition.Os +import org.apache.tools.ant.filters.ReplaceTokens + +// We download various C++ open-source dependencies into downloads. +// We then copy both the downloaded code and our custom makefiles and headers into third-party-ndk. +// After that we build native code from src/main/jni with module path pointing at third-party-ndk. + + +ext.coreVersion = getDependenciesVersion("REALM_CORE_VERSION").trim() +ext.syncVersion = getDependenciesVersion("REALM_SYNC_VERSION").trim() +def currentVersion = getDependenciesVersion("VERSION").trim() +println "Realm Core Version: $ext.coreVersion" +println "Realm Sync Version: $ext.syncVersion" + +def downloadsDir = new File("$projectDir/downloads") +def jscDownloadDir = new File("$projectDir/src/main/jni/jsc") +def coreDownloadDir = new File("$projectDir/src/main/jni") +def publishDir = new File("$projectDir/../../android/") +// to build with sync run: ./gradlew assembleDebug -PbuildWithSync=true +ext.buildSync = project.hasProperty('buildWithSync') ? project.getProperty('buildWithSync').toBoolean() : true + +task generateVersionClass(type: Copy) { + from 'src/main/templates/Version.java' + into 'build/generated-src/main/java/io/realm/react' + filter(ReplaceTokens, tokens: [version: currentVersion]) + outputs.upToDateWhen { false } +} + +task createNativeDepsDirectories { + downloadsDir.mkdirs() +} + +task downloadJSCHeaders(type: Download) { + def jscAPIBaseURL = 'https://svn.webkit.org/repository/webkit/!svn/bc/174650/trunk/Source/JavaScriptCore/API/' + def jscHeaderFiles = ['JSBase.h', 'JSContextRef.h', 'JSObjectRef.h', 'JSRetainPtr.h', 'JSStringRef.h', 'JSValueRef.h', 'WebKitAvailability.h'] + + def output = new File(jscDownloadDir, 'JavaScriptCore') + output.mkdirs() + src(jscHeaderFiles.collect { headerName -> "$jscAPIBaseURL$headerName" }) + onlyIfNewer true + overwrite false + dest output + } + +task downloadRealmCore(type: Download) { + if (project.buildSync) { + src "https://static.realm.io/downloads/sync/realm-sync-android-${project.syncVersion}.tar.gz" + } else { + src "https://static.realm.io/downloads/core/realm-core-android-${project.coreVersion}.tar.gz" + } + onlyIfNewer true + overwrite true + if (project.buildSync) { + dest new File(downloadsDir, "realm-core-android-${project.syncVersion}.tar.gz") + } else { + dest new File(downloadsDir, "realm-core-android-${project.coreVersion}.tar.gz") + } +} + +task prepareRealmCore(dependsOn: downloadRealmCore, type:Copy) { + from tarTree(downloadRealmCore.dest) + into "$coreDownloadDir/core" + rename { String fileName -> + fileName.replace("-arm-", "-armeabi-") + } +} + +task downloadOpenSSL_x86(type: Download) { + src "https://static.realm.io/downloads/openssl/1.0.2k/Android/x86/openssl-release-1.0.2k-Android-x86.tar.gz" + onlyIfNewer true + overwrite true + dest new File(downloadsDir, "openssl-release-1.0.2k-Android-x86.tar.gz") +} + +task prepareOpenSSL_x86(dependsOn: downloadOpenSSL_x86, type:Copy) { + from tarTree(downloadOpenSSL_x86.dest) + into "$coreDownloadDir/core" +} + +task downloadOpenSSL_arm(type: Download) { + src "https://static.realm.io/downloads/openssl/1.0.2k/Android/armeabi-v7a/openssl-release-1.0.2k-Android-armeabi-v7a.tar.gz" + onlyIfNewer true + overwrite true + dest new File(downloadsDir, "openssl-release-1.0.2k-Android-armeabi-v7a.tar.gz") +} + +task prepareOpenSSL_arm(dependsOn: downloadOpenSSL_arm, type:Copy) { + from tarTree(downloadOpenSSL_arm.dest) + into "$coreDownloadDir/core" + rename { String fileName -> + fileName.replace("-arm-", "-armeabi-") + } +} + +def getDependenciesVersion(keyName) { + def inputFile = new File(buildscript.sourceFile.getParent() + "/../../dependencies.list") + def line + inputFile.withReader { reader -> + while ((line = reader.readLine())!=null) { + def (key, value) = line.tokenize('=') + if (keyName == key) { + return value + } + } + + throw new GradleException("${keyName} not found in dependencies.list.") + } +} + +def getNdkBuildName() { + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + return "ndk-build.cmd" + } else { + return "ndk-build" + } +} + +def findNdkBuildFullPath() { + // we allow to provide full path to ndk-build tool + if (hasProperty('ndk.command')) { + return property('ndk.command') + } + // or just a path to the containing directory + if (hasProperty('ndk.path')) { + def ndkDir = property('ndk.path') + return new File(ndkDir, getNdkBuildName()).getAbsolutePath() + } + if (System.getenv('ANDROID_NDK') != null) { + def ndkDir = System.getenv('ANDROID_NDK') + return new File(ndkDir, getNdkBuildName()).getAbsolutePath() + } + if (System.getenv('ANDROID_NDK_HOME') != null) { + def ndkDir = System.getenv('ANDROID_NDK_HOME') + return new File(ndkDir, getNdkBuildName()).getAbsolutePath() + } + def ndkDir = android.hasProperty('plugin') ? android.plugin.ndkFolder : + plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder() + if (ndkDir) { + return new File(ndkDir, getNdkBuildName()).getAbsolutePath() + } + return null +} + +def checkNdkVersion(ndkBuildFullPath) { + def ndkPath = new File(ndkBuildFullPath).getParent() + def detectedNdkVersion + def releaseFile = new File(ndkPath, 'RELEASE.TXT') + def propertyFile = new File(ndkPath, 'source.properties') + if (releaseFile.isFile()) { + detectedNdkVersion = releaseFile.text.trim().split()[0].split('-')[0] + } else if (propertyFile.isFile()) { + detectedNdkVersion = getValueFromPropertiesFile(propertyFile, 'Pkg.Revision') + if (detectedNdkVersion == null) { + throw new GradleException("Failed to obtain the NDK version information from ${ndkPath}/source.properties") + } + } else { + throw new GradleException("Neither ${releaseFile.getAbsolutePath()} nor ${propertyFile.getAbsolutePath()} is a file.") + } + if (detectedNdkVersion != project.ndkVersion) { + throw new GradleException("Your NDK version: ${detectedNdkVersion}." + + " Realm JNI must be compiled with the version ${project.ndkVersion} of NDK.") + } +} + +static def getValueFromPropertiesFile(File propFile, String key) { + if (!propFile.isFile() || !propFile.canRead()) { + return null + } + def prop = new Properties() + def reader = propFile.newReader() + try { + prop.load(reader) + } finally { + reader.close() + } + return prop.get(key) +} + +def getNdkBuildFullPath() { + def ndkBuildFullPath = findNdkBuildFullPath() + if (ndkBuildFullPath == null) { + throw new GradleScriptException( + "ndk-build binary cannot be found, check if you've set " + + "\$ANDROID_NDK environment variable correctly or if ndk.dir is " + + "setup in local.properties", + null) + } + if (!new File(ndkBuildFullPath).canExecute()) { + throw new GradleScriptException( + "ndk-build binary " + ndkBuildFullPath + " doesn't exist or isn't executable.\n" + + "Check that the \$ANDROID_NDK environment variable, or ndk.dir in local.proerties, is set correctly.\n" + + "(On Windows, make sure you escape backslashes in local.properties or use forward slashes, e.g. C:\\\\ndk or C:/ndk rather than C:\\ndk)", + null) + } + + checkNdkVersion(ndkBuildFullPath); + + return ndkBuildFullPath +} + +task buildReactNdkLib(dependsOn: [downloadJSCHeaders,prepareRealmCore,prepareOpenSSL_x86,prepareOpenSSL_arm], type: Exec) { + inputs.files('src/main/jni') + outputs.dir("$buildDir/realm-react-ndk/all") + commandLine getNdkBuildFullPath(), + '-e', + project.buildSync ? 'BUILD_TYPE_SYNC=1' : 'BUILD_TYPE_SYNC=0', + 'NDK_PROJECT_PATH=null', + "NDK_APPLICATION_MK=$projectDir/src/main/jni/Application.mk", + 'NDK_OUT=' + temporaryDir, + "NDK_LIBS_OUT=$buildDir/realm-react-ndk/all", + '-C', file('src/main/jni').absolutePath, + 'NDK_LOG=1', + 'NDK_DEBUG=' + (DEBUG_BUILD.toBoolean() ? '1' : '0'), + '--jobs', Runtime.runtime.availableProcessors(), + 'V=1' +} + +task cleanReactNdkLib(type: Exec) { + commandLine getNdkBuildFullPath(), + '-C', file('src/main/jni').absolutePath, + 'clean' +} + +task packageReactNdkLibs(dependsOn: buildReactNdkLib, type: Copy) { + from "$buildDir/realm-react-ndk/all" + exclude '**/libjsc.so' + exclude '**/gdbserver' + exclude '**/gdb.setup' + into "$buildDir/realm-react-ndk/exported" +} + +android { + compileSdkVersion 26 + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 26 + } + + sourceSets.main { + java.srcDir "$buildDir/generated-src/main/java" + jni.srcDirs = [] + jniLibs.srcDir "$buildDir/realm-react-ndk/exported" + res.srcDirs = ['src/main/res/devsupport', 'src/main/res/shell'] + } + + tasks.withType(JavaCompile) { + compileTask -> compileTask.dependsOn generateVersionClass, packageReactNdkLibs + } + + clean.dependsOn cleanReactNdkLib + + lintOptions { + abortOnError false + } +} + +task publishAndroid(dependsOn: [generateVersionClass, packageReactNdkLibs], type: Sync) { + // Copy task can only have one top level + into "$publishDir" + + // copy java source + into ('/src/main') { + from "$projectDir/src/main", "$buildDir/generated-src/main" + exclude '**/jni/**', '**/templates/**' + } + + // add compiled shared object + into ('/src/main/jniLibs') { + from "$buildDir/realm-react-ndk/exported/" + } + + // copy gradle wrapper files + FileTree gradleWrapper = fileTree(projectDir).include('gradlew*').include('gradle/**') + into ('/') { + from gradleWrapper + } + + // copy and rename template build.gradle + into ('/') { + from "$projectDir/publish_android_template" + rename { String fileName -> + 'build.gradle' + } + } + + // copy analytics script + into ('/') { + from "$projectDir/analytics_template" + rename { String fileName -> + 'analytics.gradle' + } + } +} + +// publishing into maven local + +def configureRealmReactNativePom(def pom) { + pom.project { + name POM_NAME + artifactId POM_ARTIFACT_ID + packaging POM_PACKAGING + description POM_DESCRIPTION + url 'https://github.com/realm/realm-js' + + issueManagement { + system 'github' + url 'https://github.com/realm/realm-js/issues' + } + + scm { + url 'scm:https://github.com/realm/realm-js' + connection 'scm:git@github.com:realm/realm-js.git' + developerConnection 'scm:git@github.com:realm/realm-js.git' + } + + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + } +} + +afterEvaluate { project -> + task androidSourcesJar(type: Jar) { + classifier = 'sources' + from android.sourceSets.main.java.srcDirs + include '**/*.java' + } + + android.libraryVariants.all { variant -> + def name = variant.name.capitalize() + task "jar${name}"(type: Jar, dependsOn: variant.javaCompile) { + from variant.javaCompile.destinationDir + } + } + + artifacts { + archives androidSourcesJar + } + + version = currentVersion + group = GROUP + + signing { + required { false } + sign configurations.archives + } + + task installArchives(type: Upload) { + configuration = configurations.archives + repositories.mavenDeployer { + beforeDeployment { + MavenDeployment deployment -> signing.signPom(deployment) + } + + repository url: "file://${System.properties['user.home']}/.m2/repository" + configureRealmReactNativePom pom + } + } +} + +def dependencyType = "implementation" +def providedDependencyType = "compileOnly" +try { + project.getConfigurations().getByName("implementation") +} catch (UnknownConfigurationException e) { + // Pre 3.0 Android Gradle Plugin + dependencyType = "compile" + providedDependencyType = "provided" +} + +project.dependencies { + add(providedDependencyType, 'com.squareup.okhttp3:okhttp:3.9.0') + add(providedDependencyType, 'com.facebook.react:react-native:+') + add(dependencyType, 'org.nanohttpd:nanohttpd:2.2.0') +} diff --git a/tests/source-files/ut.ewh.audiometrytest/app/build.gradle b/tests/source-files/ut.ewh.audiometrytest/app/build.gradle new file mode 100644 index 00000000..640b6678 --- /dev/null +++ b/tests/source-files/ut.ewh.audiometrytest/app/build.gradle @@ -0,0 +1,41 @@ +apply plugin: 'android' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.1" + + defaultConfig { + minSdkVersion 8 + targetSdkVersion 21 + versionCode 14 + versionName "1.65" + } + signingConfigs{ + releaseSign{ + storeFile file("/Users/reecestevens/keys/keystore.jks") + //storePassword System.console().readLine("\nKeystore password: ") + storePassword System.getenv("KSTOREPWD") + keyAlias "AppKey" + //keyPassword System.console().readLine("\nKey password: ") + keyPassword System.getenv("KEYPWD") + } + } + buildTypes { + release { + minifyEnabled true; + debuggable false + signingConfig signingConfigs.releaseSign + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +repositories { + maven { url "https://jitpack.io" } +} + +dependencies { + compile 'com.android.support:appcompat-v7:21.0.2' + compile 'com.github.PhilJay:MPAndroidChart:v2.0.9' + compile fileTree(dir: 'libs', include: ['*.jar']) +} From 828d164fb2fb74a211febf83c553b2224d7f70bc Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Wed, 30 Oct 2019 20:41:21 +0000 Subject: [PATCH 0158/2775] Gradle 5.6.3 --- gradlew-fdroid | 3 ++- makebuildserver | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index ee1698ad..7446d5df 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -125,6 +125,7 @@ get_sha() { '5.6') echo '15c02ef5dd3631ec02ac52e8725703e0285d9a7eecbf4e5939aa9e924604d01d' ;; '5.6.1') echo '0986244820e4a35d32d91df2ec4b768b5ba5d6c8246753794f85159f9963ec12' ;; '5.6.2') echo '32fce6628848f799b0ad3205ae8db67d0d828c10ffe62b748a7c0d9f4a5d9ee0' ;; + '5.6.3') echo '60a6d8f687e3e7a4bc901cc6bc3db190efae0f02f0cc697e323e0f9336f224a3' ;; *) exit 1 esac } @@ -145,7 +146,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index cf689af4..ea4907f1 100755 --- a/makebuildserver +++ b/makebuildserver @@ -358,8 +358,8 @@ CACHE_FILES = [ '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc'), ('https://services.gradle.org/distributions/gradle-5.5.1-bin.zip', '222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00'), - ('https://services.gradle.org/distributions/gradle-5.6.2-bin.zip', - '32fce6628848f799b0ad3205ae8db67d0d828c10ffe62b748a7c0d9f4a5d9ee0'), + ('https://services.gradle.org/distributions/gradle-5.6.3-bin.zip', + '60a6d8f687e3e7a4bc901cc6bc3db190efae0f02f0cc697e323e0f9336f224a3'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 3c398e2aa6af89150b6325d21958f6a9c330dce6 Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Sat, 2 Nov 2019 18:40:58 +0000 Subject: [PATCH 0159/2775] remove redundant google analytics match 'google.*play.*services' and 'firebase' will catch both manners of including analytics I think https://developers.google.com/android/guides/setup#split https://firebase.google.com/support/release-notes/android#latest_sdk_versions This has the desired side effect of also allowing the libre analytics library 'net.mikehardy:google-analytics-java' and 'net.mikehardy:google-analytics-java7' --- fdroidserver/scanner.py | 1 - 1 file changed, 1 deletion(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index bc07f8a9..acc19e72 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -61,7 +61,6 @@ def scan_source(build_dir, build=metadata.Build()): exp: re.compile(r'.*' + exp, re.IGNORECASE) for exp in [ r'flurryagent', r'paypal.*mpl', - r'google.*analytics', r'admob.*sdk.*android', r'google.*ad.*view', r'google.*admob', From 3648ef1f2e21fd9e9853e7af87109e8f7825e06c Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Sat, 2 Nov 2019 18:54:54 +0000 Subject: [PATCH 0160/2775] Update scanner.TestCase to match new regex regime scanning for analytics is now handled by firebase/play-services regexes --- tests/scanner.TestCase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 22f9417b..6e94d5fb 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -30,7 +30,7 @@ class ScannerTest(unittest.TestCase): projects = { 'Zillode': 1, 'firebase-suspect': 1, - 'org.mozilla.rocket': 4, + 'org.mozilla.rocket': 3, 'realm': 1, } for d in glob.glob(os.path.join(source_files, '*')): From cca78114cb15e3056c3496c0ca7c07b66e400ea9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 5 Nov 2019 15:30:34 +0100 Subject: [PATCH 0161/2775] gitlab-ci: fedora no longer installs difftools by default --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 96fc53a9..415a39b0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -171,6 +171,7 @@ fedora_latest: - dnf -y update || dnf -y update - dnf -y install @development-tools + diffutils findutils git gnupg From f7f9bea1f746b22b6f07a5ea20e9b051d643b72f Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 6 Nov 2019 08:59:44 +0100 Subject: [PATCH 0162/2775] Gradle 5.6.4 https://gitlab.com/fdroid/fdroidserver/-/jobs/342228827 https://gradle.org/release-checksums/ --- gradlew-fdroid | 3 ++- makebuildserver | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 7446d5df..0e5dc5de 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -126,6 +126,7 @@ get_sha() { '5.6.1') echo '0986244820e4a35d32d91df2ec4b768b5ba5d6c8246753794f85159f9963ec12' ;; '5.6.2') echo '32fce6628848f799b0ad3205ae8db67d0d828c10ffe62b748a7c0d9f4a5d9ee0' ;; '5.6.3') echo '60a6d8f687e3e7a4bc901cc6bc3db190efae0f02f0cc697e323e0f9336f224a3' ;; + '5.6.4') echo '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d' ;; *) exit 1 esac } @@ -146,7 +147,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index ea4907f1..03b1aa4c 100755 --- a/makebuildserver +++ b/makebuildserver @@ -358,8 +358,8 @@ CACHE_FILES = [ '7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc'), ('https://services.gradle.org/distributions/gradle-5.5.1-bin.zip', '222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00'), - ('https://services.gradle.org/distributions/gradle-5.6.3-bin.zip', - '60a6d8f687e3e7a4bc901cc6bc3db190efae0f02f0cc697e323e0f9336f224a3'), + ('https://services.gradle.org/distributions/gradle-5.6.4-bin.zip', + '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 2cbde77798374eb93d158dc43265ce146940caa0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 13 Nov 2019 11:58:55 +0100 Subject: [PATCH 0163/2775] build: do not crash if SVN URL pre-validation fails; log error This is the problem: https://jenkins.debian.net/job/reproducible_fdroid_build_apps/704/console --- fdroidserver/common.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 9fa6072d..033aaebf 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1034,9 +1034,12 @@ class vcs_gitsvn(vcs): raise VCSException(_('HTTPS must be used with Subversion URLs!')) # git-svn sucks at certificate validation, this throws useful errors: - import requests - r = requests.head(remote) - r.raise_for_status() + try: + import requests + r = requests.head(remote) + r.raise_for_status() + except Exception as e: + raise VCSException('SVN certificate pre-validation failed: ' + str(e)) location = r.headers.get('location') if location and not location.startswith('https://'): raise VCSException(_('Invalid redirect to non-HTTPS: {before} -> {after} ') From 3354e66bd379f02c1ebfcc656c31f9f41ebb1509 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 1 Nov 2019 17:36:49 +0100 Subject: [PATCH 0164/2775] common: use standard format tags when generating the log name --- fdroidserver/common.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 033aaebf..99b3a5ed 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3261,8 +3261,9 @@ def deploy_build_log_with_rsync(appid, vercode, log_content): # gzip compress log file log_gz_path = os.path.join('repo', - '{pkg}_{ver}.log.gz'.format(pkg=appid, - ver=vercode)) + '{appid}_{versionCode}.log.gz'.format(appid=appid, + versionCode=vercode)) + with gzip.open(log_gz_path, 'wb') as f: if isinstance(log_content, str): f.write(bytes(log_content, 'utf-8')) From e6bf586e748e8c85a4a2deda9c22d9e447422210 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 1 Nov 2019 17:38:08 +0100 Subject: [PATCH 0165/2775] common: make v2 signature message a debug message https://gitlab.com/fdroid/fdroidserver/issues/703#note_238122327 closes #703 --- fdroidserver/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 99b3a5ed..7e145519 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2537,12 +2537,12 @@ def get_first_signer_certificate(apkpath): apkobject = _get_androguard_APK(apkpath) certs = apkobject.get_certificates_der_v2() if len(certs) > 0: - logging.info(_('Using APK Signature v2')) + logging.debug(_('Using APK Signature v2')) cert_encoded = certs[0] if not cert_encoded: certs = apkobject.get_certificates_der_v3() if len(certs) > 0: - logging.info(_('Using APK Signature v3')) + logging.debug(_('Using APK Signature v3')) cert_encoded = certs[0] if not cert_encoded: From b95f66a806c9d05f9edc905b6bd58be02e5f8b77 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 6 Nov 2019 09:00:32 +0100 Subject: [PATCH 0166/2775] scanner: only allow HTTPS versions of the whitelist --- fdroidserver/scanner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index acc19e72..94c8cf72 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -96,7 +96,7 @@ def scan_source(build_dir, build=metadata.Build()): gradle_mavenrepo = re.compile(r'maven *{ *(url)? *[\'"]?([^ \'"]*)[\'"]?') - allowed_repos = [re.compile(r'^https?://' + re.escape(repo) + r'/*') for repo in [ + allowed_repos = [re.compile(r'^https://' + re.escape(repo) + r'/*') for repo in [ 'repo1.maven.org/maven2', # mavenCentral() 'jcenter.bintray.com', # jcenter() 'jitpack.io', From 1f363a889dcf8ca074d9d22e55b21d75566661f0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 18 Nov 2019 18:13:37 +0100 Subject: [PATCH 0167/2775] jenkins-setup-build-environment: auto-detect RAM/CPU specs This lets this setup run on more basic hardware, like schweiger/vibi. --- jenkins-setup-build-environment | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index 678772cd..36c0a2aa 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -55,15 +55,27 @@ mkdir $VAGRANT_HOME rm -rf "$WORKSPACE"/../*/.testfiles -cd $WORKSPACE +memtotal=$(grep ^MemTotal: /proc/meminfo | awk '{print $2}') +if [ $memtotal -gt 8092876 ]; then + memory=8192 +else + memory=$(((memtotal / 1024) - 1024)) +fi +if [ `nproc` -le 6 ]; then + cpus=$((`nproc` - 1)) +else + cpus=6 +fi cat < $WORKSPACE/makebuildserver.config.py debian_mirror = 'http://deb.debian.org/debian/' boot_timeout = 1200 apt_package_cache = True copy_caches_from_host = True -memory = 8192 -cpus = 6 +memory = $memory +cpus = $cpus EOF + +cd $WORKSPACE ./makebuildserver -vv --clean if [ -z "`vagrant box list | egrep '^buildserver\s+\((libvirt|virtualbox), [0-9]+\)$'`" ]; then From d0449d97132b632ca6bf758683fb284bd15fd8b5 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Tue, 26 Nov 2019 10:04:04 +0000 Subject: [PATCH 0168/2775] Gradle 6.0 & 6.0.1 --- gradlew-fdroid | 4 +++- makebuildserver | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 0e5dc5de..b4e48857 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -127,6 +127,8 @@ get_sha() { '5.6.2') echo '32fce6628848f799b0ad3205ae8db67d0d828c10ffe62b748a7c0d9f4a5d9ee0' ;; '5.6.3') echo '60a6d8f687e3e7a4bc901cc6bc3db190efae0f02f0cc697e323e0f9336f224a3' ;; '5.6.4') echo '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d' ;; + '6.0') echo '5a3578b9f0bb162f5e08cf119f447dfb8fa950cedebb4d2a977e912a11a74b91' ;; + '6.0.1') echo 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44' ;; *) exit 1 esac } @@ -147,7 +149,7 @@ d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 03b1aa4c..0d742fa8 100755 --- a/makebuildserver +++ b/makebuildserver @@ -360,6 +360,8 @@ CACHE_FILES = [ '222a03fcf2fcaf3691767ce9549f78ebd4a77e73f9e23a396899fb70b420cd00'), ('https://services.gradle.org/distributions/gradle-5.6.4-bin.zip', '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d'), + ('https://services.gradle.org/distributions/gradle-6.0.1-bin.zip', + 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From b83c3c9e18d0e9913de78adafe06c6c3c128c929 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Thu, 28 Nov 2019 19:06:23 +0100 Subject: [PATCH 0169/2775] Support hex in versionCode Example: https://github.com/Wilm0r/giggity/blob/master/app/src/main/AndroidManifest.xml#L2 --- fdroidserver/checkupdates.py | 12 ++++++++++-- fdroidserver/common.py | 8 ++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index b166ca39..ea21bb66 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -168,10 +168,18 @@ def check_tags(app, pattern): if vercode: logging.debug("Manifest exists in subdir '{0}'. Found version {1} ({2})" .format(subdir, version, vercode)) - if int(vercode) > int(hcode): + try: + i_vercode = int(vercode, 0) + except ValueError: + i_vercode = int(vercode) + try: + i_hcode = int(hcode, 0) + except ValueError: + i_hcode = int(hcode) + if i_vercode > i_hcode: hpak = package htag = tag - hcode = str(int(vercode)) + hcode = str(i_vercode) hver = version if not hpak: diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 7e145519..02a58390 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3209,10 +3209,14 @@ def parse_xml(path): def string_is_integer(string): try: - int(string) + int(string, 0) return True except ValueError: - return False + try: + int(string) + return True + except ValueError: + return False def local_rsync(options, fromdir, todir): From 0e071a689d5aa7dcbbe22537087b0eb69bf2b76f Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Thu, 28 Nov 2019 21:44:28 +0100 Subject: [PATCH 0170/2775] Support hex versionCode in build command line Example: fdroid build net.gaast.giggity:0x200 --- fdroidserver/common.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 02a58390..b5c4d2a5 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -497,6 +497,11 @@ def read_pkg_args(appid_versionCode_pairs, allow_vercodes=False): for p in appid_versionCode_pairs: if allow_vercodes and ':' in p: package, vercode = p.split(':') + try: + i_vercode = int(vercode, 0) + except ValueError: + i_vercode = int(vercode) + vercode = str(i_vercode) else: package, vercode = p, None if package not in vercodes: From f92eaf644fd41fb33156eb795d3db0e26e70be5f Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Dec 2019 00:09:51 +0100 Subject: [PATCH 0171/2775] nightly: set descriptions for repo and archive --- fdroidserver/nightly.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 7a90294d..1b7fb76d 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -232,9 +232,11 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, config += "repo_name = '%s'\n" % repo_git_base config += "repo_url = '%s'\n" % repo_url config += "repo_icon = 'icon.png'\n" + config += "repo_description = 'Nightly builds from %s'\n" % git_user_email config += "archive_name = '%s'\n" % (repo_git_base + ' archive') config += "archive_url = '%s'\n" % (repo_base + '/archive') config += "archive_icon = 'icon.png'\n" + config += "archive_description = 'Old nightly builds that have been archived.'\n" config += "archive_older = %i\n" % options.archive_older config += "servergitmirrors = '%s'\n" % servergitmirror config += "keystore = '%s'\n" % KEYSTORE_FILE From 75639ba0e834bc80986604b3cfa918ce11de8dc6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Dec 2019 00:06:00 +0100 Subject: [PATCH 0172/2775] update: description is a hard requirement, set a default for archive --- fdroidserver/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 7e145519..960a0280 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -145,6 +145,7 @@ default_config = { developers, or are binaries built from source by the admin of f-droid.org using the tools on https://gitlab.com/u/fdroid. ''', + 'archive_description': _('These are the apps that have been archived from the main repo.'), 'archive_older': 0, 'lint_licenses': fdroidserver.lint.APPROVED_LICENSES, } From ddf1f8ea15af5cd365b3e1aa9bbe6155ad77d19b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Dec 2019 00:06:30 +0100 Subject: [PATCH 0173/2775] update: make default repo description translatable --- fdroidserver/common.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 960a0280..8a87efcf 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -139,12 +139,12 @@ default_config = { 'repo_url': "https://MyFirstFDroidRepo.org/fdroid/repo", 'repo_name': "My First FDroid Repo Demo", 'repo_icon': "fdroid-icon.png", - 'repo_description': ''' + 'repo_description': _(''' This is a repository of apps to be used with FDroid. Applications in this repository are either official binaries built by the original application - developers, or are binaries built from source by the admin of f-droid.org - using the tools on https://gitlab.com/u/fdroid. - ''', + developers, or are binaries built from source by f-droid.org using the + tools on https://gitlab.com/fdroid. + '''), 'archive_description': _('These are the apps that have been archived from the main repo.'), 'archive_older': 0, 'lint_licenses': fdroidserver.lint.APPROVED_LICENSES, From 492f12a7a8aad2a72f774d6363eb109cdfb830ea Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Dec 2019 00:09:51 +0100 Subject: [PATCH 0174/2775] nightly: set descriptions for repo and archive --- fdroidserver/nightly.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 6f09aa4d..0a3a8012 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -232,9 +232,11 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, config += "repo_name = '%s'\n" % repo_git_base config += "repo_url = '%s'\n" % repo_url config += "repo_icon = 'icon.png'\n" + config += "repo_description = 'Nightly builds from %s'\n" % git_user_email config += "archive_name = '%s'\n" % (repo_git_base + ' archive') config += "archive_url = '%s'\n" % (repo_base + '/archive') config += "archive_icon = 'icon.png'\n" + config += "archive_description = 'Old nightly builds that have been archived.'\n" config += "archive_older = %i\n" % options.archive_older config += "servergitmirrors = '%s'\n" % servergitmirror config += "keystore = '%s'\n" % KEYSTORE_FILE From dcb72a77ce2bba78a6a0a97792bb6d411c5d81ad Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Dec 2019 00:12:26 +0100 Subject: [PATCH 0175/2775] bump to version v1.1.6 --- setup.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9f81aaa9..efc46573 100755 --- a/setup.py +++ b/setup.py @@ -48,11 +48,13 @@ def get_data_files(): data_files.append((d, [f, ])) return data_files + with open("README.md", "r") as fh: long_description = fh.read() + setup(name='fdroidserver', - version='1.1.5', + version='1.1.6', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From bbee2cf707c6a7207367124d52791e109734b2ed Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Tue, 3 Dec 2019 21:49:44 +0100 Subject: [PATCH 0176/2775] Add unit test for string_is_integer() --- tests/common.TestCase | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/common.TestCase b/tests/common.TestCase index d2d46ce4..89508b15 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1076,6 +1076,14 @@ class CommonTest(unittest.TestCase): with gzip.open(expected_log_path, 'r') as f: self.assertEqual(f.read(), mocklogcontent) + def test_string_is_integer(self): + self.assertTrue(fdroidserver.common.string_is_integer('0x10')) + self.assertTrue(fdroidserver.common.string_is_integer('010')) + self.assertTrue(fdroidserver.common.string_is_integer('123')) + self.assertFalse(fdroidserver.common.string_is_integer('0xgg')) + self.assertFalse(fdroidserver.common.string_is_integer('01g')) + self.assertFalse(fdroidserver.common.string_is_integer('o123')) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 7d40e893413526d23c8a697a12d5ad93147fd551 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Dec 2019 23:51:48 +0100 Subject: [PATCH 0177/2775] checkupdates: split out vercode parsing into testable function --- fdroidserver/checkupdates.py | 11 ++--------- fdroidserver/common.py | 8 ++++++++ tests/common.TestCase | 8 ++++++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index ea21bb66..0fde3536 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -168,15 +168,8 @@ def check_tags(app, pattern): if vercode: logging.debug("Manifest exists in subdir '{0}'. Found version {1} ({2})" .format(subdir, version, vercode)) - try: - i_vercode = int(vercode, 0) - except ValueError: - i_vercode = int(vercode) - try: - i_hcode = int(hcode, 0) - except ValueError: - i_hcode = int(hcode) - if i_vercode > i_hcode: + i_vercode = common.version_code_string_to_int(vercode) + if i_vercode > common.version_code_string_to_int(hcode): hpak = package htag = tag hcode = str(i_vercode) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index b5c4d2a5..9032cf8f 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3224,6 +3224,14 @@ def string_is_integer(string): return False +def version_code_string_to_int(vercode): + """Convert an version code string of any base into an int""" + try: + return int(vercode, 0) + except ValueError: + return int(vercode) + + def local_rsync(options, fromdir, todir): '''Rsync method for local to local copying of things diff --git a/tests/common.TestCase b/tests/common.TestCase index 89508b15..33db7283 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1084,6 +1084,14 @@ class CommonTest(unittest.TestCase): self.assertFalse(fdroidserver.common.string_is_integer('01g')) self.assertFalse(fdroidserver.common.string_is_integer('o123')) + def test_version_code_string_to_int(self): + self.assertEqual(16, fdroidserver.common.version_code_string_to_int('0x10')) + self.assertEqual(198712389, fdroidserver.common.version_code_string_to_int('198712389')) + self.assertEqual(8, fdroidserver.common.version_code_string_to_int('0o10')) + self.assertEqual(10, fdroidserver.common.version_code_string_to_int('010')) + self.assertEqual(123, fdroidserver.common.version_code_string_to_int('0000123')) + self.assertEqual(-42, fdroidserver.common.version_code_string_to_int('-42')) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 126f6bf8392737a993a07671c137e5b84c58715c Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Mon, 16 Dec 2019 00:07:03 +0000 Subject: [PATCH 0178/2775] Add NDK r20b --- buildserver/config.buildserver.py | 2 +- buildserver/provision-android-ndk | 2 +- examples/config.py | 2 +- makebuildserver | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index 7edf693c..3b5a5c1f 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -10,7 +10,7 @@ ndk_paths = { 'r17c': "/home/vagrant/android-ndk/r17c", 'r18b': "/home/vagrant/android-ndk/r18b", 'r19c': "/home/vagrant/android-ndk/r19c", - 'r20': "/home/vagrant/android-ndk/r20", + 'r20b': "/home/vagrant/android-ndk/r20b", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index 7e137d48..1836e2cb 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/examples/config.py b/examples/config.py index c766eab2..b400af6c 100644 --- a/examples/config.py +++ b/examples/config.py @@ -21,7 +21,7 @@ # 'r17c': None, # 'r18b': None, # 'r19c': None, -# 'r20': None, +# 'r20b': None, # } # Directory to store downloaded tools in (i.e. gradle versions) diff --git a/makebuildserver b/makebuildserver index 0d742fa8..b4cf56c1 100755 --- a/makebuildserver +++ b/makebuildserver @@ -382,8 +382,8 @@ CACHE_FILES = [ '4f61cbe4bbf6406aa5ef2ae871def78010eed6271af72de83f8bd0b07a9fd3fd'), ('https://dl.google.com/android/repository/android-ndk-r19c-linux-x86_64.zip', '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), - ('https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip', - '57435158f109162f41f2f43d5563d2164e4d5d0364783a9a6fab3ef12cb06ce0'), + ('https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip', + '8381c440fe61fcbb01e209211ac01b519cd6adf51ab1c2281d5daad6ca4c8c8c'), ] From 5642dc56aef2e826ee38e41189f152250eccd4b4 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 23 Dec 2019 01:27:09 +0100 Subject: [PATCH 0179/2775] remove unused function The users of this were removed years ago in 013315bf1084c3a9d38b815e06323d36875c210e. --- fdroidserver/metadata.py | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 2924dde8..219562f1 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -848,40 +848,6 @@ def split_list_values(s): return res -def get_default_app_info(metadatapath=None): - if metadatapath is None: - appid = None - else: - appid, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath)) - - if appid == '.fdroid': # we have local metadata in the app's source - if os.path.exists('AndroidManifest.xml'): - manifestroot = fdroidserver.common.parse_xml('AndroidManifest.xml') - else: - pattern = re.compile(r""".*manifest\.srcFile\s+'AndroidManifest\.xml'.*""") - for root, dirs, files in os.walk(os.getcwd()): - if 'build.gradle' in files: - p = os.path.join(root, 'build.gradle') - with open(p, 'rb') as f: - data = f.read() - m = pattern.search(data) - if m: - logging.debug('Using: ' + os.path.join(root, 'AndroidManifest.xml')) - manifestroot = fdroidserver.common.parse_xml(os.path.join(root, 'AndroidManifest.xml')) - break - if manifestroot is None: - warn_or_exception(_("Cannot find an appid for {path}!") - .format(path=metadatapath)) - appid = manifestroot.attrib['package'] - - app = App() - app.metadatapath = metadatapath - if appid is not None: - app.id = appid - - return app - - def sorted_builds(builds): return sorted(builds, key=lambda build: int(build.versionCode)) From 01d00d54ca860c756c0dc3d458c9d0900b03931a Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 23 Dec 2019 01:08:45 +0100 Subject: [PATCH 0180/2775] metadata: use yaml C implementation when available This is an order of magnitude faster. Requires the C yaml bindings to be installed. Fixes fdroid/fdroidserver#716 --- fdroidserver/metadata.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 2924dde8..61c77b06 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -27,6 +27,10 @@ import logging import textwrap import io import yaml +try: + from yaml import CSafeLoader as SafeLoader +except ImportError: + from yaml import SafeLoader import importlib from collections import OrderedDict @@ -1070,7 +1074,7 @@ def parse_json_metadata(mf, app): def parse_yaml_metadata(mf, app): - yamldata = yaml.safe_load(mf) + yamldata = yaml.load(mf, Loader=SafeLoader) deprecated_in_yaml = ['Provides'] From 3403402fbcb48d299cf52a9037f46563727ea9fd Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 23 Dec 2019 14:48:52 +0100 Subject: [PATCH 0181/2775] git force fetch tags The behaviour of fetching tags changed in git 2.20. We need to force fetch tags to restore the earlier behaviour and make fdroid git operations work with newer git versions. Closes fdroid/fdroidserver#718 --- fdroidserver/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 00dcb7c8..05060658 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -906,7 +906,7 @@ class vcs_git(vcs): p = self.git(['fetch', 'origin'], cwd=self.local) if p.returncode != 0: raise VCSException(_("Git fetch failed"), p.output) - p = self.git(['fetch', '--prune', '--tags', 'origin'], output=False, cwd=self.local) + p = self.git(['fetch', '--prune', '--tags', '--force', 'origin'], output=False, cwd=self.local) if p.returncode != 0: raise VCSException(_("Git fetch failed"), p.output) # Recreate origin/HEAD as git clone would do it, in case it disappeared From 7f6efa74f59a69962184a5a3cba2981223803990 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 23 Dec 2019 20:07:56 +0100 Subject: [PATCH 0182/2775] tests: add test for correctly handling CVC when archiving --- tests/keystore.jks | Bin 3760 -> 5967 bytes tests/run-tests | 15 +++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/tests/keystore.jks b/tests/keystore.jks index 1eb91fe78cd6b773f05764a10a25b2809392c3d7..ca13f91754e1bb641da876784ff0aa59e77e1a56 100644 GIT binary patch delta 2252 zcmb`Ic{J1u8^?dYnK78LFLkd%*+rRQWK@G+Cl#P=rgl)DW^q z2-(+c7g@?0YD!tkb?MbP_dTa`-hbaeoO%`}jFg&@ZvPq~Y?#_g*gQ!mc)D6|`Zm={y@jK(|1o>Hgr zH~AxX4PisZ7L)YOr6a{Fh&x`Qi8uMIlQI;BsNNzt?TY+su@QhUe|klb4*}M>PRsc; zu-q!P8pl;rCIE?o&-5O(l4&fe=>;veUax!hs^%B{;~>1lxSnrNwKn|?$*%Boy-?E! z`O!VmZawhZF@mVD%#H&+3?d_?1^vz9lbT#vf^SqryIr}rIxFo*xh9C0IDO5L!nmQKf0S*dO%Rh*qZ5kn*ZjL1xTG zRLt_(7TXYC%Xuen9_-SgmPn0fmD6z95d2Q!H+h{QMrqeW;F1*7-t^*S&JcCK%Ftd}o*AOX z`8l*pjXdG5PTB3FYn^H{A|gTw&s_$$X)B0lTJTMZ?q};q@;|VqECs}%O9^_m$2k@UV#QbtbhX zLqbnK>FJScG5Dl>%lm~sr>imEx!wOY-cEe1cj`o^{@ON zFZ5r{{GYwVfKtCkaqu#rF(5yHiUARj7!U;VPwx2BE4!=8xSJ)f`|%#CZH|*^yjRh| zr=z9HmSzV$_9Gib`7h;II4Xolt}n;{JT|0?b)wYiwo&O6`~pOE?#G#j!OJA=Npnhs z(R#xMq_d)+OkgPA$Bp6G=~&PF3;s+sVtuGYh%42uuQHmgS1R8JS%0}Nlziv=R{?U3 zn%y`0q0Z9K^X!-9b4|q!k-r=Ar_?CMt5})|x;8n9ip#K83aMY{%X+~dou?YLz7~jk zX_kx0sIrm6Vk0aZ!UXLh=c6K#91uSk| z*YxX8z_ZG;o$~XQv3;K#G{`&3=|$?Vhak{Y7ak$H|NO}QxN}kPDOGjCZc}uIXh1^E zugM)8(Lr(`057)>+`hjRLaR)nE?J(%<-a(zN83=kT{*v_Vdfj2Nt3i~%C*0Nh(i^( z+=?`Qn>n`QLMa=YRU(q>W(C`N20};W2#s0#OGIke#ldsd{UUbI#&JG6b7Qhc@;(yA zy_IXpB!}~*>P+lY@V>@|+_B>@f5#9vFvoV*U@pf(SNuLp+FiKDSxDIwAaj=hmpM} zbqgz)V4+pz@IedSAadfz{O3F=^9p>MPQdV4eVho}cjDu2-|JyXT%|SsNzT%?*Mm*M jfXAQT7t49>@`=oPJ*A|Dru|c1s7Tm)lR{xSDv$mLLEhVz delta 43 zcmX@Fw?UTY-`jt085kItfS7UfYK{qfB3mxxe0skzDK}yJ+rT@' archive/index.xml | wc -l` -eq 3 + test `grep '' repo/index.xml | wc -l` -eq 1 + grep -F com.politedroid_3.apk archive/index.xml + grep -F com.politedroid_4.apk archive/index.xml + grep -F com.politedroid_5.apk repo/index.xml + grep -F com.politedroid_6.apk archive/index.xml + test -e archive/com.politedroid_3.apk + test -e archive/com.politedroid_4.apk + test -e repo/com.politedroid_5.apk + ! test -e repo/com.politedroid_6.apk + test -e archive/com.politedroid_6.apk fi From a7a83e1ee35cf38ab102261d514c0933468ac94b Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 23 Dec 2019 16:32:14 +0100 Subject: [PATCH 0183/2775] update: keep CVC of an app out of the archive We want to keep the stable version (CV) of an app in /repo with highest priority and only move it to /archive when ArchivePolicy is set to 0. For this to work we need two changes here: 1) when sorting apks by version code we insert the apk corresponding to the CVC of the app afterwards with highest priority. So when walking the list of apks afterwards the CVC apk is always kept first. 2) Instead of the two pass algorithm of moving things back and forth to the archive we instead figure out where each apk of an app goes in first before actually moving them into the right place. Fixes: fdroid/fdroidserver#385 --- fdroidserver/update.py | 50 +++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 463a1c7d..9225c241 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1823,12 +1823,20 @@ def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversi def filter_apk_list_sorted(apk_list): res = [] + currentVersionApk = None for apk in apk_list: if apk['packageName'] == appid: + if apk['versionCode'] == common.version_code_string_to_int(app.CurrentVersionCode): + currentVersionApk = apk + continue res.append(apk) # Sort the apk list by version code. First is highest/newest. - return sorted(res, key=lambda apk: apk['versionCode'], reverse=True) + sorted_list = sorted(res, key=lambda apk: apk['versionCode'], reverse=True) + if currentVersionApk: + # Insert apk which corresponds to currentVersion at the front + sorted_list.insert(0, currentVersionApk) + return sorted_list for appid, app in apps.items(): @@ -1840,26 +1848,28 @@ def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversi logging.debug(_("Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}") .format(appid=appid, integer=len(apks), keep=keepversions, arch=len(archapks))) - current_app_apks = filter_apk_list_sorted(apks) - if len(current_app_apks) > keepversions: - # Move back the ones we don't want. - for apk in current_app_apks[keepversions:]: - move_apk_between_sections(repodir, archivedir, apk) - archapks.append(apk) - apks.remove(apk) + all_app_apks = filter_apk_list_sorted(apks + archapks) - current_app_archapks = filter_apk_list_sorted(archapks) - if len(current_app_apks) < keepversions and len(current_app_archapks) > 0: - kept = 0 - # Move forward the ones we want again, except DisableAlgorithm - for apk in current_app_archapks: - if 'DisabledAlgorithm' not in apk['antiFeatures']: - move_apk_between_sections(archivedir, repodir, apk) - archapks.remove(apk) - apks.append(apk) - kept += 1 - if kept == keepversions: - break + # determine which apks to keep in repo + keep = [] + for apk in all_app_apks: + if len(keep) == keepversions: + break + if 'antiFeatures' not in apk: + keep.append(apk) + elif 'DisabledAlgorithm' not in apk['antiFeatures']: + keep.append(apk) + + # actually move apks to the target section + for apk in all_app_apks: + if apk in apks and apk not in keep: + apks.remove(apk) + archapks.append(apk) + move_apk_between_sections(repodir, archivedir, apk) + elif apk in archapks and apk in keep: + archapks.remove(apk) + apks.append(apk) + move_apk_between_sections(archivedir, repodir, apk) def move_apk_between_sections(from_dir, to_dir, apk): From 83526e09a35aafcf1316fae844fa7604e9a659e1 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 24 Dec 2019 17:18:42 +0100 Subject: [PATCH 0184/2775] update: fix unarchiving of allowed disabled algorithm 6d0b1bbe6fae0909683f2c6a154515bc4bfcb674 didn't handle the allow_disabled_algorithm case at all, so we add it back. This additionally fixes a (previously existing) bug where setting allow_disabled_algorithms to True didn't move apks back from archive to repo. Introduce a new test for this. The disabled_algorithm archiving logic is still all over the place so ideally that needs a future refactor. --- fdroidserver/update.py | 10 +++++++--- tests/run-tests | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 9225c241..bc2583fc 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -117,6 +117,10 @@ def get_all_icon_dirs(repodir): yield get_icon_dir(repodir, density) +def disabled_algorithms_allowed(): + return options.allow_disabled_algorithms or config['allow_disabled_algorithms'] + + def update_wiki(apps, sortedids, apks): """Update the wiki @@ -460,7 +464,7 @@ def get_cache(): """ apkcachefile = get_cache_file() - ada = options.allow_disabled_algorithms or config['allow_disabled_algorithms'] + ada = disabled_algorithms_allowed() if not options.clean and os.path.exists(apkcachefile): with open(apkcachefile) as fp: apkcache = json.load(fp, object_pairs_hook=collections.OrderedDict) @@ -1598,7 +1602,7 @@ def process_apks(apkcache, repodir, knownapks, use_date_from_apk=False): apks = [] for apkfile in sorted(glob.glob(os.path.join(repodir, '*.apk'))): apkfilename = apkfile[len(repodir) + 1:] - ada = options.allow_disabled_algorithms or config['allow_disabled_algorithms'] + ada = disabled_algorithms_allowed() (skip, apk, cachethis) = process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk, ada, True) if skip: @@ -1857,7 +1861,7 @@ def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversi break if 'antiFeatures' not in apk: keep.append(apk) - elif 'DisabledAlgorithm' not in apk['antiFeatures']: + elif 'DisabledAlgorithm' not in apk['antiFeatures'] or disabled_algorithms_allowed(): keep.append(apk) # actually move apks to the target section diff --git a/tests/run-tests b/tests/run-tests index 16ec8bb3..7ae22fe9 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -555,6 +555,30 @@ if ! which apksigner; then test -e repo/com.politedroid_6.apk fi +# test unarchiving when disabled_algorithms are allowed again +echo 'allow_disabled_algorithms = True' >> config.py +$fdroid update --pretty --nosign +test `grep '' archive/index.xml | wc -l` -eq 2 +test `grep '' repo/index.xml | wc -l` -eq 6 +grep -F com.politedroid_3.apk archive/index.xml +grep -F com.politedroid_4.apk repo/index.xml +grep -F com.politedroid_5.apk repo/index.xml +grep -F com.politedroid_6.apk repo/index.xml +grep -F org.bitbucket.tickytacky.mirrormirror_1.apk archive/index.xml +grep -F org.bitbucket.tickytacky.mirrormirror_2.apk repo/index.xml +grep -F org.bitbucket.tickytacky.mirrormirror_3.apk repo/index.xml +grep -F org.bitbucket.tickytacky.mirrormirror_4.apk repo/index.xml +! grep -F urzip-badsig.apk repo/index.xml +! grep -F urzip-badsig.apk archive/index.xml +test -e archive/com.politedroid_3.apk +test -e repo/com.politedroid_4.apk +test -e repo/com.politedroid_5.apk +test -e repo/com.politedroid_6.apk +test -e archive/org.bitbucket.tickytacky.mirrormirror_1.apk +test -e repo/org.bitbucket.tickytacky.mirrormirror_2.apk +test -e repo/org.bitbucket.tickytacky.mirrormirror_3.apk +test -e repo/org.bitbucket.tickytacky.mirrormirror_4.apk +test -e archive/urzip-badsig.apk #------------------------------------------------------------------------------# echo_header 'rename apks with `fdroid update --rename-apks`, --nosign for speed' From cf9bff1d56bf1e43abfeccc0c86b9f646de6213e Mon Sep 17 00:00:00 2001 From: Gerhard Olsson Date: Thu, 2 Jan 2020 13:27:12 +0000 Subject: [PATCH 0185/2775] AutoUpdateMode: Do not include + in suffix Add suffix to version only --- fdroidserver/checkupdates.py | 10 +++---- tests/checkupdates.TestCase | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 0fde3536..8620f899 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -485,13 +485,13 @@ def checkupdates_app(app): pass elif mode.startswith('Version '): pattern = mode[8:] + suffix = '' if pattern.startswith('+'): try: - suffix, pattern = pattern.split(' ', 1) + suffix, pattern = pattern[1:].split(' ', 1) except ValueError: raise MetaDataException("Invalid AUM: " + mode) - else: - suffix = '' + gotcur = False latest = None for build in app.builds: @@ -507,9 +507,9 @@ def checkupdates_app(app): newbuild = copy.deepcopy(latest) newbuild.disable = False newbuild.versionCode = app.CurrentVersionCode - newbuild.versionName = app.CurrentVersion + suffix + newbuild.versionName = app.CurrentVersion + suffix.replace('%c', newbuild.versionCode) logging.info("...auto-generating build for " + newbuild.versionName) - commit = pattern.replace('%v', newbuild.versionName) + commit = pattern.replace('%v', app.CurrentVersion) commit = commit.replace('%c', newbuild.versionCode) newbuild.commit = commit app.builds.append(newbuild) diff --git a/tests/checkupdates.TestCase b/tests/checkupdates.TestCase index 503f6b76..ab68cd8d 100755 --- a/tests/checkupdates.TestCase +++ b/tests/checkupdates.TestCase @@ -32,6 +32,58 @@ class CommonTest(unittest.TestCase): os.makedirs(self.tmpdir) os.chdir(self.basedir) + def test_autoupdatemode_no_suffix(self): + fdroidserver.checkupdates.options = mock.Mock() + fdroidserver.checkupdates.options.auto = 'bleh' + fdroidserver.checkupdates.config = {} + + app = fdroidserver.metadata.App() + app.id = 'loop.starts.shooting' + app.metadatapath = 'metadata/' + app.id + '.yml' + app.CurrentVersion = '1.1.8-fdroid' + app.CurrentVersionCode = 10108 + app.UpdateCheckMode = 'HTTP' + app.AutoUpdateMode = 'Version %v' + + build = fdroidserver.metadata.Build() + build.versionCode = app.CurrentVersionCode + build.versionName = app.CurrentVersion + app.builds.append(build) + + with mock.patch('fdroidserver.checkupdates.check_http', lambda app: ('1.1.9', 10109)): + with mock.patch('fdroidserver.metadata.write_metadata', mock.Mock()): + with mock.patch('subprocess.call', lambda cmd: 0): + fdroidserver.checkupdates.checkupdates_app(app) + build = app.builds[-1] + self.assertEqual(build.versionName, '1.1.9') + self.assertEqual(build.commit, '1.1.9') + + def test_autoupdatemode_suffix(self): + fdroidserver.checkupdates.options = mock.Mock() + fdroidserver.checkupdates.options.auto = 'bleh' + fdroidserver.checkupdates.config = {} + + app = fdroidserver.metadata.App() + app.id = 'loop.starts.shooting' + app.metadatapath = 'metadata/' + app.id + '.yml' + app.CurrentVersion = '1.1.8-fdroid' + app.CurrentVersionCode = 10108 + app.UpdateCheckMode = 'HTTP' + app.AutoUpdateMode = 'Version +.%c-fdroid v%v_%c' + + build = fdroidserver.metadata.Build() + build.versionCode = app.CurrentVersionCode + build.versionName = app.CurrentVersion + app.builds.append(build) + + with mock.patch('fdroidserver.checkupdates.check_http', lambda app: ('1.1.9', 10109)): + with mock.patch('fdroidserver.metadata.write_metadata', mock.Mock()): + with mock.patch('subprocess.call', lambda cmd: 0): + fdroidserver.checkupdates.checkupdates_app(app) + build = app.builds[-1] + self.assertEqual(build.versionName, '1.1.9.10109-fdroid') + self.assertEqual(build.commit, 'v1.1.9_10109') + def test_checkupdates_app_http(self): fdroidserver.checkupdates.options = mock.Mock() fdroidserver.checkupdates.options.auto = 'bleh' From 96ba194d656dfc02773a2b8b9b69856766a22353 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 8 Jan 2020 14:20:18 +0100 Subject: [PATCH 0186/2775] bump title char_limit to 50 This follows google play in doing so. Closes fdroidserver#726, fdroid/fdroiddata#1906. --- examples/config.py | 2 +- fdroidserver/common.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/config.py b/examples/config.py index b400af6c..1093fac8 100644 --- a/examples/config.py +++ b/examples/config.py @@ -306,7 +306,7 @@ The repository of older versions of applications from the main demo repository. # Only the fields listed here are supported, defaults shown # char_limits = { # 'author': 256, -# 'name': 30, +# 'name': 50, # 'summary': 80, # 'description': 4000, # 'video': 256, diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 05060658..8a89cec0 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -129,7 +129,7 @@ default_config = { 'smartcardoptions': [], 'char_limits': { 'author': 256, - 'name': 30, + 'name': 50, 'summary': 80, 'description': 4000, 'video': 256, From f2b48575e6a949e35e856534c6ff4c6a86b8f010 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 6 Nov 2019 09:02:53 +0100 Subject: [PATCH 0187/2775] deploy: github/gitlab use bare git repos, only size the .git/ dir needs test: generate giant APKs by including AndroidManifest.xml and and large file from /dev/urandom, then sign it. Then add those to the git repo. --- fdroidserver/server.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index 964edc3b..229aa13f 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -352,10 +352,13 @@ def update_servergitmirrors(servergitmirrors, repo_section): git_repodir = os.path.join(git_mirror_path, 'fdroid', repo_section) if not os.path.isdir(git_repodir): os.makedirs(git_repodir) - if os.path.isdir(dotgit) and _get_size(git_mirror_path) > 1000000000: + # github/gitlab use bare git repos, so only count the .git folder + # test: generate giant APKs by including AndroidManifest.xml and and large + # file from /dev/urandom, then sign it. Then add those to the git repo. + if os.path.isdir(dotgit) and _get_size(dotgit) > 1000000000: logging.warning('Deleting git-mirror history, repo is too big (1 gig max)') shutil.rmtree(dotgit) - if options.no_keep_git_mirror_archive and _get_size(git_mirror_path) > 1000000000: + if options.no_keep_git_mirror_archive and _get_size(dotgit) > 1000000000: logging.warning('Deleting archive, repo is too big (1 gig max)') archive_path = os.path.join(git_mirror_path, 'fdroid', 'archive') shutil.rmtree(archive_path, ignore_errors=True) From 058b47e4843f74f7b8ffe97d8adea5fdb1288179 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 19 Dec 2019 10:34:48 +0100 Subject: [PATCH 0188/2775] deploy: fix virustotal report fetching, use GET and query string --- fdroidserver/server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index 229aa13f..d4a1b784 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -476,7 +476,7 @@ def upload_to_android_observatory(repo_section): logging.info(message) -def upload_to_virustotal(repo_section, vt_apikey): +def upload_to_virustotal(repo_section, virustotal_apikey): import json import requests @@ -509,13 +509,13 @@ def upload_to_virustotal(repo_section, vt_apikey): "User-Agent": "F-Droid" } data = { - 'apikey': vt_apikey, + 'apikey': virustotal_apikey, 'resource': package['hash'], } needs_file_upload = False while True: - r = requests.post('https://www.virustotal.com/vtapi/v2/file/report', - data=data, headers=headers) + r = requests.get('https://www.virustotal.com/vtapi/v2/file/report?' + + urllib.parse.urlencode(data), headers=headers) if r.status_code == 200: response = r.json() if response['response_code'] == 0: From 4fa11ef4fc2b72d746e0be3f0937768b5d61f96c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 19 Dec 2019 10:36:15 +0100 Subject: [PATCH 0189/2775] deploy: detect virustotal size limits while uploading This prevents the size limits from blocking the whole deploy. --- fdroidserver/server.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index d4a1b784..a69ed030 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -25,6 +25,7 @@ import pwd import re import subprocess import time +import urllib from argparse import ArgumentParser import logging import shutil @@ -536,18 +537,40 @@ def upload_to_virustotal(repo_section, virustotal_apikey): elif r.status_code == 204: time.sleep(10) # wait for public API rate limiting + upload_url = None if needs_file_upload: - logging.info('Uploading ' + repofilename + ' to virustotal') + manual_url = 'https://www.virustotal.com/' + size = os.path.getsize(repofilename) + if size > 200000000: + # VirusTotal API 200MB hard limit + logging.error(_('{path} more than 200MB, manually upload: {url}') + .format(path=repofilename, url=manual_url)) + elif size > 32000000: + # VirusTotal API requires fetching a URL to upload bigger files + r = requests.get('https://www.virustotal.com/vtapi/v2/file/scan/upload_url?' + + urllib.parse.urlencode(data), headers=headers) + if r.status_code == 200: + upload_url = r.json().get('upload_url') + elif r.status_code == 403: + logging.error(_('VirusTotal API key cannot upload files larger than 32MB, ' + + 'use {url} to upload {path}.') + .format(path=repofilename, url=manual_url)) + else: + r.raise_for_status() + else: + upload_url = 'https://www.virustotal.com/vtapi/v2/file/scan' + + if upload_url: + logging.info(_('Uploading {apkfilename} to virustotal') + .format(apkfilename=repofilename)) files = { 'file': (filename, open(repofilename, 'rb')) } - r = requests.post('https://www.virustotal.com/vtapi/v2/file/scan', - data=data, headers=headers, files=files) - logging.debug('If this upload fails, try manually uploading here:\n' - + 'https://www.virustotal.com/') + r = requests.post(upload_url, data=data, headers=headers, files=files) + logging.debug(_('If this upload fails, try manually uploading to {url}') + .format(url=manual_url)) r.raise_for_status() response = r.json() - logging.info(response['verbose_msg'] + " " + response['permalink']) From e76a0c9d6afc35474b1b7773978e7b46278210f2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 13 Jan 2020 11:48:23 +0100 Subject: [PATCH 0190/2775] git_mirror_size_limit config option to set max git mirror size GitHub and GitLab have some kinds of limits on how big a git repo can be, this makes that option configurable. This also is very useful for tests. --- examples/config.py | 7 ++++++ fdroidserver/common.py | 23 ++++++++++++++++++ fdroidserver/server.py | 12 ++++++---- tests/common.TestCase | 9 +++++++ tests/run-tests | 53 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 4 deletions(-) diff --git a/examples/config.py b/examples/config.py index b400af6c..9035baa5 100644 --- a/examples/config.py +++ b/examples/config.py @@ -190,6 +190,13 @@ The repository of older versions of applications from the main demo repository. # 'https://gitlab.com/user/repo', # } +# Most git hosting services have hard size limits for each git repo. +# `fdroid deploy` will delete the git history when the git mirror repo +# approaches this limit to ensure that the repo will still fit when +# pushed. GitHub recommends 1GB, gitlab.com recommends 10GB. +# +# git_mirror_size_limit = '10GB' + # Any mirrors of this repo, for example all of the servers declared in # serverwebroot and all the servers declared in servergitmirrors, # will automatically be used by the client. If one diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 05060658..a18d49f1 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -148,6 +148,7 @@ default_config = { 'archive_description': _('These are the apps that have been archived from the main repo.'), 'archive_older': 0, 'lint_licenses': fdroidserver.lint.APPROVED_LICENSES, + 'git_mirror_size_limit': 10000000000, } @@ -354,9 +355,31 @@ def read_config(opts, config_file='config.py'): raise TypeError(_('only accepts strings, lists, and tuples')) config['servergitmirrors'] = roots + limit = config['git_mirror_size_limit'] + config['git_mirror_size_limit'] = parse_human_readable_size(limit) + return config +def parse_human_readable_size(size): + units = { + 'b': 1, + 'kb': 1000, 'mb': 1000**2, 'gb': 1000**3, 'tb': 1000**4, + 'kib': 1024, 'mib': 1024**2, 'gib': 1024**3, 'tib': 1024**4, + } + try: + return int(float(size)) + except (ValueError, TypeError): + if type(size) != str: + raise ValueError(_('Could not parse size "{size}", wrong type "{type}"') + .format(size=size, type=type(size))) + s = size.lower().replace(' ', '') + m = re.match(r'^(?P[0-9][0-9.]+) *(?P' + r'|'.join(units.keys()) + r')$', s) + if not m: + raise ValueError(_('Not a valid size definition: "{}"').format(size)) + return int(float(m.group("value")) * units[m.group("unit")]) + + def assert_config_keystore(config): """Check weather keystore is configured correctly and raise exception if not.""" diff --git a/fdroidserver/server.py b/fdroidserver/server.py index a69ed030..18b30f7c 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -356,11 +356,15 @@ def update_servergitmirrors(servergitmirrors, repo_section): # github/gitlab use bare git repos, so only count the .git folder # test: generate giant APKs by including AndroidManifest.xml and and large # file from /dev/urandom, then sign it. Then add those to the git repo. - if os.path.isdir(dotgit) and _get_size(dotgit) > 1000000000: - logging.warning('Deleting git-mirror history, repo is too big (1 gig max)') + dotgit_size = _get_size(dotgit) + dotgit_over_limit = dotgit_size > config['git_mirror_size_limit'] + if os.path.isdir(dotgit) and dotgit_over_limit: + logging.warning(_('Deleting git-mirror history, repo is too big ({size} max {limit})') + .format(size=dotgit_size, limit=config['git_mirror_size_limit'])) shutil.rmtree(dotgit) - if options.no_keep_git_mirror_archive and _get_size(dotgit) > 1000000000: - logging.warning('Deleting archive, repo is too big (1 gig max)') + if options.no_keep_git_mirror_archive and dotgit_over_limit: + logging.warning(_('Deleting archive, repo is too big ({size} max {limit})') + .format(size=dotgit_size, limit=config['git_mirror_size_limit'])) archive_path = os.path.join(git_mirror_path, 'fdroid', 'archive') shutil.rmtree(archive_path, ignore_errors=True) diff --git a/tests/common.TestCase b/tests/common.TestCase index 33db7283..3d90707a 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -45,6 +45,15 @@ class CommonTest(unittest.TestCase): os.makedirs(self.tmpdir) os.chdir(self.basedir) + def test_parse_human_readable_size(self): + for k, v in ((9827, 9827), (123.456, 123), ('123b', 123), ('1.2', 1), + ('10.43 KiB', 10680), ('11GB', 11000000000), ('59kb', 59000), + ('343.1 mb', 343100000), ('99.9GiB', 107266808217)): + self.assertEqual(fdroidserver.common.parse_human_readable_size(k), v) + for v in ((12, 123), '0xfff', [], None, '12,123', '123GG', '982374bb', self): + with self.assertRaises(ValueError): + fdroidserver.common.parse_human_readable_size(v) + def test_assert_config_keystore(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with self.assertRaises(FDroidException): diff --git a/tests/run-tests b/tests/run-tests index 7ae22fe9..d769686e 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -1096,6 +1096,59 @@ $fdroid update --create-key test -e $KEYSTORE +#------------------------------------------------------------------------------# +echo_header "setup a new repo from scratch using ANDROID_HOME with git mirror" + +# fake git remote server for repo mirror +SERVER_GIT_MIRROR=`create_test_dir` +cd $SERVER_GIT_MIRROR +git init +git config receive.denyCurrentBranch updateInstead + +REPOROOT=`create_test_dir` +GIT_MIRROR=$REPOROOT/git-mirror +cd $REPOROOT +fdroid_init_with_prebuilt_keystore +echo "servergitmirrors = '$SERVER_GIT_MIRROR'" >> config.py + +cp $WORKSPACE/tests/repo/com.politedroid_[345].apk repo/ +$fdroid update --create-metadata +$fdroid deploy +test -e $GIT_MIRROR/fdroid/repo/com.politedroid_3.apk +test -e $GIT_MIRROR/fdroid/repo/com.politedroid_4.apk +test -e $GIT_MIRROR/fdroid/repo/com.politedroid_5.apk +test -e $SERVER_GIT_MIRROR/fdroid/repo/com.politedroid_3.apk +test -e $SERVER_GIT_MIRROR/fdroid/repo/com.politedroid_4.apk +test -e $SERVER_GIT_MIRROR/fdroid/repo/com.politedroid_5.apk +date > $GIT_MIRROR/.git/test-stamp + +# add one more APK to trigger archiving +cp $WORKSPACE/tests/repo/com.politedroid_6.apk repo/ +$fdroid update +$fdroid deploy +test -e $REPOROOT/archive/com.politedroid_3.apk +! test -e $GIT_MIRROR/fdroid/archive/com.politedroid_3.apk +! test -e $SERVER_GIT_MIRROR/fdroid/archive/com.politedroid_3.apk +test -e $GIT_MIRROR/fdroid/repo/com.politedroid_4.apk +test -e $GIT_MIRROR/fdroid/repo/com.politedroid_5.apk +test -e $GIT_MIRROR/fdroid/repo/com.politedroid_6.apk +test -e $SERVER_GIT_MIRROR/fdroid/repo/com.politedroid_4.apk +test -e $SERVER_GIT_MIRROR/fdroid/repo/com.politedroid_5.apk +test -e $SERVER_GIT_MIRROR/fdroid/repo/com.politedroid_6.apk +before=`du -s --bytes $GIT_MIRROR/.git/ | awk '{print $1}'` + +echo "git_mirror_size_limit = '60kb'" >> config.py +$fdroid update +$fdroid deploy +test -e $REPOROOT/archive/com.politedroid_3.apk +! test -e $SERVER_GIT_MIRROR/fdroid/archive/com.politedroid_3.apk +after=`du -s --bytes $GIT_MIRROR/.git/ | awk '{print $1}'` +! test -e $GIT_MIRROR/.git/test-stamp +git -C $GIT_MIRROR gc +git -C $SERVER_GIT_MIRROR gc +test $before -gt $after + + #------------------------------------------------------------------------------# echo_header "sign binary repo in offline box, then publishing from online box" From df7d7adf78ceb5c29e5e6dee5d0b1c0b37790a96 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 13 Jan 2020 15:06:02 +0100 Subject: [PATCH 0191/2775] mirror: optionally fetch build logs and src tarballs --- fdroidserver/mirror.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fdroidserver/mirror.py b/fdroidserver/mirror.py index 0aa43722..920c9acf 100644 --- a/fdroidserver/mirror.py +++ b/fdroidserver/mirror.py @@ -48,6 +48,10 @@ def main(): + 'using the query string: ?fingerprint=')) parser.add_argument("--archive", action='store_true', default=False, help=_("Also mirror the full archive section")) + parser.add_argument("--build-logs", action='store_true', default=False, + help=_("Include the build logs in the mirror")) + parser.add_argument("--src-tarballs", action='store_true', default=False, + help=_("Include the source tarballs in the mirror")) parser.add_argument("--output-dir", default=None, help=_("The directory to write the mirror to")) options = parser.parse_args() @@ -135,7 +139,10 @@ def main(): for packageName, packageList in data['packages'].items(): for package in packageList: to_fetch = [] - for k in ('apkName', 'srcname'): + keys = ['apkName', ] + if options.src_tarballs: + keys.append('srcname') + for k in keys: if k in package: to_fetch.append(package[k]) elif k == 'apkName': @@ -146,6 +153,9 @@ def main(): or (f.endswith('.apk') and os.path.getsize(f) != package['size']): urls.append(_append_to_url_path(section, f)) urls.append(_append_to_url_path(section, f + '.asc')) + if options.build_logs and f.endswith('.apk'): + urls.append(_append_to_url_path(section, f[:-4] + '.log.gz')) + _run_wget(sectiondir, urls) for app in data['apps']: From 3c3b3dbcf22ed56a98c5daed0eacd1d25f3b3ec1 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Wed, 15 Jan 2020 12:28:36 +0000 Subject: [PATCH 0192/2775] Add NDK21 --- buildserver/config.buildserver.py | 1 + buildserver/provision-android-ndk | 2 +- examples/config.py | 1 + makebuildserver | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index 3b5a5c1f..f54f126e 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -11,6 +11,7 @@ ndk_paths = { 'r18b': "/home/vagrant/android-ndk/r18b", 'r19c': "/home/vagrant/android-ndk/r19c", 'r20b': "/home/vagrant/android-ndk/r20b", + 'r21': "/home/vagrant/android-ndk/r21", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index 1836e2cb..44498dd7 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/examples/config.py b/examples/config.py index 17903dd0..1ed0de51 100644 --- a/examples/config.py +++ b/examples/config.py @@ -22,6 +22,7 @@ # 'r18b': None, # 'r19c': None, # 'r20b': None, +# 'r21': None, # } # Directory to store downloaded tools in (i.e. gradle versions) diff --git a/makebuildserver b/makebuildserver index b4cf56c1..c962c6b7 100755 --- a/makebuildserver +++ b/makebuildserver @@ -384,6 +384,8 @@ CACHE_FILES = [ '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), ('https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip', '8381c440fe61fcbb01e209211ac01b519cd6adf51ab1c2281d5daad6ca4c8c8c'), + ('https://dl.google.com/android/repository/android-ndk-r21-linux-x86_64.zip', + 'b65ea2d5c5b68fb603626adcbcea6e4d12c68eb8a73e373bbb9d23c252fc647b'), ] From 999b15a90954ebcdbacf56cd008acb55418b2747 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 15 Jan 2020 22:09:41 +0100 Subject: [PATCH 0193/2775] Revert "Merge branch 'ndk21' into 'master'" This reverts commit 9b4cb8b76a5239e1c92f3cf94c3a917b438f12c8, reversing changes made to 3bdbbfd45b786d2982d4718062100ea4b07f0e0f. --- buildserver/config.buildserver.py | 1 - buildserver/provision-android-ndk | 2 +- examples/config.py | 1 - makebuildserver | 2 -- 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index f54f126e..3b5a5c1f 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -11,7 +11,6 @@ ndk_paths = { 'r18b': "/home/vagrant/android-ndk/r18b", 'r19c': "/home/vagrant/android-ndk/r19c", 'r20b': "/home/vagrant/android-ndk/r20b", - 'r21': "/home/vagrant/android-ndk/r21", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index 44498dd7..1836e2cb 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/examples/config.py b/examples/config.py index 1ed0de51..17903dd0 100644 --- a/examples/config.py +++ b/examples/config.py @@ -22,7 +22,6 @@ # 'r18b': None, # 'r19c': None, # 'r20b': None, -# 'r21': None, # } # Directory to store downloaded tools in (i.e. gradle versions) diff --git a/makebuildserver b/makebuildserver index c962c6b7..b4cf56c1 100755 --- a/makebuildserver +++ b/makebuildserver @@ -384,8 +384,6 @@ CACHE_FILES = [ '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), ('https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip', '8381c440fe61fcbb01e209211ac01b519cd6adf51ab1c2281d5daad6ca4c8c8c'), - ('https://dl.google.com/android/repository/android-ndk-r21-linux-x86_64.zip', - 'b65ea2d5c5b68fb603626adcbcea6e4d12c68eb8a73e373bbb9d23c252fc647b'), ] From fdcb1ad23f523f11e1c895df13698b192f61e4ca Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 15 Jan 2020 22:48:40 +0100 Subject: [PATCH 0194/2775] Revert "Revert "Merge branch 'ndk21' into 'master'"" This reverts commit 999b15a90954ebcdbacf56cd008acb55418b2747. --- buildserver/config.buildserver.py | 1 + buildserver/provision-android-ndk | 2 +- examples/config.py | 1 + makebuildserver | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index 3b5a5c1f..f54f126e 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -11,6 +11,7 @@ ndk_paths = { 'r18b': "/home/vagrant/android-ndk/r18b", 'r19c': "/home/vagrant/android-ndk/r19c", 'r20b': "/home/vagrant/android-ndk/r20b", + 'r21': "/home/vagrant/android-ndk/r21", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index 1836e2cb..44498dd7 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/examples/config.py b/examples/config.py index 17903dd0..1ed0de51 100644 --- a/examples/config.py +++ b/examples/config.py @@ -22,6 +22,7 @@ # 'r18b': None, # 'r19c': None, # 'r20b': None, +# 'r21': None, # } # Directory to store downloaded tools in (i.e. gradle versions) diff --git a/makebuildserver b/makebuildserver index b4cf56c1..c962c6b7 100755 --- a/makebuildserver +++ b/makebuildserver @@ -384,6 +384,8 @@ CACHE_FILES = [ '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), ('https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip', '8381c440fe61fcbb01e209211ac01b519cd6adf51ab1c2281d5daad6ca4c8c8c'), + ('https://dl.google.com/android/repository/android-ndk-r21-linux-x86_64.zip', + 'b65ea2d5c5b68fb603626adcbcea6e4d12c68eb8a73e373bbb9d23c252fc647b'), ] From 33ddf944f3ac03f65916a1dc5b18fc3ece3eb8e0 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Sun, 19 Jan 2020 18:46:52 +0000 Subject: [PATCH 0195/2775] Add Gradle 6.1 --- gradlew-fdroid | 1 + makebuildserver | 2 ++ 2 files changed, 3 insertions(+) diff --git a/gradlew-fdroid b/gradlew-fdroid index b4e48857..35c53c02 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -129,6 +129,7 @@ get_sha() { '5.6.4') echo '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d' ;; '6.0') echo '5a3578b9f0bb162f5e08cf119f447dfb8fa950cedebb4d2a977e912a11a74b91' ;; '6.0.1') echo 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44' ;; + '6.1') echo 'd0c43d14e1c70a48b82442f435d06186351a2d290d72afd5b8866f15e6d7038a' ;; *) exit 1 esac } diff --git a/makebuildserver b/makebuildserver index c962c6b7..9bf09d40 100755 --- a/makebuildserver +++ b/makebuildserver @@ -362,6 +362,8 @@ CACHE_FILES = [ '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d'), ('https://services.gradle.org/distributions/gradle-6.0.1-bin.zip', 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44'), + ('https://services.gradle.org/distributions/gradle-6.1-bin.zip', + 'd0c43d14e1c70a48b82442f435d06186351a2d290d72afd5b8866f15e6d7038a'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 09db49355712e71dd8d9165aab744bc23049e233 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 21 Jan 2020 11:15:51 +0100 Subject: [PATCH 0196/2775] gradlew-fdroid: support parsing files with no EOL before EOF Fixes cases like: https://gitlab.com/fdroid/fdroiddata/merge_requests/6216#note_273985937 --- gradlew-fdroid | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index b4e48857..520cfbea 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -156,7 +156,7 @@ v_all=${plugin_v[@]} # Earliest takes priority for f in {.,..}/gradle/wrapper/gradle-wrapper.properties; do [[ -f $f ]] || continue - while read -r line; do + while IFS='' read -r line || [ -n "$line" ]; do if [[ $line == 'distributionUrl='* ]]; then wrapper_ver=${line#*/gradle-} wrapper_ver=${wrapper_ver%-*.zip} @@ -174,7 +174,7 @@ fi # Earliest takes priority for f in {.,..}/build.gradle; do [[ -f $f ]] || continue - while read -r line; do + while IFS='' read -r line || [ -n "$line" ]; do if [[ -z "$plugin_pver" && $line == *'com.android.tools.build:gradle:'* ]]; then plugin_pver=${line#*[\'\"]com.android.tools.build:gradle:} plugin_pver=${plugin_pver%[\'\"]*} From 7a4254efa2e61c0420d4f7e8fe09527e7936b75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sun, 19 Jan 2020 18:51:51 +0100 Subject: [PATCH 0197/2775] make main script pythonic --- fdroid | 156 +---------------------------------- fdroidserver/__main__.py | 170 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 152 deletions(-) create mode 100755 fdroidserver/__main__.py diff --git a/fdroid b/fdroid index 59fc69a0..2ad697b2 100755 --- a/fdroid +++ b/fdroid @@ -1,8 +1,7 @@ #!/usr/bin/env python3 -# +# # fdroid.py - part of the FDroid server tools -# Copyright (C) 2010-2015, Ciaran Gultnieks, ciaran@ciarang.com -# Copyright (C) 2013-2014 Daniel Marti +# Copyright (C) 2020 Michael Pöhn . -import sys -import os -import locale -import logging -import fdroidserver.common -import fdroidserver.metadata -from fdroidserver import _ -from argparse import ArgumentError -from collections import OrderedDict +import fdroidserver.__main__ - -commands = OrderedDict([ - ("build", _("Build a package from source")), - ("init", _("Quickly start a new repository")), - ("publish", _("Sign and place packages in the repo")), - ("gpgsign", _("Add PGP signatures using GnuPG for packages in repo")), - ("update", _("Update repo information for new packages")), - ("deploy", _("Interact with the repo HTTP server")), - ("verify", _("Verify the integrity of downloaded packages")), - ("checkupdates", _("Check for updates to applications")), - ("import", _("Add a new application from its source code")), - ("install", _("Install built packages on devices")), - ("readmeta", _("Read all the metadata files and exit")), - ("rewritemeta", _("Rewrite all the metadata files")), - ("lint", _("Warn about possible metadata errors")), - ("scanner", _("Scan the source code of a package")), - ("dscanner", _("Dynamically scan APKs post build")), - ("stats", _("Update the stats of the repo")), - ("server", _("Old, deprecated name for fdroid deploy")), - ("signindex", _("Sign indexes created using update --nosign")), - ("btlog", _("Update the binary transparency log for a URL")), - ("signatures", _("Extract signatures from APKs")), - ("nightly", _("Set up an app build for a nightly build repo")), - ("mirror", _("Download complete mirrors of small repos")), -]) - - -def print_help(): - print(_("usage: ") + _("fdroid [] [-h|--help|--version|]")) - print("") - print(_("Valid commands are:")) - for cmd, summary in commands.items(): - print(" " + cmd + ' ' * (15 - len(cmd)) + summary) - print("") - - -def main(): - - if len(sys.argv) <= 1: - print_help() - sys.exit(0) - - command = sys.argv[1] - if command not in commands: - if command in ('-h', '--help'): - print_help() - sys.exit(0) - elif command == '--version': - output = _('no version info found!') - cmddir = os.path.realpath(os.path.dirname(__file__)) - moduledir = os.path.realpath(os.path.dirname(fdroidserver.common.__file__) + '/..') - if cmddir == moduledir: - # running from git - os.chdir(cmddir) - if os.path.isdir('.git'): - import subprocess - try: - output = subprocess.check_output(['git', 'describe'], - stderr=subprocess.STDOUT, - universal_newlines=True) - except subprocess.CalledProcessError: - output = 'git commit ' + subprocess.check_output(['git', 'rev-parse', 'HEAD'], - universal_newlines=True) - elif os.path.exists('setup.py'): - import re - m = re.search(r'''.*[\s,\(]+version\s*=\s*["']([0-9a-z.]+)["'].*''', - open('setup.py').read(), flags=re.MULTILINE) - if m: - output = m.group(1) + '\n' - else: - from pkg_resources import get_distribution - output = get_distribution('fdroidserver').version + '\n' - print(output), - sys.exit(0) - else: - print(_("Command '%s' not recognised.\n" % command)) - print_help() - sys.exit(1) - - verbose = any(s in sys.argv for s in ['-v', '--verbose']) - quiet = any(s in sys.argv for s in ['-q', '--quiet']) - - # Helpful to differentiate warnings from errors even when on quiet - logformat = '%(levelname)s: %(message)s' - loglevel = logging.INFO - if verbose: - loglevel = logging.DEBUG - elif quiet: - loglevel = logging.WARN - - logging.basicConfig(format=logformat, level=loglevel) - - if verbose and quiet: - logging.critical(_("Conflicting arguments: '--verbose' and '--quiet' " - "can not be specified at the same time.")) - sys.exit(1) - - # temporary workaround until server.py becomes deploy.py - if command == 'deploy': - command = 'server' - sys.argv.insert(2, 'update') - - # Trick optparse into displaying the right usage when --help is used. - sys.argv[0] += ' ' + command - - del sys.argv[1] - mod = __import__('fdroidserver.' + command, None, None, [command]) - - system_langcode, system_encoding = locale.getdefaultlocale() - if system_encoding is None or system_encoding.lower() not in ('utf-8', 'utf8'): - logging.warn(_("Encoding is set to '{enc}' fdroid might run " - "into encoding issues. Please set it to 'UTF-8' " - "for best results.".format(enc=system_encoding))) - - try: - mod.main() - # These are ours, contain a proper message and are "expected" - except (fdroidserver.common.FDroidException, - fdroidserver.metadata.MetaDataException) as e: - if verbose: - raise - else: - logging.critical(str(e)) - sys.exit(1) - except ArgumentError as e: - logging.critical(str(e)) - sys.exit(1) - except KeyboardInterrupt: - print('') - fdroidserver.common.force_exit(1) - # These should only be unexpected crashes due to bugs in the code - # str(e) often doesn't contain a reason, so just show the backtrace - except Exception as e: - logging.critical(_("Unknown exception found!")) - raise e - sys.exit(0) - - -if __name__ == "__main__": - main() +fdroidserver.__main__.main() diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py new file mode 100755 index 00000000..d2daad34 --- /dev/null +++ b/fdroidserver/__main__.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# +# fdroidserver/__main__.py - part of the FDroid server tools +# Copyright (C) 2010-2015, Ciaran Gultnieks, ciaran@ciarang.com +# Copyright (C) 2013-2014 Daniel Marti +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import sys +import os +import locale +import logging + +import fdroidserver.common +import fdroidserver.metadata +from fdroidserver import _ +from argparse import ArgumentError +from collections import OrderedDict + + +commands = OrderedDict([ + ("build", _("Build a package from source")), + ("init", _("Quickly start a new repository")), + ("publish", _("Sign and place packages in the repo")), + ("gpgsign", _("Add PGP signatures using GnuPG for packages in repo")), + ("update", _("Update repo information for new packages")), + ("deploy", _("Interact with the repo HTTP server")), + ("verify", _("Verify the integrity of downloaded packages")), + ("checkupdates", _("Check for updates to applications")), + ("import", _("Add a new application from its source code")), + ("install", _("Install built packages on devices")), + ("readmeta", _("Read all the metadata files and exit")), + ("rewritemeta", _("Rewrite all the metadata files")), + ("lint", _("Warn about possible metadata errors")), + ("scanner", _("Scan the source code of a package")), + ("dscanner", _("Dynamically scan APKs post build")), + ("stats", _("Update the stats of the repo")), + ("server", _("Old, deprecated name for fdroid deploy")), + ("signindex", _("Sign indexes created using update --nosign")), + ("btlog", _("Update the binary transparency log for a URL")), + ("signatures", _("Extract signatures from APKs")), + ("nightly", _("Set up an app build for a nightly build repo")), + ("mirror", _("Download complete mirrors of small repos")), +]) + + +def print_help(): + print(_("usage: ") + _("fdroid [] [-h|--help|--version|]")) + print("") + print(_("Valid commands are:")) + for cmd, summary in commands.items(): + print(" " + cmd + ' ' * (15 - len(cmd)) + summary) + print("") + + +def main(): + + if len(sys.argv) <= 1: + print_help() + sys.exit(0) + + command = sys.argv[1] + if command not in commands: + if command in ('-h', '--help'): + print_help() + sys.exit(0) + elif command == '--version': + output = _('no version info found!') + cmddir = os.path.realpath(os.path.dirname(__file__)) + moduledir = os.path.realpath(os.path.dirname(fdroidserver.common.__file__) + '/..') + if cmddir == moduledir: + # running from git + os.chdir(cmddir) + if os.path.isdir('.git'): + import subprocess + try: + output = subprocess.check_output(['git', 'describe'], + stderr=subprocess.STDOUT, + universal_newlines=True) + except subprocess.CalledProcessError: + output = 'git commit ' + subprocess.check_output(['git', 'rev-parse', 'HEAD'], + universal_newlines=True) + elif os.path.exists('setup.py'): + import re + m = re.search(r'''.*[\s,\(]+version\s*=\s*["']([0-9a-z.]+)["'].*''', + open('setup.py').read(), flags=re.MULTILINE) + if m: + output = m.group(1) + '\n' + else: + from pkg_resources import get_distribution + output = get_distribution('fdroidserver').version + '\n' + print(output), + sys.exit(0) + else: + print(_("Command '%s' not recognised.\n" % command)) + print_help() + sys.exit(1) + + verbose = any(s in sys.argv for s in ['-v', '--verbose']) + quiet = any(s in sys.argv for s in ['-q', '--quiet']) + + # Helpful to differentiate warnings from errors even when on quiet + logformat = '%(levelname)s: %(message)s' + loglevel = logging.INFO + if verbose: + loglevel = logging.DEBUG + elif quiet: + loglevel = logging.WARN + + logging.basicConfig(format=logformat, level=loglevel) + + if verbose and quiet: + logging.critical(_("Conflicting arguments: '--verbose' and '--quiet' " + "can not be specified at the same time.")) + sys.exit(1) + + # temporary workaround until server.py becomes deploy.py + if command == 'deploy': + command = 'server' + sys.argv.insert(2, 'update') + + # Trick optparse into displaying the right usage when --help is used. + sys.argv[0] += ' ' + command + + del sys.argv[1] + mod = __import__('fdroidserver.' + command, None, None, [command]) + + system_langcode, system_encoding = locale.getdefaultlocale() + if system_encoding is None or system_encoding.lower() not in ('utf-8', 'utf8'): + logging.warn(_("Encoding is set to '{enc}' fdroid might run " + "into encoding issues. Please set it to 'UTF-8' " + "for best results.".format(enc=system_encoding))) + + try: + mod.main() + # These are ours, contain a proper message and are "expected" + except (fdroidserver.common.FDroidException, + fdroidserver.metadata.MetaDataException) as e: + if verbose: + raise + else: + logging.critical(str(e)) + sys.exit(1) + except ArgumentError as e: + logging.critical(str(e)) + sys.exit(1) + except KeyboardInterrupt: + print('') + fdroidserver.common.force_exit(1) + # These should only be unexpected crashes due to bugs in the code + # str(e) often doesn't contain a reason, so just show the backtrace + except Exception as e: + logging.critical(_("Unknown exception found!")) + raise e + sys.exit(0) + + +if __name__ == "__main__": + main() From f21481ca81a6120b6ac8b9db095c4c417069ea59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 20 Jan 2020 23:16:34 +0100 Subject: [PATCH 0198/2775] add some simple tests for main --- tests/main.TestCase | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100755 tests/main.TestCase diff --git a/tests/main.TestCase b/tests/main.TestCase new file mode 100755 index 00000000..82adac46 --- /dev/null +++ b/tests/main.TestCase @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +import inspect +import logging +import optparse +import os +import shutil +import sys +import unittest +import tempfile +import textwrap +from unittest import mock + +localmodule = os.path.realpath( + os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) +print('localmodule: ' + localmodule) +if localmodule not in sys.path: + sys.path.insert(0, localmodule) + +from fdroidserver import common +import fdroidserver.__main__ + + +class FdroidTest(unittest.TestCase): + '''this tests fdroid.py''' + + def test_commands(self): + """make sure the built in sub-command defs didn't change unintentionally""" + self.assertListEqual([x for x in fdroidserver.__main__.commands.keys()], + ['build', + 'init', + 'publish', + 'gpgsign', + 'update', + 'deploy', + 'verify', + 'checkupdates', + 'import', + 'install', + 'readmeta', + 'rewritemeta', + 'lint', + 'scanner', + 'dscanner', + 'stats', + 'server', + 'signindex', + 'btlog', + 'signatures', + 'nightly', + 'mirror']) + + def test_call_init(self): + co = mock.Mock() + with mock.patch('sys.argv', ['', 'init', '-h']): + with mock.patch('fdroidserver.init.main', co): + with mock.patch('sys.exit', lambda x: None): + fdroidserver.__main__.main() + co.assert_called_once() + + def test_call_deploy(self): + co = mock.Mock() + with mock.patch('sys.argv', ['', 'deploy', '-h']): + with mock.patch('fdroidserver.server.main', co): + with mock.patch('sys.exit', lambda x: None): + fdroidserver.__main__.main() + co.assert_called_once() + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + + parser = optparse.OptionParser() + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="Spew out even more information than normal") + (common.options, args) = parser.parse_args(['--verbose']) + + newSuite = unittest.TestSuite() + newSuite.addTest(unittest.makeSuite(FdroidTest)) + unittest.main(failfast=False) From 69fc38c6684822a47f2d489a0cc18b0246eb93d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 21 Jan 2020 00:00:11 +0100 Subject: [PATCH 0199/2775] repair fdroid --version --- fdroidserver/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index d2daad34..953e3bd3 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -77,7 +77,7 @@ def main(): sys.exit(0) elif command == '--version': output = _('no version info found!') - cmddir = os.path.realpath(os.path.dirname(__file__)) + cmddir = os.path.realpath(os.path.dirname(os.path.dirname(__file__))) moduledir = os.path.realpath(os.path.dirname(fdroidserver.common.__file__) + '/..') if cmddir == moduledir: # running from git From b25eeb66a12acb86145015db9cb2c3b0b1dc540e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 21 Jan 2020 17:10:40 +0100 Subject: [PATCH 0200/2775] fix code style --- fdroid | 2 +- tests/main.TestCase | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/fdroid b/fdroid index 2ad697b2..248282b2 100755 --- a/fdroid +++ b/fdroid @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # fdroid.py - part of the FDroid server tools # Copyright (C) 2020 Michael Pöhn Date: Tue, 28 Jan 2020 11:40:58 +0100 Subject: [PATCH 0201/2775] fix tests on old python version --- fdroid | 2 +- tests/main.TestCase | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fdroid b/fdroid index 248282b2..314d2467 100755 --- a/fdroid +++ b/fdroid @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # # fdroid.py - part of the FDroid server tools -# Copyright (C) 2020 Michael Pöhn # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by diff --git a/tests/main.TestCase b/tests/main.TestCase index 2581e33d..cceafcf4 100755 --- a/tests/main.TestCase +++ b/tests/main.TestCase @@ -52,7 +52,7 @@ class FdroidTest(unittest.TestCase): with mock.patch('fdroidserver.init.main', co): with mock.patch('sys.exit', lambda x: None): fdroidserver.__main__.main() - co.assert_called_once() + co.assert_called_once_with() def test_call_deploy(self): co = mock.Mock() @@ -60,7 +60,7 @@ class FdroidTest(unittest.TestCase): with mock.patch('fdroidserver.server.main', co): with mock.patch('sys.exit', lambda x: None): fdroidserver.__main__.main() - co.assert_called_once() + co.assert_called_once_with() if __name__ == "__main__": From 89614851250c79a05db84070feca6dea033af334 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 31 Jan 2020 14:16:33 +0100 Subject: [PATCH 0202/2775] remove dscanner subcommand It's unused and unmaintained. It could potentially be revived as a plugin at a later point. --- MANIFEST.in | 7 - README.md | 16 -- completion/bash-completion | 16 -- docker/Dockerfile | 180 -------------- docker/Makefile | 48 ---- docker/README.md | 13 - docker/drozer.py | 35 --- docker/enable_service.py | 16 -- docker/entrypoint.sh | 42 ---- docker/install_agent.py | 63 ----- fdroidserver/__main__.py | 1 - fdroidserver/build.py | 39 --- fdroidserver/dscanner.py | 484 ------------------------------------- locale/POTFILES.in | 1 - setup.py | 1 - tests/main.TestCase | 1 - 16 files changed, 963 deletions(-) delete mode 100644 docker/Dockerfile delete mode 100644 docker/Makefile delete mode 100644 docker/README.md delete mode 100644 docker/drozer.py delete mode 100755 docker/enable_service.py delete mode 100755 docker/entrypoint.sh delete mode 100755 docker/install_agent.py delete mode 100644 fdroidserver/dscanner.py diff --git a/MANIFEST.in b/MANIFEST.in index 8be4dabf..04434d18 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -8,13 +8,6 @@ include buildserver/setup-env-vars include buildserver/Vagrantfile include CHANGELOG.md include completion/bash-completion -include docker/Dockerfile -include docker/drozer.py -include docker/enable_service.py -include docker/entrypoint.sh -include docker/install_agent.py -include docker/Makefile -include docker/README.md include examples/config.py include examples/fdroid-icon.png include examples/makebuildserver.config.py diff --git a/README.md b/README.md index 00ddb3bc..dac49d72 100644 --- a/README.md +++ b/README.md @@ -85,22 +85,6 @@ RAM. These test scripts are in the root of the project, all starting with _jenkins-_ since they are run on https://jenkins.debian.net. - -### Drozer Scanner - -There is a new feature under development that can scan any APK in a -repo, or any build, using Drozer. Drozer is a dynamic exploit -scanner, it runs an app in the emulator and runs known exploits on it. - -This setup requires specific versions of two Python modules: -_docker-py_ 1.9.0 and _requests_ older than 2.11. Other versions -might cause the docker-py connection to break with the containers. -Newer versions of docker-py might have this fixed already. - -For Debian based distributions: - - apt-get install libffi-dev libssl-dev python-docker - ## Translation Everything can be translated. See diff --git a/completion/bash-completion b/completion/bash-completion index d00a767a..780509db 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -104,22 +104,6 @@ __complete_build() { esac } -__complete_dscanner() { - opts="-v -q -l" - lopts="--verbose --quiet --clean-after --clean-before --clean-only --init-only --latest --repo-path" - case "${cur}" in - -*) - __complete_options - return 0;; - *:) - __vercode - return 0;; - *) - __package - return 0;; - esac -} - __complete_gpgsign() { opts="-v -q" lopts="--verbose --quiet" diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 9b7b4fb6..00000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,180 +0,0 @@ -# This image is intended to be used with fdroidserver for the purpose -# of dynamic scanning of pre-built APKs during the fdroid build process. - -# Start with ubuntu 12.04 (i386). -FROM ubuntu:14.04 -MAINTAINER fdroid.dscanner - -ENV DROZER_URL https://github.com/mwrlabs/drozer/releases/download/2.3.4/drozer_2.3.4.deb -ENV DROZER_DEB drozer_2.3.4.deb - -ENV AGENT_URL https://github.com/mwrlabs/drozer/releases/download/2.3.4/drozer-agent-2.3.4.apk -ENV AGENT_APK drozer-agent-2.3.4.apk - -# Specially for SSH access and port redirection -ENV ROOTPASSWORD android - -# Expose ADB, ADB control and VNC ports -EXPOSE 22 -EXPOSE 5037 -EXPOSE 5554 -EXPOSE 5555 -EXPOSE 5900 -EXPOSE 5901 - -ENV DEBIAN_FRONTEND noninteractive -RUN echo "debconf shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections -RUN echo "debconf shared/accepted-oracle-license-v1-1 seen true" | debconf-set-selections - -# Update packages -RUN apt-get -y update - -# Drozer packages -RUN apt-get install wget python2.7 python-dev python2.7-dev python-openssl python-twisted python-protobuf bash-completion -y - -# First, install add-apt-repository, sshd and bzip2 -RUN apt-get -y install python-software-properties bzip2 ssh net-tools - -# ubuntu 14.04 needs this too -RUN apt-get -y install software-properties-common - -# Add oracle-jdk7 to repositories -RUN add-apt-repository ppa:webupd8team/java - -# Make sure the package repository is up to date -RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe" > /etc/apt/sources.list - -# Update apt -RUN apt-get update - -# Add drozer -RUN useradd -ms /bin/bash drozer - -# Install oracle-jdk7 -RUN apt-get -y install oracle-java7-installer - -# Install android sdk -RUN wget http://dl.google.com/android/android-sdk_r23-linux.tgz -RUN tar -xvzf android-sdk_r23-linux.tgz -RUN mv -v android-sdk-linux /usr/local/android-sdk - -# Install apache ant -RUN wget http://archive.apache.org/dist/ant/binaries/apache-ant-1.8.4-bin.tar.gz -RUN tar -xvzf apache-ant-1.8.4-bin.tar.gz -RUN mv -v apache-ant-1.8.4 /usr/local/apache-ant - -# Add android tools and platform tools to PATH -ENV ANDROID_HOME /usr/local/android-sdk -ENV PATH $PATH:$ANDROID_HOME/tools -ENV PATH $PATH:$ANDROID_HOME/platform-tools - -# Add ant to PATH -ENV ANT_HOME /usr/local/apache-ant -ENV PATH $PATH:$ANT_HOME/bin - -# Export JAVA_HOME variable -ENV JAVA_HOME /usr/lib/jvm/java-7-oracle - -# Remove compressed files. -RUN cd /; rm android-sdk_r23-linux.tgz && rm apache-ant-1.8.4-bin.tar.gz - -# Some preparation before update -RUN chown -R root:root /usr/local/android-sdk/ - -# Install latest android tools and system images -RUN echo "y" | android update sdk --filter platform-tool --no-ui --force -RUN echo "y" | android update sdk --filter platform --no-ui --force -RUN echo "y" | android update sdk --filter build-tools-22.0.1 --no-ui -a -RUN echo "y" | android update sdk --filter sys-img-x86-android-19 --no-ui -a -#RUN echo "y" | android update sdk --filter sys-img-x86-android-21 --no-ui -a -#RUN echo "y" | android update sdk --filter sys-img-x86-android-22 --no-ui -a -RUN echo "y" | android update sdk --filter sys-img-armeabi-v7a-android-19 --no-ui -a -#RUN echo "y" | android update sdk --filter sys-img-armeabi-v7a-android-21 --no-ui -a -#RUN echo "y" | android update sdk --filter sys-img-armeabi-v7a-android-22 --no-ui -a - -# Update ADB -RUN echo "y" | android update adb - -# Create fake keymap file -RUN mkdir /usr/local/android-sdk/tools/keymaps -RUN touch /usr/local/android-sdk/tools/keymaps/en-us - -# Run sshd -RUN apt-get install -y openssh-server -RUN mkdir /var/run/sshd -RUN echo "root:$ROOTPASSWORD" | chpasswd -RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config -RUN sed -i 's/PermitEmptyPasswords no/PermitEmptyPasswords yes/' /etc/ssh/sshd_config - -# SSH login fix. Otherwise user is kicked off after login -RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd - -ENV NOTVISIBLE "in users profile" -RUN echo "export VISIBLE=now" >> /etc/profile - -# Install socat -RUN apt-get install -y socat - -# symlink android bins -RUN ln -sv /usr/local/android-sdk/tools/android /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/tools/emulator /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/tools/ddms /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/tools/scheenshot2 /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/tools/monkeyrunner /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/tools/monitor /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/tools/mksdcard /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/tools/uiautomatorviewer /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/tools/traceview /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/platform-tools/adb /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/platform-tools/fastboot /usr/local/bin/ -RUN ln -sv /usr/local/android-sdk/platform-tools/sqlite3 /usr/local/bin/ - -# Setup DROZER... -# https://labs.mwrinfosecurity.com/tools/drozer/ - -# Run as drozer user -WORKDIR /home/drozer - -# Site lists the shasums, however, I'm not sure the best way to integrate the -# checks here. No real idiomatic way for Dockerfile to do that and most of -# the examples online use chained commands but we want things to *BREAK* when -# the sha doesn't match. So far, I can't seem to reliably make Docker not -# finish the image build process. - -# Download the console -RUN wget -c $DROZER_URL - -# Install the console -RUN dpkg -i $DROZER_DEB - -# Download agent -RUN wget -c $AGENT_URL -# Keep it version agnostic for other scripts such as install_drozer.py -RUN mv -v $AGENT_APK drozer-agent.apk - -# Port forwarding required by drozer -RUN echo 'adb forward tcp:31415 tcp:31415' >> /home/drozer/.bashrc - -# Alias for Drozer -RUN echo "alias drozer='drozer console connect'" >> /home/drozer/.bashrc - -# add extra scripting -COPY install_agent.py /home/drozer/install_agent.py -RUN chmod 755 /home/drozer/install_agent.py -COPY enable_service.py /home/drozer/enable_service.py -RUN chmod 755 /home/drozer/enable_service.py -COPY drozer.py /home/drozer/drozer.py -RUN chmod 755 /home/drozer/drozer.py - -# fix ownerships -RUN chown -R drozer.drozer /home/drozer - -RUN apt-get -y --force-yes install python-pkg-resources=3.3-1ubuntu1 -RUN apt-get -y install python-pip python-setuptools git -RUN pip install "git+https://github.com/dtmilano/AndroidViewClient.git#egg=androidviewclient" -RUN apt-get -y install python-pexpect - -# Add entrypoint -COPY entrypoint.sh /home/drozer/entrypoint.sh -RUN chmod +x /home/drozer/entrypoint.sh -ENTRYPOINT ["/home/drozer/entrypoint.sh"] diff --git a/docker/Makefile b/docker/Makefile deleted file mode 100644 index eacb3268..00000000 --- a/docker/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -SHELL := /bin/bash -ALIAS = "dscanner" -EXISTS := $(shell docker ps -a -q -f name=$(ALIAS)) -RUNNED := $(shell docker ps -q -f name=$(ALIAS)) -ifneq "$(RUNNED)" "" -IP := $(shell docker inspect $(ALIAS) | grep "IPAddress\"" | head -n1 | cut -d '"' -f 4) -endif -STALE_IMAGES := $(shell docker images | grep "" | awk '{print($$3)}') -EMULATOR ?= "android-19" -ARCH ?= "armeabi-v7a" - -COLON := : - -.PHONY = build clean kill info - -all: help - -help: - @echo "usage: make {help|build|clean|kill|info}" - @echo "" - @echo " help this help screen" - @echo " build create docker image" - @echo " clean remove images and containers" - @echo " kill stop running containers" - @echo " info details of running container" - -build: - @docker build -t "dscanner/fdroidserver:latest" . - -clean: kill - @docker ps -a -q | xargs -n 1 -I {} docker rm -f {} -ifneq "$(STALE_IMAGES)" "" - @docker rmi -f $(STALE_IMAGES) -endif - -kill: -ifneq "$(RUNNED)" "" - @docker kill $(ALIAS) -endif - -info: - @docker ps -a -f name=$(ALIAS) -ifneq "$(RUNNED)" "" - $(eval ADBPORT := $(shell docker port $(ALIAS) | grep '5555/tcp' | awk '{split($$3,a,"$(COLON)");print a[2]}')) - @echo -e "Use:\n adb kill-server\n adb connect $(IP):$(ADBPORT)" -else - @echo "Run container" -endif diff --git a/docker/README.md b/docker/README.md deleted file mode 100644 index 9f2d657c..00000000 --- a/docker/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# dscanner docker image # - -Use `make help` for up-to-date instructions. - -``` -usage: make {help|build|clean|kill|info} - - help this help screen - build create docker image - clean remove images and containers - kill stop running containers - info details of running container -``` diff --git a/docker/drozer.py b/docker/drozer.py deleted file mode 100644 index d0546934..00000000 --- a/docker/drozer.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python2 - -import pexpect -import sys - -prompt = "dz>" -target = sys.argv[1] - -drozer = pexpect.spawn("drozer console connect") -drozer.logfile = open("/tmp/drozer_report.log", "w") - - -# start -drozer.expect(prompt) - - -def send_command(command, target): - cmd = "run {0} -a {1}".format(command, target) - drozer.sendline(cmd) - drozer.expect(prompt) - -scanners = [ - "scanner.misc.native", # Find native components included in packages - #"scanner.misc.readablefiles", # Find world-readable files in the given folder - #"scanner.misc.secretcodes", # Search for secret codes that can be used from the dialer - #"scanner.misc.sflagbinaries", # Find suid/sgid binaries in the given folder (default is /system). - #"scanner.misc.writablefiles", # Find world-writable files in the given folder - "scanner.provider.finduris", # Search for content providers that can be queried. - "scanner.provider.injection", # Test content providers for SQL injection vulnerabilities. - "scanner.provider.sqltables", # Find tables accessible through SQL injection vulnerabilities. - "scanner.provider.traversal" # Test content providers for basic directory traversal -] - -for scanner in scanners: - send_command(scanner, target) diff --git a/docker/enable_service.py b/docker/enable_service.py deleted file mode 100755 index 803532c9..00000000 --- a/docker/enable_service.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python2 - -from com.dtmilano.android.viewclient import ViewClient - -vc = ViewClient(*ViewClient.connectToDeviceOrExit()) - -button = vc.findViewWithText("OFF") - -if button: - (x, y) = button.getXY() - button.touch() -else: - print("Button not found. Is the app currently running?") - exit() - -print("Done!") diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh deleted file mode 100755 index 95b5ede1..00000000 --- a/docker/entrypoint.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -if [[ $EMULATOR == "" ]]; then - EMULATOR="android-19" - echo "Using default emulator $EMULATOR" -fi - -if [[ $ARCH == "" ]]; then - ARCH="x86" - echo "Using default arch $ARCH" -fi -echo EMULATOR = "Requested API: ${EMULATOR} (${ARCH}) emulator." -if [[ -n $1 ]]; then - echo "Last line of file specified as non-opt/last argument:" - tail -1 $1 -fi - -# Run sshd -/usr/sbin/sshd -adb start-server - -# Detect ip and forward ADB ports outside to outside interface -ip=$(ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}') -socat tcp-listen:5037,bind=$ip,fork tcp:127.0.0.1:5037 & -socat tcp-listen:5554,bind=$ip,fork tcp:127.0.0.1:5554 & -socat tcp-listen:5555,bind=$ip,fork tcp:127.0.0.1:5555 & - -# Set up and run emulator -if [[ $ARCH == *"x86"* ]] -then - EMU="x86" -else - EMU="arm" -fi - -#FASTDROID_VNC_URL="https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/fastdroid-vnc/fastdroid-vnc" -#wget -c "${FASTDROID_VNC_URL}" - -export PATH="${PATH}:/usr/local/android-sdk/tools/:/usr/local/android-sdk/platform-tools/" - -echo "no" | android create avd -f -n test -t ${EMULATOR} --abi default/${ARCH} -echo "no" | emulator64-${EMU} -avd test -noaudio -no-window -gpu off -verbose -qemu -usbdevice tablet -vnc :0 diff --git a/docker/install_agent.py b/docker/install_agent.py deleted file mode 100755 index 1a0f348a..00000000 --- a/docker/install_agent.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python2 - -import os -from subprocess import call, check_output -from time import sleep - -FNULL = open(os.devnull, 'w') - -print("Ensuring device is online") -call("adb wait-for-device", shell=True) - -print("Installing the drozer agent") -print("If the device just came online it is likely the package manager hasn't booted.") -print("Will try multiple attempts to install.") -print("This may need tweaking depending on hardware.") - - -attempts = 0 -time_to_sleep = 30 - -while attempts < 8: - output = check_output('adb shell "pm list packages"', shell=True) - print("Checking whether the package manager is up...") - if "Could not access the Package Manager" in output: - print("Nope. Sleeping for 30 seconds and then trying again.") - sleep(time_to_sleep) - else: - break - -time_to_sleep = 5 -attempts = 0 - -while attempts < 5: - sleep(time_to_sleep) - try: - install_output = check_output("adb install /home/drozer/drozer-agent.apk", shell=True) - except Exception: - print("Failed. Trying again.") - attempts += 1 - else: - attempts += 1 - if "Error: Could not access the Package Manager" not in install_output: - break - -print("Install attempted. Checking everything worked") - -pm_list_output = check_output('adb shell "pm list packages"', shell=True) - -if "com.mwr.dz" not in pm_list_output: - print(install_output) - exit("APK didn't install properly. Exiting.") - -print("Installed ok.") - -print("Starting the drozer agent main activity: com.mwr.dz/.activities.MainActivity") -call('adb shell "am start com.mwr.dz/.activities.MainActivity"', shell=True, stdout=FNULL) - -print("Starting the service") -# start the service -call("python /home/drozer/enable_service.py", shell=True, stdout=FNULL) - -print("Forward dem ports mon.") -call("adb forward tcp:31415 tcp:31415", shell=True, stdout=FNULL) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index 953e3bd3..a75236b9 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -44,7 +44,6 @@ commands = OrderedDict([ ("rewritemeta", _("Rewrite all the metadata files")), ("lint", _("Warn about possible metadata errors")), ("scanner", _("Scan the source code of a package")), - ("dscanner", _("Dynamically scan APKs post build")), ("stats", _("Update the stats of the repo")), ("server", _("Old, deprecated name for fdroid deploy")), ("signindex", _("Sign indexes created using update --nosign")), diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 0bc08745..a4a1f553 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -882,8 +882,6 @@ def parse_commandline(): help=argparse.SUPPRESS) parser.add_argument("--skip-scan", dest="skipscan", action="store_true", default=False, help=_("Skip scanning the source code for binaries and other problems")) - parser.add_argument("--dscanner", action="store_true", default=False, - 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, help=_("Don't create a source tarball, useful when testing a build")) parser.add_argument("--no-refresh", dest="refresh", action="store_false", default=True, @@ -1216,43 +1214,6 @@ def main(): for fa in failed_apps: logging.info("Build for app %s failed:\n%s" % (fa, failed_apps[fa])) - # perform a drozer scan of all successful builds - if options.dscanner and build_succeeded: - from .dscanner import DockerDriver - - docker = DockerDriver() - - try: - for app in build_succeeded: - - logging.info("Need to sign the app before we can install it.") - subprocess.call("fdroid publish {0}".format(app.id)) - - apk_path = None - - for f in os.listdir(repo_dir): - if f.endswith('.apk') and f.startswith(app.id): - apk_path = os.path.join(repo_dir, f) - break - - if not apk_path: - raise Exception("No signed APK found at path: {path}".format(path=apk_path)) - - if not os.path.isdir(repo_dir): - logging.critical("directory does not exists '{path}'".format(path=repo_dir)) - common.force_exit(1) - - logging.info("Performing Drozer scan on {0}.".format(app)) - docker.perform_drozer_scan(apk_path, app.id, repo_dir) - except Exception as e: - logging.error(str(e)) - logging.error("An exception happened. Making sure to clean up") - else: - logging.info("Scan succeeded.") - - logging.info("Cleaning up after ourselves.") - docker.clean() - logging.info(_("Finished")) if len(build_succeeded) > 0: logging.info(ngettext("{} build succeeded", diff --git a/fdroidserver/dscanner.py b/fdroidserver/dscanner.py deleted file mode 100644 index 49362e5f..00000000 --- a/fdroidserver/dscanner.py +++ /dev/null @@ -1,484 +0,0 @@ -#!/usr/bin/env python3 -# -# dscanner.py - part of the FDroid server tools -# Copyright (C) 2016-2017 Shawn Gustaw -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import logging -import os -import json -import sys -from time import sleep -from argparse import ArgumentParser -from subprocess import CalledProcessError, check_output - -from . import _ -from . import common -from . import metadata - -try: - from docker import Client -except ImportError: - logging.error(("Docker client not installed." - "Install it using pip install docker-py")) - -config = None -options = None - - -class DockerConfig: - ALIAS = "dscanner" - CONTAINER = "dscanner/fdroidserver" - EMULATOR = "android-19" - ARCH = "armeabi-v7a" - - -class DockerDriver(object): - """ - Handles all the interactions with the docker container the - Android emulator runs in. - """ - class Commands: - build = ['docker', 'build', '--no-cache=false', '--pull=true', - '--quiet=false', '--rm=true', '-t', - '{0}:latest'.format(DockerConfig.CONTAINER), '.'] - run = [ - 'docker', 'run', - '-e', '"EMULATOR={0}"'.format(DockerConfig.EMULATOR), - '-e', '"ARCH={0}"'.format(DockerConfig.ARCH), - '-d', '-P', '--name', - '{0}'.format(DockerConfig.ALIAS), '--log-driver=json-file', - DockerConfig.CONTAINER] - start = ['docker', 'start', '{0}'.format(DockerConfig.ALIAS)] - inspect = ['docker', 'inspect', '{0}'.format(DockerConfig.ALIAS)] - pm_list = 'adb shell "pm list packages"' - install_drozer = "docker exec {0} python /home/drozer/install_agent.py" - run_drozer = 'python /home/drozer/drozer.py {0}' - copy_to_container = 'docker cp "{0}" {1}:{2}' - copy_from_container = 'docker cp {0}:{1} "{2}"' - - def __init__(self, init_only=False, fresh_start=False, clean_only=False): - self.container_id = None - self.ip_address = None - - self.cli = Client(base_url='unix://var/run/docker.sock') - - if fresh_start or clean_only: - self.clean() - - if clean_only: - logging.info("Cleaned containers and quitting.") - exit(0) - - self.init_docker() - - if init_only: - logging.info("Initialized and quitting.") - exit(0) - - def _copy_to_container(self, src_path, dest_path): - """ - Copies a file (presumed to be an apk) from src_path - to home directory on container. - """ - path = '/home/drozer/{path}.apk'.format(path=dest_path) - command = self.Commands.copy_to_container.format(src_path, - self.container_id, - path) - - try: - check_output(command, shell=True) - except CalledProcessError as e: - logging.error(('Command "{command}" failed with ' - 'error code {code}'.format(command=command, - code=e.returncode))) - raise - - def _copy_from_container(self, src_path, dest_path): - """ - Copies a file from src_path on the container to - dest_path on the host machine. - """ - command = self.Commands.copy_from_container.format(self.container_id, - src_path, - dest_path) - try: - check_output(command, shell=True) - except CalledProcessError as e: - logging.error(('Command "{command}" failed with ' - 'error code {code}'.format(command=command, - code=e.returncode))) - raise - - logging.info("Log stored at {path}".format(path=dest_path)) - - def _adb_install_apk(self, apk_path): - """ - Installs an apk on the device running in the container - using adb. - """ - logging.info("Attempting to install an apk.") - exec_id = self.cli.exec_create( - self.container_id, 'adb install {0}' - .format(apk_path) - )['Id'] - output = self.cli.exec_start(exec_id).decode('utf-8') - - if "INSTALL_PARSE_FAILED_NO_CERTIFICATES" in output: - raise Exception('Install parse failed, no certificates') - elif "INSTALL_FAILED_ALREADY_EXISTS" in output: - logging.info("APK already installed. Skipping.") - elif "Success" not in output: - logging.error("APK didn't install properly") - return False - return True - - def _adb_uninstall_apk(self, app_id): - """ - Uninstalls an application from the device running in the container - via its app_id. - """ - logging.info( - "Uninstalling {app_id} from the emulator." - .format(app_id=app_id) - ) - exec_id = self.cli.exec_create( - self.container_id, - 'adb uninstall {0}'.format(app_id) - )['Id'] - output = self.cli.exec_start(exec_id).decode('utf-8') - - if 'Success' in output: - logging.info("Successfully uninstalled.") - - return True - - def _verify_apk_install(self, app_id): - """ - Checks that the app_id is installed on the device running in the - container. - """ - logging.info( - "Verifying {app} is installed on the device." - .format(app=app_id) - ) - exec_id = self.cli.exec_create( - self.container_id, self.Commands.pm_list - )['Id'] - output = self.cli.exec_start(exec_id).decode('utf-8') - - if ("Could not access the Package Manager" in output - or "device offline" in output): - logging.info("Device or package manager isn't up") - - if app_id.split('_')[0] in output: # TODO: this is a temporary fix - logging.info("{app} is installed.".format(app=app_id)) - return True - - logging.error("APK not found in packages list on emulator.") - - def _delete_file(self, path): - """ - Deletes file off the container to preserve space if scanning many apps - """ - command = "rm {path}".format(path=path) - exec_id = self.cli.exec_create(self.container_id, command)['Id'] - logging.info("Deleting {path} on the container.".format(path=path)) - self.cli.exec_start(exec_id) - - def _install_apk(self, apk_path, app_id): - """ - Installs apk found at apk_path on the emulator. Will then - verify it installed properly by looking up its app_id in - the package manager. - """ - if not all([self.container_id, self.ip_address]): - # TODO: maybe have this fail nicely - raise Exception("Went to install apk and couldn't find container") - - path = "/home/drozer/{app_id}.apk".format(app_id=app_id) - self._copy_to_container(apk_path, app_id) - self._adb_install_apk(path) - self._verify_apk_install(app_id) - self._delete_file(path) - - def _install_drozer(self): - """ - Performs all the initialization of drozer within the emulator. - """ - logging.info("Attempting to install com.mwr.dz on the emulator") - logging.info("This could take a while so be patient...") - logging.info(("We need to wait for the device to boot AND" - " the package manager to come online.")) - command = self.Commands.install_drozer.format(self.container_id) - try: - output = check_output(command, - shell=True).decode('utf-8') - except CalledProcessError as e: - logging.error(('Command "{command}" failed with ' - 'error code {code}'.format(command=command, - code=e.returncode))) - raise - - if 'Installed ok' in output: - return True - - def _run_drozer_scan(self, app): - """ - Runs the drozer agent which connects to the app running - on the emulator. - """ - logging.info("Running the drozer agent") - exec_id = self.cli.exec_create( - self.container_id, - self.Commands.run_drozer.format(app) - )['Id'] - self.cli.exec_start(exec_id) - - def _container_is_running(self): - """ - Checks whether the emulator container is running. - """ - for container in self.cli.containers(): - if DockerConfig.ALIAS in container['Image']: - return True - - def _docker_image_exists(self): - """ - Check whether the docker image exists already. - If this returns false we'll need to build the image - from the DockerFile. - """ - for image in self.cli.images(): - for tag in image['RepoTags']: - if DockerConfig.ALIAS in tag: - return True - - _image_queue = {} - - def _build_docker_image(self): - """ - Builds the docker container so we can run the android emulator - inside it. - """ - logging.info("Pulling the container from docker hub") - logging.info("Image is roughly 5 GB so be patient") - - logging.info("(Progress output is slow and requires a tty.)") - # we pause briefly to narrow race condition windows of opportunity - sleep(1) - - is_a_tty = os.isatty(sys.stdout.fileno()) - - for output in self.cli.pull( - DockerConfig.CONTAINER, - stream=True, - tag="latest"): - if not is_a_tty: - # run silent, run quick - continue - try: - p = json.loads(output.decode('utf-8')) - p_id = p['id'] - self._image_queue[p_id] = p - t, c, j = 1, 1, 0 - for k in sorted(self._image_queue): - j += 1 - v = self._image_queue[k] - vd = v['progressDetail'] - t += vd['total'] - c += vd['current'] - msg = "\rDownloading: {0}/{1} {2}% [{3} jobs]" - msg = msg.format(c, t, int(c / t * 100), j) - sys.stdout.write(msg) - sys.stdout.flush() - except Exception: - pass - print("\nDONE!\n") - - def _verify_apk_exists(self, full_apk_path): - """ - Verifies that the apk path we have is actually a file. - """ - return os.path.isfile(full_apk_path) - - def init_docker(self): - """ - Perform all the initialization required before a drozer scan. - 1. build the image - 2. run the container - 3. install drozer and enable the service within the app - """ - built = self._docker_image_exists() - - if not built: - self._build_docker_image() - - running = self._container_is_running() - - if not running: - logging.info('Trying to run container...') - try: - check_output(self.Commands.run) - except CalledProcessError as e: - logging.error(( - 'Command "{command}" failed with error code {code}' - .format(command=self.Commands.run, code=e.returncode) - )) - running = self._container_is_running() - - if not running: - logging.info('Trying to start container...') - try: - check_output(self.Commands.start) - except CalledProcessError as e: - logging.error(( - 'Command "{command}" failed with error code {code}' - .format(command=self.Commands.run, code=e.returncode) - )) - running = self._container_is_running() - - if not running: - raise Exception("Running container not found, critical error.") - - containers = self.cli.containers() - - for container in containers: - if DockerConfig.ALIAS in container['Image']: - self.container_id = container['Id'] - n = container['NetworkSettings']['Networks'] - self.ip_address = n['bridge']['IPAddress'] - break - - if not self.container_id or not self.ip_address: - logging.error("No ip address or container id found.") - exit(1) - - if self._verify_apk_install('com.mwr.dz'): - return - - self._install_drozer() - - def clean(self): - """ - Clean up all the containers made by this script. - Should be run after the drozer scan completes. - """ - for container in self.cli.containers(): - if DockerConfig.ALIAS in container['Image']: - logging.info("Removing container {0}".format(container['Id'])) - self.cli.remove_container(container['Id'], force=True) - - def perform_drozer_scan(self, apk_path, app_id): - """ - Entrypoint for scanning an android app. Performs the following steps: - 1. installs an apk on the device - 2. runs a drozer scan - 3. copies the report off the container - 4. uninstalls the apk to save space on the device - """ - self._install_apk(apk_path, app_id) - logging.info("Running the drozer scan.") - self._run_drozer_scan(app_id) - logging.info("Scan finished. Moving the report off the container") - dest = apk_path + '.drozer' - self._copy_from_container('/tmp/drozer_report.log', dest) - self._adb_uninstall_apk(app_id) - - -def main(): - global config, options - - # Parse command line... - parser = ArgumentParser( - usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]" - ) - common.setup_global_opts(parser) - - parser.add_argument( - "app_id", nargs='*', - help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) - parser.add_argument( - "-l", "--latest", action="store_true", default=False, - help=_("Scan only the latest version of each package")) - parser.add_argument( - "--clean-after", default=False, action='store_true', - help=_("Clean after all scans have finished")) - parser.add_argument( - "--clean-before", default=False, action='store_true', - help=_("Clean before the scans start and rebuild the container")) - parser.add_argument( - "--clean-only", default=False, action='store_true', - help=_("Clean up all containers and then exit")) - parser.add_argument( - "--init-only", default=False, action='store_true', - help=_("Prepare Drozer to run a scan")) - parser.add_argument( - "--repo-path", default="repo", action="store", - help=_("Override path for repo APKs (default: ./repo)")) - - options = parser.parse_args() - config = common.read_config(options) - - if not os.path.isdir(options.repo_path): - sys.stderr.write("repo-path not found: \"" + options.repo_path + "\"") - exit(1) - - # Read all app and srclib metadata - allapps = metadata.read_metadata() - apps = common.read_app_args(options.app_id, allapps, True) - - docker = DockerDriver( - init_only=options.init_only, - fresh_start=options.clean_before, - clean_only=options.clean_only - ) - - if options.clean_before: - docker.clean() - - if options.clean_only: - exit(0) - - for app_id, app in apps.items(): - vercode = 0 - if ':' in app_id: - vercode = app_id.split(':')[1] - for build in reversed(app.builds): - if build.disable: - continue - if options.latest or vercode == 0 or build.versionCode == vercode: - app.builds = [build] - break - continue - continue - - for app_id, app in apps.items(): - for build in app.builds: - apks = [] - for f in os.listdir(options.repo_path): - n = common.get_release_filename(app, build) - if f == n: - apks.append(f) - for apk in sorted(apks): - apk_path = os.path.join(options.repo_path, apk) - docker.perform_drozer_scan(apk_path, app.id) - - if options.clean_after: - docker.clean() - - -if __name__ == "__main__": - main() diff --git a/locale/POTFILES.in b/locale/POTFILES.in index 45480db2..7d31bec0 100644 --- a/locale/POTFILES.in +++ b/locale/POTFILES.in @@ -3,7 +3,6 @@ fdroidserver/btlog.py fdroidserver/build.py fdroidserver/checkupdates.py fdroidserver/common.py -fdroidserver/dscanner.py fdroidserver/import.py fdroidserver/init.py fdroidserver/install.py diff --git a/setup.py b/setup.py index f38759dc..40abdb19 100755 --- a/setup.py +++ b/setup.py @@ -86,7 +86,6 @@ setup(name='fdroidserver', 'qrcode', 'ruamel.yaml >= 0.15', 'requests >= 2.5.2, != 2.11.0, != 2.12.2, != 2.18.0', - 'docker-py >= 1.9, < 2.0', ], classifiers=[ 'Development Status :: 4 - Beta', diff --git a/tests/main.TestCase b/tests/main.TestCase index cceafcf4..8621cfcc 100755 --- a/tests/main.TestCase +++ b/tests/main.TestCase @@ -37,7 +37,6 @@ class FdroidTest(unittest.TestCase): 'rewritemeta', 'lint', 'scanner', - 'dscanner', 'stats', 'server', 'signindex', From d8f3d9499758c9d24138306ceb1333ab5d0a6e01 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 31 Jan 2020 15:17:49 +0100 Subject: [PATCH 0203/2775] gitlab-ci: remove dscanner exclusions from bandit --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 415a39b0..f555f613 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -141,7 +141,6 @@ lint_format_safety_bandit_checks: - bandit -ii -s B110,B310,B322,B404,B408,B410,B603,B607 - -x fdroidserver/dscanner.py,docker/install_agent.py,docker/drozer.py -r $CI_PROJECT_DIR fdroid || export EXITVALUE=1 - safety check --full-report || export EXITVALUE=1 From 3df276cc3c8c60d8a6b12e8f42aa3563b69a080e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 31 Jan 2020 15:20:24 +0100 Subject: [PATCH 0204/2775] fix all bandit B310 urllib_urlopen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Audit url open for permitted schemes. Allowing use of ‘file:’’ or custom schemes is often unexpected." https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html#b310-urllib-urlopen --- .gitlab-ci.yml | 2 +- fdroidserver/checkupdates.py | 6 +++--- fdroidserver/import.py | 5 +++-- tests/checkupdates.TestCase | 12 ++++++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f555f613..eb65036f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -140,7 +140,7 @@ lint_format_safety_bandit_checks: - ./hooks/pre-commit || export EXITVALUE=1 - bandit -ii - -s B110,B310,B322,B404,B408,B410,B603,B607 + -s B110,B322,B404,B408,B410,B603,B607 -r $CI_PROJECT_DIR fdroid || export EXITVALUE=1 - safety check --full-report || export EXITVALUE=1 diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 8620f899..5aa1e4bf 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -64,7 +64,7 @@ def check_http(app): if len(urlcode) > 0: logging.debug("...requesting {0}".format(urlcode)) req = urllib.request.Request(urlcode, None) - resp = urllib.request.urlopen(req, None, 20) + resp = urllib.request.urlopen(req, None, 20) # nosec B310 scheme is filtered above page = resp.read().decode('utf-8') m = re.search(codeex, page) @@ -77,7 +77,7 @@ def check_http(app): if urlver != '.': logging.debug("...requesting {0}".format(urlver)) req = urllib.request.Request(urlver, None) - resp = urllib.request.urlopen(req, None, 20) + resp = urllib.request.urlopen(req, None, 20) # nosec B310 scheme is filtered above page = resp.read().decode('utf-8') m = re.search(verex, page) @@ -295,7 +295,7 @@ def check_gplay(app): headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:18.0) Gecko/20100101 Firefox/18.0'} req = urllib.request.Request(url, None, headers) try: - resp = urllib.request.urlopen(req, None, 20) + resp = urllib.request.urlopen(req, None, 20) # nosec B310 URL base is hardcoded above page = resp.read().decode() except urllib.error.HTTPError as e: return (None, str(e.code)) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 51713cee..b463824c 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -40,8 +40,9 @@ SETTINGS_GRADLE = re.compile(r'''include\s+['"]:([^'"]*)['"]''') # when one of these is found it's assumed that's the information we want. # Returns repotype, address, or None, reason def getrepofrompage(url): - - req = urllib.request.urlopen(url) + if not url.startswith('http'): + return (None, _('{url} does not start with "http"!'.format(url=url))) + req = urllib.request.urlopen(url) # nosec B310 non-http URLs are filtered out if req.getcode() != 200: return (None, 'Unable to get ' + url + ' - return code ' + str(req.getcode())) page = req.read().decode(req.headers.get_content_charset()) diff --git a/tests/checkupdates.TestCase b/tests/checkupdates.TestCase index ab68cd8d..5d3ca311 100755 --- a/tests/checkupdates.TestCase +++ b/tests/checkupdates.TestCase @@ -19,6 +19,7 @@ if localmodule not in sys.path: import fdroidserver.checkupdates import fdroidserver.metadata +from fdroidserver.exception import FDroidException class CommonTest(unittest.TestCase): @@ -123,6 +124,17 @@ class CommonTest(unittest.TestCase): self.assertEqual(vername, '1.1.9') self.assertEqual(vercode, '10109') + def test_check_http_blocks_unknown_schemes(self): + app = fdroidserver.metadata.App() + for scheme in ('file', 'ssh', 'http', ';pwn'): + app.id = scheme + faked = scheme + '://fake.url/for/testing/scheme' + app.UpdateCheckData = faked + '|ignored|' + faked + '|ignored' + app.metadatapath = 'metadata/' + app.id + '.yml' + vername, vercode = fdroidserver.checkupdates.check_http(app) + self.assertIsNone(vername) + self.assertTrue(FDroidException.__name__ in vercode) + def test_check_http_ignore(self): fdroidserver.checkupdates.options = mock.Mock() From fdede914cd177f09a91b403c55ce9d7c24929dac Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 31 Jan 2020 15:23:16 +0100 Subject: [PATCH 0205/2775] tests: properly name CheckupdatesTest class --- tests/checkupdates.TestCase | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/checkupdates.TestCase b/tests/checkupdates.TestCase index 5d3ca311..7772dfa5 100755 --- a/tests/checkupdates.TestCase +++ b/tests/checkupdates.TestCase @@ -22,8 +22,8 @@ import fdroidserver.metadata from fdroidserver.exception import FDroidException -class CommonTest(unittest.TestCase): - '''fdroidserver/common.py''' +class CheckupdatesTest(unittest.TestCase): + '''fdroidserver/checkupdates.py''' def setUp(self): logging.basicConfig(level=logging.DEBUG) @@ -163,5 +163,5 @@ if __name__ == "__main__": (fdroidserver.common.options, args) = parser.parse_args(['--verbose']) newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(CommonTest)) + newSuite.addTest(unittest.makeSuite(CheckupdatesTest)) unittest.main(failfast=False) From 3b5e3a62a367acd59df293bdf2b324b3390b7564 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 13 Jan 2020 15:35:22 +0100 Subject: [PATCH 0206/2775] move getappname+getcvname to checkupdates, the only place they're used --- fdroidserver/checkupdates.py | 34 +++++++++++++++++++++++----------- fdroidserver/common.py | 12 ------------ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 5aa1e4bf..871ec98c 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -358,6 +358,18 @@ def possible_subdirs(app): yield subdir +def _getappname(app): + if app.Name: + return app.Name + if app.AutoName: + return app.AutoName + return app.id + + +def _getcvname(app): + return '%s (%s)' % (app.CurrentVersion, app.CurrentVersionCode) + + def fetch_autoname(app, tag): if not app.RepoType or app.UpdateCheckMode in ('None', 'Static') \ @@ -393,7 +405,7 @@ def fetch_autoname(app, tag): if new_name != app.AutoName: app.AutoName = new_name if not commitmsg: - commitmsg = "Set autoname of {0}".format(common.getappname(app)) + commitmsg = "Set autoname of {0}".format(_getappname(app)) else: logging.debug("...couldn't get autoname") @@ -472,8 +484,8 @@ def checkupdates_app(app): commitmsg = fetch_autoname(app, tag) if updating: - name = common.getappname(app) - ver = common.getcvname(app) + name = _getappname(app) + ver = _getcvname(app) logging.info('...updating to version %s' % ver) commitmsg = 'Update CV of %s to %s' % (name, ver) @@ -513,8 +525,8 @@ def checkupdates_app(app): commit = commit.replace('%c', newbuild.versionCode) newbuild.commit = commit app.builds.append(newbuild) - name = common.getappname(app) - ver = common.getcvname(app) + name = _getappname(app) + ver = _getcvname(app) commitmsg = "Update %s to %s" % (name, ver) else: logging.warning('Invalid auto update mode "' + mode + '" on ' + app.id) @@ -610,24 +622,24 @@ def main(): version, reason = check_gplay(app) if version is None: if reason == '404': - logging.info("{0} is not in the Play Store".format(common.getappname(app))) + logging.info("{0} is not in the Play Store".format(_getappname(app))) else: - logging.info("{0} encountered a problem: {1}".format(common.getappname(app), reason)) + logging.info("{0} encountered a problem: {1}".format(_getappname(app), reason)) if version is not None: stored = app.CurrentVersion if not stored: logging.info("{0} has no Current Version but has version {1} on the Play Store" - .format(common.getappname(app), version)) + .format(_getappname(app), version)) elif LooseVersion(stored) < LooseVersion(version): logging.info("{0} has version {1} on the Play Store, which is bigger than {2}" - .format(common.getappname(app), version, stored)) + .format(_getappname(app), version, stored)) else: if stored != version: logging.info("{0} has version {1} on the Play Store, which differs from {2}" - .format(common.getappname(app), version, stored)) + .format(_getappname(app), version, stored)) else: logging.info("{0} has the same version {1} on the Play Store" - .format(common.getappname(app), version)) + .format(_getappname(app), version)) update_wiki(gplaylog, None) return diff --git a/fdroidserver/common.py b/fdroidserver/common.py index f68bb88f..946c0de1 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -664,18 +664,6 @@ def getsrcname(app, build): return "%s_%s_src.tar.gz" % (app.id, build.versionCode) -def getappname(app): - if app.Name: - return app.Name - if app.AutoName: - return app.AutoName - return app.id - - -def getcvname(app): - return '%s (%s)' % (app.CurrentVersion, app.CurrentVersionCode) - - def get_build_dir(app): '''get the dir that this app will be built in''' From 6ce22bff566d57c0f9f8b127b1f2f60477e08a3b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 13 Jan 2020 18:54:28 +0100 Subject: [PATCH 0207/2775] update: strip newlines from name/summary/video entries These entries are hardcoded as a single line in all the app stores, so newlines should be stripped to get the data simple to use. This is in contrast with the on-disk format for Fastlane and Triple-T, which includes a newline in the title.txt and short_description.txt files. I think all files in those systems are normalized to end in a newline. --- fdroidserver/update.py | 5 ++++- tests/repo/index-v1.json | 6 +++--- tests/update.TestCase | 8 ++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index bc2583fc..44d4b8c0 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -714,7 +714,10 @@ def _set_localized_text_entry(app, locale, key, f): with open(f, errors='replace') as fp: text = fp.read()[:limit] if len(text) > 0: - localized[key] = text + if key in ('name', 'summary', 'video'): # hardcoded as a single line + localized[key] = text.strip('\n') + else: + localized[key] = text def _set_author_entry(app, key, f): diff --git a/tests/repo/index-v1.json b/tests/repo/index-v1.json index 492b6051..32d76b7d 100644 --- a/tests/repo/index-v1.json +++ b/tests/repo/index-v1.json @@ -198,9 +198,9 @@ "description": "full description\n", "featureGraphic": "featureGraphic_GFRT5BovZsENGpJq1HqPODGWBRPWQsx25B95Ol5w_wU=.png", "icon": "icon_NJXNzMcyf-v9i5a1ElJi0j9X1LvllibCa48xXYPlOqQ=.png", - "name": "title\n", - "summary": "short description\n", - "video": "video\n" + "name": "title", + "summary": "short description", + "video": "video" } } } diff --git a/tests/update.TestCase b/tests/update.TestCase index 61658292..e3d9ef53 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -114,9 +114,9 @@ class UpdateTest(unittest.TestCase): if packageName == 'info.guardianproject.urzip': self.assertEqual(7, len(app['localized']['en-US'])) self.assertEqual('full description\n', app['localized']['en-US']['description']) - self.assertEqual('title\n', app['localized']['en-US']['name']) - self.assertEqual('short description\n', app['localized']['en-US']['summary']) - self.assertEqual('video\n', app['localized']['en-US']['video']) + self.assertEqual('title', app['localized']['en-US']['name']) + self.assertEqual('short description', app['localized']['en-US']['summary']) + self.assertEqual('video', app['localized']['en-US']['video']) self.assertEqual('icon_NJXNzMcyf-v9i5a1ElJi0j9X1LvllibCa48xXYPlOqQ=.png', app['localized']['en-US']['icon']) self.assertEqual('featureGraphic_GFRT5BovZsENGpJq1HqPODGWBRPWQsx25B95Ol5w_wU=.png', @@ -140,7 +140,7 @@ class UpdateTest(unittest.TestCase): elif packageName == 'com.nextcloud.client.dev': self.assertEqual('Nextcloud Dev', app['localized']['en-US']['name']) self.assertEqual(586, len(app['localized']['en-US']['description'])) - self.assertEqual(79, len(app['localized']['en-US']['summary'])) + self.assertEqual(78, len(app['localized']['en-US']['summary'])) elif packageName == 'eu.siacs.conversations': self.assertEqual('Conversations', app['localized']['en-US']['name']) From 82a4817e8a3c9da9b9f900306c551ac67a3bc8ea Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 13 Jan 2020 16:06:07 +0100 Subject: [PATCH 0208/2775] fix field name errors in examples/template.yml --- examples/template.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/template.yml b/examples/template.yml index 37d72c16..72d584aa 100644 --- a/examples/template.yml +++ b/examples/template.yml @@ -2,7 +2,7 @@ AuthorName: . WebSite: '' Bitcoin: null Litecoin: null -Donation: null +Donate: null License: Unknown Categories: @@ -17,5 +17,5 @@ Summary: . Description: | . -Archive Policy: 2 versions -Requires Root: No +ArchivePolicy: 2 versions +RequiresRoot: No From 5c829565612c6f1adb1317fd953144a0698152ee Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 14 Jan 2020 15:12:21 +0100 Subject: [PATCH 0209/2775] mirror: make .asc downloading opt-in with --pgp-signatures Lots of third party repos do not use .asc PGP signatures at all, so having this optional prevents tons of 404 Not Found errors. --- completion/bash-completion | 2 +- fdroidserver/mirror.py | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index 780509db..4a54954d 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -253,7 +253,7 @@ __complete_btlog() { __complete_mirror() { opts="-v" - lopts="--archive --output-dir" + lopts="--all --archive --build-logs --pgp-signatures --src-tarballs --output-dir" __complete_options } diff --git a/fdroidserver/mirror.py b/fdroidserver/mirror.py index 920c9acf..2510e3d0 100644 --- a/fdroidserver/mirror.py +++ b/fdroidserver/mirror.py @@ -46,16 +46,26 @@ def main(): parser.add_argument("url", nargs='?', help=_('Base URL to mirror, can include the index signing key ' + 'using the query string: ?fingerprint=')) + parser.add_argument("--all", action='store_true', default=False, + help=_("Mirror the full repo and archive, all file types.")) parser.add_argument("--archive", action='store_true', default=False, help=_("Also mirror the full archive section")) parser.add_argument("--build-logs", action='store_true', default=False, help=_("Include the build logs in the mirror")) + parser.add_argument("--pgp-signatures", action='store_true', default=False, + help=_("Include the PGP signature .asc files in the mirror")) parser.add_argument("--src-tarballs", action='store_true', default=False, help=_("Include the source tarballs in the mirror")) parser.add_argument("--output-dir", default=None, help=_("The directory to write the mirror to")) options = parser.parse_args() + if options.all: + options.archive = True + options.build_logs = True + options.pgp_signatures = True + options.src_tarballs = True + if options.url is None: logging.error(_('A URL is required as an argument!') + '\n') parser.print_help() @@ -152,7 +162,8 @@ def main(): if not os.path.exists(f) \ or (f.endswith('.apk') and os.path.getsize(f) != package['size']): urls.append(_append_to_url_path(section, f)) - urls.append(_append_to_url_path(section, f + '.asc')) + if options.pgp_signatures: + urls.append(_append_to_url_path(section, f + '.asc')) if options.build_logs and f.endswith('.apk'): urls.append(_append_to_url_path(section, f[:-4] + '.log.gz')) From e5d847903345729af946ec50bfc41e7dfec2d7b6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 14 Jan 2020 19:10:06 +0100 Subject: [PATCH 0210/2775] only do bash completion on .yml files closes #719 --- completion/bash-completion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completion/bash-completion b/completion/bash-completion index 4a54954d..d679fbd9 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -73,7 +73,7 @@ __vercode() { line="${line#*,}" printf "${line%%,*} " fi - done < "metadata/${p}.txt" )" -- $cur ) ) + done < "metadata/${p}.yml" )" -- $cur ) ) } __complete_options() { From 0fa1f91a2337ce3e91bf7e92102237e33de49be2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 14 Jan 2020 20:04:14 +0100 Subject: [PATCH 0211/2775] gitlab-ci: long timeout and many retries for pip installs --- .gitlab-ci.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eb65036f..8afae7b0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,8 +1,12 @@ +variables: + pip: pip3 --timeout 100 --retries 10 + + test: image: registry.gitlab.com/fdroid/ci-images-server:latest script: - - pip3 install -e . + - $pip install -e . - cd tests - ./complete-ci-tests @@ -104,8 +108,8 @@ ubuntu_xenial_pip: - rm -rf env - pyvenv env - . env/bin/activate - - pip3 install --upgrade babel pip setuptools - - pip3 install -e . + - $pip install --upgrade babel pip setuptools + - $pip install -e . - ./setup.py compile_catalog - ./tests/run-tests @@ -135,7 +139,7 @@ lint_format_safety_bandit_checks: script: - apk add --no-cache bash dash ca-certificates python3 - python3 -m ensurepip - - pip3 install Babel 'bandit<1.6.0' pycodestyle pyflakes 'pylint<2.0' safety + - $pip install Babel 'bandit<1.6.0' pycodestyle pyflakes 'pylint<2.0' safety - export EXITVALUE=0 - ./hooks/pre-commit || export EXITVALUE=1 - bandit @@ -184,7 +188,7 @@ fedora_latest: which - ./setup.py compile_catalog sdist - useradd -m -c "test account" --password "fakepassword" testuser - - su testuser --login --command "cd `pwd`; pip3 install --user dist/fdroidserver-*.tar.gz" + - su testuser --login --command "cd `pwd`; $pip install --user dist/fdroidserver-*.tar.gz" - test -e ~testuser/.local/share/locale/de/LC_MESSAGES/fdroidserver.mo - wget --no-verbose -O tools.zip https://dl.google.com/android/repository/tools_r25.2.5-linux.zip - unzip -q tools.zip @@ -222,5 +226,5 @@ gradle: test -z "$CHANGED" && exit; fi - python3 -m ensurepip - - pip3 install beautifulsoup4 requests + - $pip install beautifulsoup4 requests - ./tests/gradle-release-checksums.py From e6b2134d2e98752468876dbfe24e1ac0e2b44dff Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 14 Jan 2020 22:51:19 +0100 Subject: [PATCH 0212/2775] makebuildserver: ensure vagrant share block symlinks to the host * https://phoenhex.re/2018-03-25/not-a-vagrant-bug * https://github.com/hashicorp/vagrant/pull/10792/files --- makebuildserver | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/makebuildserver b/makebuildserver index 9bf09d40..694173b9 100755 --- a/makebuildserver +++ b/makebuildserver @@ -531,6 +531,10 @@ def main(): open(logfilename, 'a').close() # create blank file log_cm = vagrant.make_file_cm(logfilename) v = vagrant.Vagrant(root=serverdir, out_cm=log_cm, err_cm=log_cm) + # https://phoenhex.re/2018-03-25/not-a-vagrant-bug + os_env = os.environ.copy() + os_env['VAGRANT_DISABLE_VBOXSYMLINKCREATE'] = '1' + v.env = os_env if options.verbosity >= 2: tail = fdroidserver.tail.Tail(logfilename) From 84c7f4db9bdb87a31df928ec37faee19774582e8 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 30 Jan 2020 13:39:48 +0100 Subject: [PATCH 0213/2775] Add Gradle 6.1.1, replacing Gradle 6.1 --- makebuildserver | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makebuildserver b/makebuildserver index 694173b9..8195983f 100755 --- a/makebuildserver +++ b/makebuildserver @@ -362,8 +362,8 @@ CACHE_FILES = [ '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d'), ('https://services.gradle.org/distributions/gradle-6.0.1-bin.zip', 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44'), - ('https://services.gradle.org/distributions/gradle-6.1-bin.zip', - 'd0c43d14e1c70a48b82442f435d06186351a2d290d72afd5b8866f15e6d7038a'), + ('https://services.gradle.org/distributions/gradle-6.1.1-bin.zip', + '9d94e6e4a28ad328072ef6e56bce79a810494ae756751fdcedffdeaf27c093b1'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 427856b5fd22d3836c67daf7db63ec7c9aad3c07 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 13 Jan 2020 22:36:45 +0100 Subject: [PATCH 0214/2775] tests: use same mirrors order in all tests This makes it so running `../fdroid update --nosign --pretty` in tests/ no longer creates a diff in the tests/*/index* files. It matches the order set in tests/run-tests. --- tests/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/config.py b/tests/config.py index 6ee05902..745fb9d6 100644 --- a/tests/config.py +++ b/tests/config.py @@ -26,8 +26,8 @@ keypass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=" keydname = "CN=sova, OU=F-Droid" mirrors = ( - 'https://foo.bar/fdroid', 'http://foobarfoobarfoobar.onion/fdroid', + 'https://foo.bar/fdroid', ) update_stats = True From 135c92f3d02728f3eab6d0b49366815d5ef462a3 Mon Sep 17 00:00:00 2001 From: licaon-kter Date: Sun, 2 Feb 2020 03:50:54 +0200 Subject: [PATCH 0215/2775] Add Microsoft Appcenter SDK to forbidden list --- fdroidserver/scanner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 94c8cf72..ad23912e 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -77,6 +77,7 @@ def scan_source(build_dir, build=metadata.Build()): r'''["']com.facebook.android['":]''', r'cloudrail', r'com.tencent.bugly', + r'com.microsoft.appcenter', ] } From 77efdac41b14909f118b4a05313711a3722ac2fc Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 5 Feb 2020 20:16:28 +0100 Subject: [PATCH 0216/2775] add Gradle 6.1.1 to gradlew-fdroid https://gitlab.com/fdroid/fdroidserver/-/merge_requests/710#note_282313001 missing from 84c7f4db9bdb87a31df928ec37faee19774582e8 [skip ci] --- gradlew-fdroid | 1 + 1 file changed, 1 insertion(+) diff --git a/gradlew-fdroid b/gradlew-fdroid index 35c53c02..286bb5d7 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -130,6 +130,7 @@ get_sha() { '6.0') echo '5a3578b9f0bb162f5e08cf119f447dfb8fa950cedebb4d2a977e912a11a74b91' ;; '6.0.1') echo 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44' ;; '6.1') echo 'd0c43d14e1c70a48b82442f435d06186351a2d290d72afd5b8866f15e6d7038a' ;; + '6.1.1') echo '9d94e6e4a28ad328072ef6e56bce79a810494ae756751fdcedffdeaf27c093b1' ;; *) exit 1 esac } From 25de42055eddd2f7d62da50e8ccda6cae5a735a4 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 5 Feb 2020 20:21:33 +0100 Subject: [PATCH 0217/2775] gradlew-fdroid: update avaiable gradle versions and min versions --- gradlew-fdroid | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 286bb5d7..1a7b90b9 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -147,11 +147,11 @@ contains() { # (key) should accept. plugin versions are actually prefixes and catch sub- # versions as well. Pairs are taken from: # https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle -d_plugin_k=(3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2) -d_plugin_v=(4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) +d_plugin_k=(3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2) +d_plugin_v=(5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} From 5fb368916fedb6bdb16df34b3db468ece6e728e0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 5 Feb 2020 20:28:48 +0100 Subject: [PATCH 0218/2775] index: fix no JAR test case that fails on example.org http://example.org/index-v1.jar now returns the HTTP header "Content-Encoding: gzip" but then the reply is plain HTML. That triggers a ContentDecodingError instead of an HTTPError, so this changes the test to success on any RequestsException. --- tests/index.TestCase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/index.TestCase b/tests/index.TestCase index 43db9433..5fb56f10 100755 --- a/tests/index.TestCase +++ b/tests/index.TestCase @@ -71,7 +71,7 @@ class IndexTest(unittest.TestCase): fdroidserver.index.download_repo_index("http://example.org") def test_download_repo_index_no_jar(self): - with self.assertRaises(requests.exceptions.HTTPError): + with self.assertRaises(requests.exceptions.RequestException): fdroidserver.index.download_repo_index("http://example.org?fingerprint=nope") @patch('requests.head') From 6b03f995bef145b4ae256cb2c94d3736a99fe603 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 14 Jan 2020 15:14:19 +0100 Subject: [PATCH 0219/2775] deploy: check if file is on androidobservatory before uploading Check if file is on androidobservatory before uploading. androidobservatory.org redirects to a GET request after the POST, and this seems to partially fail with requests. The checking code was broken. --- fdroidserver/server.py | 62 ++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index 18b30f7c..d00dd2da 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -33,6 +33,7 @@ import shutil from . import _ from . import common from . import index +from . import update from .exception import FDroidException config = None @@ -450,35 +451,48 @@ def upload_to_android_observatory(repo_section): import requests from lxml.html import fromstring + if options.verbose: + logging.getLogger("requests").setLevel(logging.INFO) + logging.getLogger("urllib3").setLevel(logging.INFO) + else: + logging.getLogger("requests").setLevel(logging.WARNING) + logging.getLogger("urllib3").setLevel(logging.WARNING) + if repo_section == 'repo': - for f in glob.glob(os.path.join(repo_section, '*.apk')): + for f in sorted(glob.glob(os.path.join(repo_section, '*.apk'))): fpath = f fname = os.path.basename(f) - logging.info('Uploading ' + fname + ' to androidobservatory.org') + r = requests.post('https://androidobservatory.org/', + data={'q': update.sha256sum(f), 'searchby': 'hash'}) + if r.status_code == 200: + # from now on XPath will be used to retrieve the message in the HTML + # androidobservatory doesn't have a nice API to talk with + # so we must scrape the page content + tree = fromstring(r.text) + + href = None + for element in tree.xpath("//html/body/div/div/table/tbody/tr/td/a"): + a = element.attrib.get('href') + if a: + m = re.match(r'^/app/[0-9A-F]{40}$', a) + if m: + href = m.group() + + page = 'https://androidobservatory.org' + message = '' + if href: + message = (_('Found {apkfilename} at {url}') + .format(apkfilename=fname, url=(page + href))) + if message: + logging.debug(message) + continue # upload the file with a post request - r = requests.post('https://androidobservatory.org/upload', files={'apk': (fname, open(fpath, 'rb'))}) - response = r.text - page = r.url - - # from now on XPath will be used to retrieve the message in the HTML - # androidobservatory doesn't have a nice API to talk with - # so we must scrape the page content - tree = fromstring(response) - alert = tree.xpath("//html/body/div[@class='container content-container']/div[@class='alert alert-info']")[0] - - message = "" - appurl = page - for el in alert: - # if the application was added successfully we retrive the url - # if the application was already uploaded we use the redirect page url - if el.attrib.get("href") is not None: - appurl = page + el.attrib["href"][1:] - message += el.text.replace(" here", "") + el.tail - else: - message += el.tail - message = message.strip() + " " + appurl - logging.info(message) + logging.info(_('Uploading {apkfilename} to androidobservatory.org') + .format(apkfilename=fname)) + r = requests.post('https://androidobservatory.org/upload', + files={'apk': (fname, open(fpath, 'rb'))}, + allow_redirects=False) def upload_to_virustotal(repo_section, virustotal_apikey): From ae86dc3d38f5da315a27aa0b9847676f8530557e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 14 Jan 2020 23:14:45 +0100 Subject: [PATCH 0220/2775] buildserver: set quiet options to stop apt-get spamming build logs https://gitlab.com/fdroid/fdroidserver/issues/636#note_266483988 --- buildserver/provision-apt-get-install | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index a99b6871..0d0cac60 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -5,7 +5,7 @@ set -e set -x debian_mirror=$1 -export DEBIAN_FRONTEND=noninteractive +export DEBIAN_FRONTEND=noninteractive printf 'APT::Install-Recommends "0";\nAPT::Install-Suggests "0";\n' \ > /etc/apt/apt.conf.d/99no-install-recommends @@ -22,6 +22,11 @@ EOF printf 'APT::Get::Assume-Yes "true";\n' \ > /etc/apt/apt.conf.d/99assumeyes +cat < /etc/apt/apt.conf.d/99quiet +Dpkg::Use-Pty "0";' +quiet "1";' +EOF + if echo $debian_mirror | grep '^https' 2>&1 > /dev/null; then apt-get update || apt-get update apt-get install apt-transport-https ca-certificates From 7a1fa6e857801f3315ad7bc1bd820acf3b4bec42 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 14 Jan 2020 23:20:48 +0100 Subject: [PATCH 0221/2775] build: keep DEBIAN_FRONTEND env var when running sudo: script closes #636 --- fdroidserver/build.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index a4a1f553..bcc4f545 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -371,7 +371,8 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext if build.sudo: logging.info("Running 'sudo' commands in %s" % os.getcwd()) - p = FDroidPopen(['sudo', 'bash', '-x', '-c', build.sudo]) + p = FDroidPopen(['sudo', '--preserve-env=DEBIAN_FRONTEND', + 'bash', '-x', '-c', build.sudo]) if p.returncode != 0: raise BuildException("Error running sudo command for %s:%s" % (app.id, build.versionName), p.output) From a746917022cc7412ac8f922cbab64d1bf6b5f2d5 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 14 Jan 2020 23:27:40 +0100 Subject: [PATCH 0222/2775] provision-gradle: disable daemon and block HTTP repos closes #624 #712 --- buildserver/provision-gradle | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/buildserver/provision-gradle b/buildserver/provision-gradle index d0eaf8ea..6ec35f0b 100644 --- a/buildserver/provision-gradle +++ b/buildserver/provision-gradle @@ -26,3 +26,17 @@ ln -fs /home/vagrant/fdroidserver/gradlew-fdroid /opt/gradle/bin/gradle chown -h vagrant.vagrant /opt/gradle/bin/gradle chown vagrant.vagrant /opt/gradle/versions chmod 0755 /opt/gradle/versions + +GRADLE_HOME=/home/vagrant/.gradle +test -d $GRADLE_HOME/ || mkdir $GRADLE_HOME/ +cat < $GRADLE_HOME/gradle.properties +# builds are not reused, so the daemon is a waste of time +org.gradle.daemon=false + +# fake info to block HTTP repos +systemProp.http.nonProxyHosts= +systemProp.http.proxyHost=127.127.127.127 +systemProp.http.proxyPort=12345 +EOF +chown -R vagrant.vagrant $GRADLE_HOME/ +chmod -R a+rX $GRADLE_HOME/ From bfe8f05de6bdb83d7e69c1c9821db62ff0f2d96d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 11 Feb 2020 12:48:34 +0100 Subject: [PATCH 0223/2775] fix syntax error from ae86dc3d38f5da315a27aa0b9847676f8530557e fdroid/fdroidserver!713 [skip ci] --- buildserver/provision-apt-get-install | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index 0d0cac60..df318bbc 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -23,8 +23,8 @@ printf 'APT::Get::Assume-Yes "true";\n' \ > /etc/apt/apt.conf.d/99assumeyes cat < /etc/apt/apt.conf.d/99quiet -Dpkg::Use-Pty "0";' -quiet "1";' +Dpkg::Use-Pty "0"; +quiet "1"; EOF if echo $debian_mirror | grep '^https' 2>&1 > /dev/null; then From 5a6422f4f33102aa26c66c3c10839afce31d40d5 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 11 Feb 2020 14:56:15 +0100 Subject: [PATCH 0224/2775] jenkins-setup-build-environment: require 9GB RAM for 8GB VM [skip ci] since this isn't used in gitlab-ci at all --- jenkins-setup-build-environment | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index 36c0a2aa..8c483a90 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -56,7 +56,7 @@ mkdir $VAGRANT_HOME rm -rf "$WORKSPACE"/../*/.testfiles memtotal=$(grep ^MemTotal: /proc/meminfo | awk '{print $2}') -if [ $memtotal -gt 8092876 ]; then +if [ $memtotal -gt 9437184 ]; then memory=8192 else memory=$(((memtotal / 1024) - 1024)) From 697a0641f19a8a1097b7301bf694e594892d08f8 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 11 Feb 2020 19:44:06 +0100 Subject: [PATCH 0225/2775] fix sudo syntax from 7a1fa6e857801f3315ad7bc1bd820acf3b4bec42 fdroid/fdroidserver!713 --- fdroidserver/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index bcc4f545..a03fb2f3 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -371,7 +371,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext if build.sudo: logging.info("Running 'sudo' commands in %s" % os.getcwd()) - p = FDroidPopen(['sudo', '--preserve-env=DEBIAN_FRONTEND', + p = FDroidPopen(['sudo', 'DEBIAN_FRONTEND=noninteractive', 'bash', '-x', '-c', build.sudo]) if p.returncode != 0: raise BuildException("Error running sudo command for %s:%s" % From bfe587979de7881592c84f8141ef4678539e4591 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 31 Jan 2020 23:49:50 +0100 Subject: [PATCH 0226/2775] import: make it work most of the time with git repos This includes real tests too. --- fdroidserver/import.py | 89 +++---- tests/common.TestCase | 24 ++ tests/import.TestCase | 70 +++++- tests/import_proxy.py | 2 + tests/scanner.TestCase | 1 + .../avenginekit/build.gradle | 2 + .../cn.wildfirechat.chat/build.gradle | 41 ++++ .../cn.wildfirechat.chat/chat/build.gradle | 115 +++++++++ .../cn.wildfirechat.chat/client/build.gradle | 57 +++++ .../client/src/main/AndroidManifest.xml | 26 ++ .../emojilibrary/build.gradle | 34 +++ .../gradle/build_libraries.gradle | 42 ++++ .../imagepicker/build.gradle | 30 +++ .../mars-core-release/build.gradle | 2 + .../cn.wildfirechat.chat/push/build.gradle | 55 +++++ .../cn.wildfirechat.chat/settings.gradle | 7 + .../com.anpmech.launcher/app/build.gradle | 76 ++++++ .../app/src/main/AndroidManifest.xml | 66 +++++ .../com.anpmech.launcher/build.gradle | 45 ++++ .../com.anpmech.launcher/settings.gradle | 16 ++ .../org.tasks/app/build.gradle.kts | 225 ++++++++++++++++++ tests/source-files/org.tasks/build.gradle | 13 + tests/source-files/org.tasks/build.gradle.kts | 26 ++ .../org.tasks/buildSrc/build.gradle.kts | 7 + .../org.tasks/settings.gradle.kts | 1 + .../app/src/main/AndroidManifest.xml | 124 ++++++++++ .../ut.ewh.audiometrytest/build.gradle | 29 +++ .../ut.ewh.audiometrytest/settings.gradle | 1 + 28 files changed, 1184 insertions(+), 42 deletions(-) create mode 100644 tests/source-files/cn.wildfirechat.chat/avenginekit/build.gradle create mode 100644 tests/source-files/cn.wildfirechat.chat/build.gradle create mode 100644 tests/source-files/cn.wildfirechat.chat/chat/build.gradle create mode 100644 tests/source-files/cn.wildfirechat.chat/client/build.gradle create mode 100644 tests/source-files/cn.wildfirechat.chat/client/src/main/AndroidManifest.xml create mode 100755 tests/source-files/cn.wildfirechat.chat/emojilibrary/build.gradle create mode 100644 tests/source-files/cn.wildfirechat.chat/gradle/build_libraries.gradle create mode 100755 tests/source-files/cn.wildfirechat.chat/imagepicker/build.gradle create mode 100644 tests/source-files/cn.wildfirechat.chat/mars-core-release/build.gradle create mode 100644 tests/source-files/cn.wildfirechat.chat/push/build.gradle create mode 100644 tests/source-files/cn.wildfirechat.chat/settings.gradle create mode 100644 tests/source-files/com.anpmech.launcher/app/build.gradle create mode 100644 tests/source-files/com.anpmech.launcher/app/src/main/AndroidManifest.xml create mode 100644 tests/source-files/com.anpmech.launcher/build.gradle create mode 100644 tests/source-files/com.anpmech.launcher/settings.gradle create mode 100644 tests/source-files/org.tasks/app/build.gradle.kts create mode 100644 tests/source-files/org.tasks/build.gradle create mode 100644 tests/source-files/org.tasks/build.gradle.kts create mode 100644 tests/source-files/org.tasks/buildSrc/build.gradle.kts create mode 100644 tests/source-files/org.tasks/settings.gradle.kts create mode 100644 tests/source-files/ut.ewh.audiometrytest/app/src/main/AndroidManifest.xml create mode 100644 tests/source-files/ut.ewh.audiometrytest/build.gradle create mode 100644 tests/source-files/ut.ewh.audiometrytest/settings.gradle diff --git a/fdroidserver/import.py b/fdroidserver/import.py index b463824c..5d0ebfcd 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -18,12 +18,12 @@ # along with this program. If not, see . import binascii +import glob import os import re import shutil import urllib.request from argparse import ArgumentParser -from configparser import ConfigParser import logging from . import _ @@ -31,8 +31,9 @@ from . import common from . import metadata from .exception import FDroidException - -SETTINGS_GRADLE = re.compile(r'''include\s+['"]:([^'"]*)['"]''') +SETTINGS_GRADLE = re.compile(r'settings\.gradle(?:\.kts)?') +GRADLE_SUBPROJECT = re.compile(r'''['"]:([^'"]+)['"]''') +ANDROID_PLUGIN = re.compile(r'''\s*(:?apply plugin:|id)\(?\s*['"](android|com\.android\.application)['"]\s*\)?''') # Get the repo type and address from the given web page. The page is scanned @@ -168,32 +169,47 @@ def get_metadata_from_url(app, url): shutil.rmtree(build_dir) vcs = common.getvcs(repotype, repo, build_dir) vcs.gotorevision(options.rev) - root_dir = get_subdir(build_dir) app.RepoType = repotype app.Repo = repo - return root_dir, build_dir - - -config = None -options = None - - -def get_subdir(build_dir): - if options.subdir: - return os.path.join(build_dir, options.subdir) - - settings_gradle = os.path.join(build_dir, 'settings.gradle') - if os.path.exists(settings_gradle): - with open(settings_gradle) as fp: - m = SETTINGS_GRADLE.search(fp.read()) - if m: - return os.path.join(build_dir, m.group(1)) - return build_dir +def get_all_gradle_and_manifests(build_dir): + paths = [] + for root, dirs, files in os.walk(build_dir): + for f in sorted(files): + if f == 'AndroidManifest.xml' \ + or f.endswith('.gradle') or f.endswith('.gradle.kts'): + full = os.path.join(root, f) + paths.append(full) + return paths + + +def get_gradle_subdir(build_dir, paths): + """get the subdir where the gradle build is based""" + first_gradle_dir = None + for path in paths: + if not first_gradle_dir: + first_gradle_dir = os.path.relpath(os.path.dirname(path), build_dir) + if os.path.exists(path) and SETTINGS_GRADLE.match(os.path.basename(path)): + with open(path) as fp: + for m in GRADLE_SUBPROJECT.finditer(fp.read()): + for f in glob.glob(os.path.join(os.path.dirname(path), m.group(1), 'build.gradle*')): + with open(f) as fp: + while True: + line = fp.readline() + if not line: + break + if ANDROID_PLUGIN.match(line): + return os.path.relpath(os.path.dirname(f), build_dir) + if first_gradle_dir and first_gradle_dir != '.': + return first_gradle_dir + + return '' + + def main(): global config, options @@ -221,7 +237,6 @@ def main(): app = metadata.App() app.UpdateCheckMode = "Tags" - root_dir = None build_dir = None local_metadata_files = common.get_local_metadata_files() @@ -233,12 +248,11 @@ def main(): app.AutoName = os.path.basename(os.getcwd()) app.RepoType = 'git' - root_dir = get_subdir(os.getcwd()) if os.path.exists('build.gradle'): build.gradle = ['yes'] import git - repo = git.repo.Repo(root_dir) # git repo + repo = git.repo.Repo(os.getcwd()) # git repo for remote in git.Remote.iter_items(repo): if remote.name == 'origin': url = repo.remotes.origin.url @@ -250,7 +264,7 @@ def main(): build.commit = binascii.hexlify(bytearray(repo.head.commit.binsha)) write_local_file = True elif options.url: - root_dir, build_dir = get_metadata_from_url(app, options.url) + build_dir = get_metadata_from_url(app, options.url) build.commit = '?' build.disable = 'Generated by import.py - check/set version fields and commit id' write_local_file = False @@ -258,9 +272,9 @@ def main(): raise FDroidException("Specify project url.") # Extract some information... - paths = common.manifest_paths(root_dir, []) + paths = get_all_gradle_and_manifests(build_dir) + subdir = get_gradle_subdir(build_dir, paths) if paths: - versionName, versionCode, package = common.parse_androidmanifests(paths, app) if not package: raise FDroidException(_("Couldn't find package ID")) @@ -269,17 +283,7 @@ def main(): if not versionCode: logging.warn(_("Couldn't find latest version code")) else: - spec = os.path.join(root_dir, 'buildozer.spec') - if os.path.exists(spec): - defaults = {'orientation': 'landscape', 'icon': '', - 'permissions': '', 'android.api': "18"} - bconfig = ConfigParser(defaults, allow_no_value=True) - bconfig.read(spec) - package = bconfig.get('app', 'package.domain') + '.' + bconfig.get('app', 'package.name') - versionName = bconfig.get('app', 'version') - versionCode = None - else: - raise FDroidException(_("No android or kivy project could be found. Specify --subdir?")) + raise FDroidException(_("No gradle project could be found. Specify --subdir?")) # Make sure it's actually new... if package in apps: @@ -290,13 +294,16 @@ def main(): build.versionCode = versionCode or '0' # TODO heinous but this is still a str if options.subdir: build.subdir = options.subdir + elif subdir: + build.subdir = subdir + if options.license: app.License = options.license if options.categories: app.Categories = options.categories.split(',') - if os.path.exists(os.path.join(root_dir, 'jni')): + if os.path.exists(os.path.join(subdir, 'jni')): build.buildjni = ['yes'] - if os.path.exists(os.path.join(root_dir, 'build.gradle')): + if os.path.exists(os.path.join(subdir, 'build.gradle')): build.gradle = ['yes'] metadata.post_metadata_parse(app) diff --git a/tests/common.TestCase b/tests/common.TestCase index 3d90707a..bb4d78a6 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -816,6 +816,30 @@ class CommonTest(unittest.TestCase): self.assertEqual(('0.94-test', '940', 'org.fdroid.fdroid'), fdroidserver.common.parse_androidmanifests(paths, app)) + app = fdroidserver.metadata.App() + app.AutoName = 'android-chat' + app.RepoType = 'git' + url = 'https://github.com/wildfirechat/android-chat.git' + app.SourceCode = url.rstrip('.git') + app.Repo = url + paths = [ + os.path.join('source-files', 'cn.wildfirechat.chat', 'avenginekit', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'src', 'main', 'AndroidManifest.xml'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'emojilibrary', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'gradle', 'build_libraries.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'imagepicker', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'mars-core-release', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'push', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'settings.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'chat', 'build.gradle'), + ] + for path in paths: + self.assertTrue(os.path.isfile(path)) + self.assertEqual(('0.6.9', '23', 'cn.wildfirechat.chat'), + fdroidserver.common.parse_androidmanifests(paths, app)) + def test_parse_androidmanifests_ignore(self): app = fdroidserver.metadata.App() app.id = 'org.fdroid.fdroid' diff --git a/tests/import.TestCase b/tests/import.TestCase index 18852628..4a8936ac 100755 --- a/tests/import.TestCase +++ b/tests/import.TestCase @@ -7,8 +7,11 @@ import logging import optparse import os import requests +import shutil import sys +import tempfile import unittest +from unittest import mock localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) @@ -48,11 +51,76 @@ class ImportTest(unittest.TestCase): app = fdroidserver.metadata.App() app.UpdateCheckMode = "Tags" - root_dir, src_dir = import_proxy.get_metadata_from_url(app, url) + build_dir = import_proxy.get_metadata_from_url(app, url) self.assertEqual(app.RepoType, 'git') self.assertEqual(app.WebSite, 'https://gitlab.com/fdroid/ci-test-app') self.assertEqual(app.Repo, 'https://gitlab.com/fdroid/ci-test-app.git') + def test_get_all_gradle_and_manifests(self): + a = import_proxy.get_all_gradle_and_manifests(os.path.join('source-files', 'cn.wildfirechat.chat')) + paths = [ + os.path.join('source-files', 'cn.wildfirechat.chat', 'avenginekit', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'chat', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'src', 'main', 'AndroidManifest.xml'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'emojilibrary', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'gradle', 'build_libraries.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'imagepicker', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'mars-core-release', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'push', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'settings.gradle'), + ] + self.assertEqual(sorted(paths), sorted(a)) + + def test_get_gradle_subdir(self): + subdirs = { + 'cn.wildfirechat.chat': 'chat', + 'com.anpmech.launcher': 'app', + 'org.tasks': 'app', + 'ut.ewh.audiometrytest': 'app', + } + for f in ('cn.wildfirechat.chat', 'com.anpmech.launcher', 'org.tasks', 'ut.ewh.audiometrytest'): + build_dir = os.path.join('source-files', f) + paths = import_proxy.get_all_gradle_and_manifests(build_dir) + logging.info(paths) + subdir = import_proxy.get_gradle_subdir(build_dir, paths) + self.assertEqual(subdirs[f], subdir) + + def test_get_metadata_from_url(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + os.mkdir(os.path.join(testdir, 'tmp')) + tmp_importer = os.path.join(testdir, 'tmp', 'importer') + data = ( + ('cn.wildfirechat.chat', 'https://github.com/wildfirechat/android-chat', '0.6.9', '23'), + ('com.anpmech.launcher', 'https://github.com/KeikaiLauncher/KeikaiLauncher', 'Unknown', None), + ('ut.ewh.audiometrytest', 'https://github.com/ReeceStevens/ut_ewh_audiometer_2014', '1.65', '14'), + ) + for appid, url, vn, vc in data: + shutil.rmtree(tmp_importer, ignore_errors=True) + shutil.copytree(os.path.join(self.basedir, 'source-files', appid), + tmp_importer) + + app = fdroidserver.metadata.App() + app.UpdateCheckMode = "Tags" + with mock.patch('fdroidserver.common.getvcs', + lambda a, b, c: fdroidserver.common.vcs(url, testdir)): + with mock.patch('fdroidserver.common.vcs.gotorevision', + lambda s, rev: None): + with mock.patch('shutil.rmtree', lambda a: None): + build_dir = import_proxy.get_metadata_from_url(app, url) + self.assertEqual('git', app.RepoType) + self.assertEqual(url, app.Repo) + self.assertEqual(url, app.SourceCode) + logging.info(build_dir) + paths = import_proxy.get_all_gradle_and_manifests(build_dir) + self.assertNotEqual(paths, []) + versionName, versionCode, package = fdroidserver.common.parse_androidmanifests(paths, app) + self.assertEqual(vn, versionName) + self.assertEqual(vc, versionCode) + self.assertEqual(appid, package) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) diff --git a/tests/import_proxy.py b/tests/import_proxy.py index ce24a50f..f3c4fef8 100644 --- a/tests/import_proxy.py +++ b/tests/import_proxy.py @@ -18,7 +18,9 @@ class Options: module = __import__('fdroidserver.import') for name, obj in inspect.getmembers(module): if name == 'import': + get_all_gradle_and_manifests = obj.get_all_gradle_and_manifests get_metadata_from_url = obj.get_metadata_from_url + get_gradle_subdir = obj.get_gradle_subdir obj.options = Options() options = obj.options break diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 6e94d5fb..b8f46af9 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -28,6 +28,7 @@ class ScannerTest(unittest.TestCase): def test_scan_source_files(self): source_files = os.path.join(self.basedir, 'source-files') projects = { + 'cn.wildfirechat.chat': 4, 'Zillode': 1, 'firebase-suspect': 1, 'org.mozilla.rocket': 3, diff --git a/tests/source-files/cn.wildfirechat.chat/avenginekit/build.gradle b/tests/source-files/cn.wildfirechat.chat/avenginekit/build.gradle new file mode 100644 index 00000000..02955512 --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/avenginekit/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('avenginekit.aar')) \ No newline at end of file diff --git a/tests/source-files/cn.wildfirechat.chat/build.gradle b/tests/source-files/cn.wildfirechat.chat/build.gradle new file mode 100644 index 00000000..acc41375 --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/build.gradle @@ -0,0 +1,41 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + google() + jcenter() + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.4.2' + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + maven { + url "http://developer.huawei.com/repo/" + } + + maven { url 'https://jitpack.io' } + maven { url 'https://dl.bintray.com/jenly/maven' } + } + configurations { + all { + resolutionStrategy { + //force "android.arch.lifecycle:runtime:1.1.1" + } + } + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/tests/source-files/cn.wildfirechat.chat/chat/build.gradle b/tests/source-files/cn.wildfirechat.chat/chat/build.gradle new file mode 100644 index 00000000..f2503356 --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/chat/build.gradle @@ -0,0 +1,115 @@ +apply plugin: 'com.android.application' + +android { + signingConfigs { + wfc { + keyAlias 'wfc' + keyPassword 'wildfirechat' + storeFile file('../wfc.keystore') + storePassword 'wildfirechat' + } + } + compileSdkVersion 28 + aaptOptions.cruncherEnabled = false + aaptOptions.useNewCruncher = false + defaultConfig { + applicationId "cn.wildfirechat.chat" + minSdkVersion 16 + targetSdkVersion 28 //当targetversion大于23时,需要使用fileprovider + versionCode 23 + versionName "0.6.9" + multiDexEnabled true + javaCompileOptions { + annotationProcessorOptions { + includeCompileClasspath true + } + } + signingConfig signingConfigs.wfc + +// buildConfigField("String", "BuglyId", '"34490ba79f"') + + ndk { + abiFilters "armeabi-v7a", 'x86', 'x86_64' // ,'armeabi', 'arm64-v8a', 'x86', 'x86_64' + } + } + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.wfc + } + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.wfc + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + lintOptions { + abortOnError false + } + sourceSets { + main { + // wfc kit start + jniLibs.srcDirs += ['libs', 'kit/libs'] + res.srcDirs += ['kit/src/main/res', 'kit/src/main/res-av'] + assets.srcDirs += ['kit/src/main/assets'] + java.srcDirs += ['kit/src/main/java'] + // wfc kit end + } + } + productFlavors { + } + + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation files('libs/TencentLocationSDK_v4.9.7.12_r247861_161205_1104.jar') + implementation files('libs/TencentMapSDK_Raster_v_1.2.7_51ae0e7.jar') + implementation files('libs/TencentSearch1.1.3.jar') + + implementation 'com.tencent.bugly:crashreport:2.8.6.0' + implementation 'com.tencent.bugly:nativecrashreport:3.6.0.1' + implementation 'com.lqr.adapter:library:1.0.2' + implementation 'com.jaeger.statusbaruitl:library:1.3.5' + implementation project(':push') + + // wfc kit start + implementation fileTree(include: ['*.jar'], dir: 'kit/libs') + implementation 'androidx.appcompat:appcompat:1.1.0-beta01' + implementation 'com.google.android.material:material:1.1.0-alpha10' + implementation 'cjt.library.wheel:camera:1.1.9' + implementation 'com.kyleduo.switchbutton:library:1.4.4' + implementation 'com.squareup.okhttp3:okhttp:3.11.0' + implementation 'com.squareup.okio:okio:1.14.0' + implementation 'com.jakewharton:butterknife:10.2.0' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0' + implementation 'com.github.bumptech.glide:glide:4.8.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0' + implementation 'com.github.chrisbanes:PhotoView:2.3.0' + implementation 'org.webrtc:google-webrtc:1.0.21929' + implementation 'com.afollestad.material-dialogs:core:0.9.6.0' + implementation 'q.rorbin:badgeview:1.1.3' + implementation 'com.google.code.gson:gson:2.8.5' + + // ViewModel and LiveData + def lifecycle_version = '2.2.0-alpha05' + implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" + + implementation project(':client') + implementation project(':avenginekit') + implementation project(':emojilibrary') + implementation project(':imagepicker') + + implementation 'com.king.zxing:zxing-lite:1.1.1' + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' + // kit wfc end +} diff --git a/tests/source-files/cn.wildfirechat.chat/client/build.gradle b/tests/source-files/cn.wildfirechat.chat/client/build.gradle new file mode 100644 index 00000000..ce41d062 --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/client/build.gradle @@ -0,0 +1,57 @@ +apply plugin: 'com.android.library' +apply plugin: 'com.github.dcendents.android-maven' + +group = 'com.github.wildfirechat' + +android { + compileSdkVersion 28 + + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + // testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + ndk { + // TODO: changes this for your application if needed + moduleName = "mmnet" + //abiFilter "armeabi" //去掉armeabi架构,armeabi-v7a可以兼容armeabi架构。 + abiFilter "armeabi-v7a" + abiFilter "arm64-v8a" + abiFilter "x86" + abiFilter "x86_64" + } + } + + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + + sourceSets { + main { + jniLibs.srcDirs = ['libs'] + } + } + + lintOptions { + abortOnError false + } + compileOptions { + targetCompatibility 1.8 + sourceCompatibility 1.8 + } +} + + +dependencies { + api project(':mars-core-release') + def lifecycle_version = '2.0.0-beta01' + implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" +} diff --git a/tests/source-files/cn.wildfirechat.chat/client/src/main/AndroidManifest.xml b/tests/source-files/cn.wildfirechat.chat/client/src/main/AndroidManifest.xml new file mode 100644 index 00000000..0c056938 --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/client/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/source-files/cn.wildfirechat.chat/emojilibrary/build.gradle b/tests/source-files/cn.wildfirechat.chat/emojilibrary/build.gradle new file mode 100755 index 00000000..50ea5f5a --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/emojilibrary/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + android { + lintOptions { + abortOnError false + } + } + +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'androidx.appcompat:appcompat:1.0.0-beta01' +} \ No newline at end of file diff --git a/tests/source-files/cn.wildfirechat.chat/gradle/build_libraries.gradle b/tests/source-files/cn.wildfirechat.chat/gradle/build_libraries.gradle new file mode 100644 index 00000000..42020666 --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/gradle/build_libraries.gradle @@ -0,0 +1,42 @@ +def checkExecResult(execResult) { + if (execResult) { + if (execResult.getExitValue() != 0) { + throw new GradleException('Non-zero exit value: ' + execResult.getExitValue()) + } + + } else { + throw new GradleException('Returned a null execResult object') + } +} + +task buildLibrariesForAndroid(type: Exec) { + workingDir '../' + + def sdkDir = System.env.ANDROID_HOME + def ndkDir = System.env.ANDROID_NDK_HOME + + if (rootProject.file("local.properties").exists()) { + Properties properties = new Properties() + properties.load(project.rootProject.file('local.properties').newDataInputStream()) + sdkDir = properties.getProperty('sdk.dir') + ndkDir = properties.getProperty('ndk.dir') + } + + def path = System.env.PATH + + def envMap = [ + 'ANDROID_HOME' : sdkDir, + 'ANDROID_NDK_HOME': ndkDir, + '_ARCH_' : 'armeabi', + 'PATH' : ndkDir, + ] + environment envMap + + print envMap + + commandLine 'python', 'build_android.py', '2', 'armeabi' + + doLast { + checkExecResult(execResult) + } +} diff --git a/tests/source-files/cn.wildfirechat.chat/imagepicker/build.gradle b/tests/source-files/cn.wildfirechat.chat/imagepicker/build.gradle new file mode 100755 index 00000000..66b153a1 --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/imagepicker/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + lintOptions { + abortOnError false + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.0.0-beta01' + implementation 'com.github.chrisbanes.photoview:library:1.2.4' + implementation 'com.github.bumptech.glide:glide:4.8.0' +} diff --git a/tests/source-files/cn.wildfirechat.chat/mars-core-release/build.gradle b/tests/source-files/cn.wildfirechat.chat/mars-core-release/build.gradle new file mode 100644 index 00000000..65e8c7fe --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/mars-core-release/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('mars-core-release.aar')) \ No newline at end of file diff --git a/tests/source-files/cn.wildfirechat.chat/push/build.gradle b/tests/source-files/cn.wildfirechat.chat/push/build.gradle new file mode 100644 index 00000000..26f5cbe2 --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/push/build.gradle @@ -0,0 +1,55 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + manifestPlaceholders = [ + + MI_APP_ID : "2882303761517722456", + MI_APP_KEY : "5731772292456", + + HMS_APP_ID : "100221325", + + MEIZU_APP_ID : "113616", + MEIZU_APP_KEY: "fcd886f51c144b45b87a67a28e2934d1", + + VIVO_APP_ID : "12918", + VIVO_APP_KEY : "c42feb05-de6c-427d-af55-4f902d9e0a75" + ] + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'com.huawei.android.hms:push:2.5.3.305' + implementation 'com.huawei.android.hms:base:2.5.3.305' + + implementation 'androidx.appcompat:appcompat:1.0.0-beta01' + implementation project(':client') + implementation 'com.meizu.flyme.internet:push-internal:3.4.2@aar' + + def lifecycle_version = '2.2.0-alpha05' + implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" +} diff --git a/tests/source-files/cn.wildfirechat.chat/settings.gradle b/tests/source-files/cn.wildfirechat.chat/settings.gradle new file mode 100644 index 00000000..e98e916c --- /dev/null +++ b/tests/source-files/cn.wildfirechat.chat/settings.gradle @@ -0,0 +1,7 @@ +include ':client', + ':push', + ':chat', + ':mars-core-release', + ':emojilibrary', + ':imagepicker', + ':avenginekit' diff --git a/tests/source-files/com.anpmech.launcher/app/build.gradle b/tests/source-files/com.anpmech.launcher/app/build.gradle new file mode 100644 index 00000000..97d2e4fc --- /dev/null +++ b/tests/source-files/com.anpmech.launcher/app/build.gradle @@ -0,0 +1,76 @@ +/* + * Copyright 2015-2017 Hayai Software + * Copyright 2018 The KeikaiLauncher Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +plugins { + id 'com.android.application' + id 'pl.allegro.tech.build.axion-release' version '1.8.1' +} + +scmVersion { + tag { + prefix = '' + } +} + +/** + * Takes version {@code major.minor.patch[-suffix]} and returns numeric versionCode based on it + * Example: {@code 1.2.3-SNAPSHOT} will return {@code 1002003} + */ +static int versionCode(String versionName) { + def matcher = (versionName =~ /(\d+)\.(\d+)\.(\d+).*/) + return matcher.matches() ? + matcher.collect { version, major, minor, patch -> + major.toInteger() * 10000 + minor.toInteger() * 100 + patch.toInteger() + }.head() : + -1 +} + +def androidVersion = [ + name: scmVersion.version, + code: versionCode(scmVersion.version), +] + +android { + compileSdkVersion 28 + defaultConfig { + applicationId 'com.anpmech.launcher' + minSdkVersion 15 + targetSdkVersion 28 + versionName androidVersion.name + versionCode androidVersion.code + } + lintOptions { + abortOnError false + } + buildTypes { + all { + buildConfigField("String", "GITHUB_USER", "\"KeikaiLauncher\"") + buildConfigField("String", "GITHUB_PROJECT", "\"KeikaiLauncher\"") + } + release { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt' + } + debug { + versionNameSuffix "-debug" + } + } + dependencies { + implementation 'com.android.support:support-annotations:28.0.0' + } +} + +dependencies { +} diff --git a/tests/source-files/com.anpmech.launcher/app/src/main/AndroidManifest.xml b/tests/source-files/com.anpmech.launcher/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..77c4e22f --- /dev/null +++ b/tests/source-files/com.anpmech.launcher/app/src/main/AndroidManifest.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/source-files/com.anpmech.launcher/build.gradle b/tests/source-files/com.anpmech.launcher/build.gradle new file mode 100644 index 00000000..a92bf663 --- /dev/null +++ b/tests/source-files/com.anpmech.launcher/build.gradle @@ -0,0 +1,45 @@ +/* + * Copyright 2015-2017 Hayai Software + * Copyright 2018 The KeikaiLauncher Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + jcenter() + google() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + jcenter() + google() + } +} + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'org.owasp:dependency-check-gradle:5.2.4' + } +} +apply plugin: 'org.owasp.dependencycheck' +dependencyCheck { + format='JSON' +} diff --git a/tests/source-files/com.anpmech.launcher/settings.gradle b/tests/source-files/com.anpmech.launcher/settings.gradle new file mode 100644 index 00000000..4d775aa7 --- /dev/null +++ b/tests/source-files/com.anpmech.launcher/settings.gradle @@ -0,0 +1,16 @@ +/* + * Copyright 2015-2017 Hayai Software + * Copyright 2018 The KeikaiLauncher Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +include ':app' diff --git a/tests/source-files/org.tasks/app/build.gradle.kts b/tests/source-files/org.tasks/app/build.gradle.kts new file mode 100644 index 00000000..23b0524d --- /dev/null +++ b/tests/source-files/org.tasks/app/build.gradle.kts @@ -0,0 +1,225 @@ +import com.android.build.gradle.api.ApplicationVariant + +plugins { + id("com.android.application") + id("checkstyle") + id("io.fabric") + id("com.cookpad.android.licensetools") + kotlin("android") +} + +repositories { + jcenter() + google() + maven(url = "https://jitpack.io") +} + +android { + bundle { + language { + enableSplit = false + } + } + + dexOptions { + javaMaxHeapSize = "2g" + } + + lintOptions { + setLintConfig(file("lint.xml")) + textOutput("stdout") + textReport = true + } + + compileSdkVersion(Versions.targetSdk) + + defaultConfig { + testApplicationId = "org.tasks.test" + applicationId = "org.tasks" + versionCode = 651 + versionName = "7.6.1" + targetSdkVersion(Versions.targetSdk) + minSdkVersion(Versions.minSdk) + multiDexEnabled = true + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + javaCompileOptions { + annotationProcessorOptions { + arguments["room.schemaLocation"] = "$projectDir/schemas" + } + } + } + + signingConfigs { + create("release") { + val tasksKeyAlias: String? by project + val tasksStoreFile: String? by project + val tasksStorePassword: String? by project + val tasksKeyPassword: String? by project + + keyAlias = tasksKeyAlias + storeFile = file(tasksStoreFile?: "none") + storePassword = tasksStorePassword + keyPassword = tasksKeyPassword + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + @Suppress("LocalVariableName") + buildTypes { + getByName("debug") { + val tasks_mapbox_key_debug: String? by project + val tasks_google_key_debug: String? by project + + applicationIdSuffix = ".debug" + resValue("string", "mapbox_key", tasks_mapbox_key_debug ?: "") + resValue("string", "google_key", tasks_google_key_debug ?: "") + isTestCoverageEnabled = true + } + getByName("release") { + val tasks_mapbox_key: String? by project + val tasks_google_key: String? by project + + resValue("string", "mapbox_key", tasks_mapbox_key ?: "") + resValue("string", "google_key", tasks_google_key ?: "") + isMinifyEnabled = true + proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard.pro") + signingConfig = signingConfigs.getByName("release") + } + } + + applicationVariants.all(object : Action { + override fun execute(variant: ApplicationVariant) { + variant.resValue("string", "app_package", variant.applicationId) + } + }) + + flavorDimensions("store") + + productFlavors { + create("generic") { + setDimension("store") + proguardFile("generic.pro") + } + create("googleplay") { + setDimension("store") + } + create("amazon") { + setDimension("store") + } + } + + viewBinding { + isEnabled = true + } + + dataBinding { + isEnabled = true + } + + packagingOptions { + exclude("META-INF/*.kotlin_module") + } +} + +configure { + configFile = project.file("google_checks.xml") + toolVersion = "8.16" +} + +configurations.all { + exclude(group = "com.google.guava", module = "guava-jdk5") + exclude(group = "org.apache.httpcomponents", module = "httpclient") + exclude(group = "com.google.http-client", module = "google-http-client-apache") + resolutionStrategy { + force("com.squareup.okhttp3:okhttp:" + Versions.okhttp) + } +} + +val googleplayImplementation by configurations +val amazonImplementation by configurations + +dependencies { + implementation("com.gitlab.bitfireAT:dav4jvm:1.0") + implementation("com.gitlab.bitfireAT:ical4android:be6d515db8") { + exclude(group = "org.threeten", module = "threetenbp") + } + implementation("com.gitlab.bitfireAT:cert4android:1488e39a66") + + annotationProcessor("com.google.dagger:dagger-compiler:${Versions.dagger}") + implementation("com.google.dagger:dagger:${Versions.dagger}") + + implementation("androidx.room:room-rxjava2:${Versions.room}") + annotationProcessor("androidx.room:room-compiler:${Versions.room}") + implementation("androidx.lifecycle:lifecycle-extensions:2.1.0") + implementation("io.reactivex.rxjava2:rxandroid:2.1.1") + implementation("androidx.paging:paging-runtime:2.1.1") + + annotationProcessor("com.jakewharton:butterknife-compiler:${Versions.butterknife}") + implementation("com.jakewharton:butterknife:${Versions.butterknife}") + + debugImplementation("com.facebook.flipper:flipper:${Versions.flipper}") + debugImplementation("com.facebook.flipper:flipper-network-plugin:${Versions.flipper}") + debugImplementation("com.facebook.soloader:soloader:0.8.0") + + debugImplementation("com.squareup.leakcanary:leakcanary-android:${Versions.leakcanary}") + + implementation("org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}") + implementation("io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:2.0.0") + implementation("androidx.multidex:multidex:2.0.1") + implementation("me.saket:better-link-movement-method:2.2.0") + implementation("com.squareup.okhttp3:okhttp:${Versions.okhttp}") + implementation("com.google.code.gson:gson:2.8.5") + implementation("com.github.rey5137:material:1.2.5") + implementation("com.nononsenseapps:filepicker:4.2.1") + implementation("com.google.android.material:material:1.1.0-rc01") + implementation("androidx.annotation:annotation:1.1.0") + implementation("androidx.constraintlayout:constraintlayout:2.0.0-beta4") + implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0") + implementation("com.jakewharton.timber:timber:4.7.1") + implementation("com.jakewharton.threetenabp:threetenabp:1.2.1") + implementation("com.google.guava:guava:27.1-android") + implementation("com.jakewharton:process-phoenix:2.0.0") + implementation("com.google.android.apps.dashclock:dashclock-api:2.0.0") + implementation("com.twofortyfouram:android-plugin-api-for-locale:1.0.2") + implementation("com.rubiconproject.oss:jchronic:0.2.6") { + isTransitive = false + } + implementation("org.scala-saddle:google-rfc-2445:20110304") { + isTransitive = false + } + implementation("com.wdullaer:materialdatetimepicker:4.0.1") + implementation("me.leolin:ShortcutBadger:1.1.22@aar") + implementation("com.google.apis:google-api-services-tasks:v1-rev59-1.25.0") + implementation("com.google.apis:google-api-services-drive:v3-rev188-1.25.0") + implementation("com.google.api-client:google-api-client-android:1.30.7") + implementation("androidx.work:work-runtime:${Versions.work}") + implementation("com.mapbox.mapboxsdk:mapbox-android-sdk:7.3.0") + implementation("com.mapbox.mapboxsdk:mapbox-sdk-services:4.6.0") + + googleplayImplementation("com.crashlytics.sdk.android:crashlytics:${Versions.crashlytics}") + googleplayImplementation("com.google.firebase:firebase-analytics:${Versions.firebase}") + googleplayImplementation("com.google.android.gms:play-services-location:17.0.0") + googleplayImplementation("com.google.android.gms:play-services-maps:17.0.0") + googleplayImplementation("com.google.android.libraries.places:places:2.1.0") + googleplayImplementation("com.android.billingclient:billing:1.2.2") + + amazonImplementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) + amazonImplementation("com.crashlytics.sdk.android:crashlytics:${Versions.crashlytics}") + amazonImplementation("com.google.firebase:firebase-core:${Versions.firebase}") + + androidTestAnnotationProcessor("com.google.dagger:dagger-compiler:${Versions.dagger}") + androidTestAnnotationProcessor("com.jakewharton:butterknife-compiler:${Versions.butterknife}") + androidTestImplementation("com.google.dexmaker:dexmaker-mockito:1.2") + androidTestImplementation("com.natpryce:make-it-easy:4.0.1") + androidTestImplementation("androidx.test:runner:1.2.0") + androidTestImplementation("androidx.test:rules:1.2.0") + androidTestImplementation("androidx.test.ext:junit:1.1.1") + androidTestImplementation("androidx.annotation:annotation:1.1.0") +} + +apply(mapOf("plugin" to "com.google.gms.google-services")) diff --git a/tests/source-files/org.tasks/build.gradle b/tests/source-files/org.tasks/build.gradle new file mode 100644 index 00000000..2edd2b70 --- /dev/null +++ b/tests/source-files/org.tasks/build.gradle @@ -0,0 +1,13 @@ + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'org.owasp:dependency-check-gradle:1.3.2.1' + } +} +apply plugin: 'org.owasp.dependencycheck' +dependencyCheck { + format='JSON' +} diff --git a/tests/source-files/org.tasks/build.gradle.kts b/tests/source-files/org.tasks/build.gradle.kts new file mode 100644 index 00000000..f766cea2 --- /dev/null +++ b/tests/source-files/org.tasks/build.gradle.kts @@ -0,0 +1,26 @@ +buildscript { + repositories { + jcenter() + google() + maven("https://maven.fabric.io/public") + } + + dependencies { + classpath("com.android.tools.build:gradle:3.6.0-rc01") + classpath("com.google.gms:google-services:4.3.3") + // https://docs.fabric.io/android/changelog.html#fabric-gradle-plugin + classpath("io.fabric.tools:gradle:1.31.2") + classpath("com.github.ben-manes:gradle-versions-plugin:0.27.0") + classpath("com.cookpad.android.licensetools:license-tools-plugin:1.7.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}") + } +} + +plugins { + id("com.github.ben-manes.versions") version "0.21.0" +} + +tasks.getByName("wrapper") { + gradleVersion = "5.6.4" + distributionType = Wrapper.DistributionType.ALL +} diff --git a/tests/source-files/org.tasks/buildSrc/build.gradle.kts b/tests/source-files/org.tasks/buildSrc/build.gradle.kts new file mode 100644 index 00000000..c39a297b --- /dev/null +++ b/tests/source-files/org.tasks/buildSrc/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +repositories { + jcenter() +} \ No newline at end of file diff --git a/tests/source-files/org.tasks/settings.gradle.kts b/tests/source-files/org.tasks/settings.gradle.kts new file mode 100644 index 00000000..15a801b1 --- /dev/null +++ b/tests/source-files/org.tasks/settings.gradle.kts @@ -0,0 +1 @@ +include(":app") diff --git a/tests/source-files/ut.ewh.audiometrytest/app/src/main/AndroidManifest.xml b/tests/source-files/ut.ewh.audiometrytest/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1ef6bb12 --- /dev/null +++ b/tests/source-files/ut.ewh.audiometrytest/app/src/main/AndroidManifest.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/source-files/ut.ewh.audiometrytest/build.gradle b/tests/source-files/ut.ewh.audiometrytest/build.gradle new file mode 100644 index 00000000..a90b6488 --- /dev/null +++ b/tests/source-files/ut.ewh.audiometrytest/build.gradle @@ -0,0 +1,29 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.0.0-rc4' + } +} + +allprojects { + repositories { + mavenCentral() + } +} + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'org.owasp:dependency-check-gradle:1.3.2.1' + } +} +apply plugin: 'org.owasp.dependencycheck' +dependencyCheck { + format='JSON' +} diff --git a/tests/source-files/ut.ewh.audiometrytest/settings.gradle b/tests/source-files/ut.ewh.audiometrytest/settings.gradle new file mode 100644 index 00000000..e7b4def4 --- /dev/null +++ b/tests/source-files/ut.ewh.audiometrytest/settings.gradle @@ -0,0 +1 @@ +include ':app' From e9a6c84efd7acfb6c1b53bbf3439d2f569e420ad Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 3 Feb 2020 12:39:41 +0100 Subject: [PATCH 0227/2775] import: split URL parsing from code cloning This makes things testable and easier to follow. --- fdroidserver/import.py | 38 ++++++++++++++++++++++---------------- tests/import.TestCase | 12 +++++------- tests/import_proxy.py | 3 ++- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 5d0ebfcd..99f4c214 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -89,12 +89,9 @@ config = None options = None -def get_metadata_from_url(app, url): +def get_app_from_url(url): - tmp_dir = 'tmp' - if not os.path.isdir(tmp_dir): - logging.info(_("Creating temporary directory")) - os.makedirs(tmp_dir) + app = metadata.App() # Figure out what kind of project it is... projecttype = None @@ -162,18 +159,25 @@ def get_metadata_from_url(app, url): or ' ' in repo): raise FDroidException("Repo address '{0}' does not seem to be valid".format(repo)) - # Get a copy of the source so we can extract some info... - logging.info('Getting source from ' + repotype + ' repo at ' + repo) - build_dir = os.path.join(tmp_dir, 'importer') - if os.path.exists(build_dir): - shutil.rmtree(build_dir) - vcs = common.getvcs(repotype, repo, build_dir) - vcs.gotorevision(options.rev) app.RepoType = repotype app.Repo = repo - return build_dir + return app + +def clone_to_tmp_dir(app): + tmp_dir = 'tmp' + if not os.path.isdir(tmp_dir): + logging.info(_("Creating temporary directory")) + os.makedirs(tmp_dir) + + tmp_dir = os.path.join(tmp_dir, 'importer') + if os.path.exists(tmp_dir): + shutil.rmtree(tmp_dir) + vcs = common.getvcs(app.RepoType, app.Repo, tmp_dir) + vcs.gotorevision(options.rev) + + return tmp_dir def get_all_gradle_and_manifests(build_dir): @@ -234,8 +238,7 @@ def main(): config = common.read_config(options) apps = metadata.read_metadata() - app = metadata.App() - app.UpdateCheckMode = "Tags" + app = None build_dir = None @@ -245,8 +248,10 @@ def main(): build = metadata.Build() if options.url is None and os.path.isdir('.git'): + app = metadata.App() app.AutoName = os.path.basename(os.getcwd()) app.RepoType = 'git' + app.UpdateCheckMode = "Tags" if os.path.exists('build.gradle'): build.gradle = ['yes'] @@ -264,7 +269,8 @@ def main(): build.commit = binascii.hexlify(bytearray(repo.head.commit.binsha)) write_local_file = True elif options.url: - build_dir = get_metadata_from_url(app, options.url) + app = get_app_from_url(options.url) + build_dir = clone_to_tmp_dir(app) build.commit = '?' build.disable = 'Generated by import.py - check/set version fields and commit id' write_local_file = False diff --git a/tests/import.TestCase b/tests/import.TestCase index 4a8936ac..097befcf 100755 --- a/tests/import.TestCase +++ b/tests/import.TestCase @@ -49,9 +49,8 @@ class ImportTest(unittest.TestCase): print('Skipping ImportTest!') return - app = fdroidserver.metadata.App() - app.UpdateCheckMode = "Tags" - build_dir = import_proxy.get_metadata_from_url(app, url) + app = import_proxy.get_app_from_url(url) + import_proxy.clone_to_tmp_dir(app) self.assertEqual(app.RepoType, 'git') self.assertEqual(app.WebSite, 'https://gitlab.com/fdroid/ci-test-app') self.assertEqual(app.Repo, 'https://gitlab.com/fdroid/ci-test-app.git') @@ -87,7 +86,7 @@ class ImportTest(unittest.TestCase): subdir = import_proxy.get_gradle_subdir(build_dir, paths) self.assertEqual(subdirs[f], subdir) - def test_get_metadata_from_url(self): + def test_get_app_from_url(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) os.chdir(testdir) os.mkdir(os.path.join(testdir, 'tmp')) @@ -102,14 +101,13 @@ class ImportTest(unittest.TestCase): shutil.copytree(os.path.join(self.basedir, 'source-files', appid), tmp_importer) - app = fdroidserver.metadata.App() - app.UpdateCheckMode = "Tags" + app = import_proxy.get_app_from_url(url) with mock.patch('fdroidserver.common.getvcs', lambda a, b, c: fdroidserver.common.vcs(url, testdir)): with mock.patch('fdroidserver.common.vcs.gotorevision', lambda s, rev: None): with mock.patch('shutil.rmtree', lambda a: None): - build_dir = import_proxy.get_metadata_from_url(app, url) + build_dir = import_proxy.clone_to_tmp_dir(app) self.assertEqual('git', app.RepoType) self.assertEqual(url, app.Repo) self.assertEqual(url, app.SourceCode) diff --git a/tests/import_proxy.py b/tests/import_proxy.py index f3c4fef8..afe9544e 100644 --- a/tests/import_proxy.py +++ b/tests/import_proxy.py @@ -18,8 +18,9 @@ class Options: module = __import__('fdroidserver.import') for name, obj in inspect.getmembers(module): if name == 'import': + clone_to_tmp_dir = obj.clone_to_tmp_dir get_all_gradle_and_manifests = obj.get_all_gradle_and_manifests - get_metadata_from_url = obj.get_metadata_from_url + get_app_from_url = obj.get_app_from_url get_gradle_subdir = obj.get_gradle_subdir obj.options = Options() options = obj.options From 1153ac24fd9ecd6acb6b6a93c6aaf0a3e1655893 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 3 Feb 2020 12:42:12 +0100 Subject: [PATCH 0228/2775] import: overhaul URL validation to use urllib.parse Python provides us a lovely URL parser with some level of validation built in. The parsed URL is then much easier to validate. --- fdroidserver/import.py | 92 +++++++++++++++++------------------------- tests/import.TestCase | 12 +++++- 2 files changed, 49 insertions(+), 55 deletions(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 99f4c214..7b42b458 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -22,6 +22,7 @@ import glob import os import re import shutil +import urllib.parse import urllib.request from argparse import ArgumentParser import logging @@ -90,81 +91,64 @@ options = None def get_app_from_url(url): + """Guess basic app metadata from the URL. + + The URL must include a network hostname, unless it is an lp:, + file:, or git/ssh URL. This throws ValueError on bad URLs to + match urlparse(). + + """ + + parsed = urllib.parse.urlparse(url) + invalid_url = False + if not parsed.scheme or not parsed.path: + invalid_url = True app = metadata.App() - - # Figure out what kind of project it is... - projecttype = None - app.WebSite = url # by default, we might override it - if url.startswith('git://'): - projecttype = 'git' - repo = url - repotype = 'git' - app.SourceCode = "" - app.WebSite = "" - elif url.startswith('https://github.com'): - projecttype = 'github' - repo = url - repotype = 'git' + app.Repo = url + if url.startswith('git://') or url.startswith('git@'): + app.RepoType = 'git' + elif parsed.netloc == 'github.com': + app.RepoType = 'git' app.SourceCode = url app.IssueTracker = url + '/issues' - app.WebSite = "" - elif url.startswith('https://gitlab.com/'): - projecttype = 'gitlab' + elif parsed.netloc == 'gitlab.com': # git can be fussy with gitlab URLs unless they end in .git if url.endswith('.git'): url = url[:-4] - repo = url + '.git' - repotype = 'git' - app.WebSite = url - app.SourceCode = url + '/tree/HEAD' - app.IssueTracker = url + '/issues' - elif url.startswith('https://notabug.org/'): - projecttype = 'notabug' - if url.endswith('.git'): - url = url[:-4] - repo = url + '.git' - repotype = 'git' + app.Repo = url + '.git' + app.RepoType = 'git' app.SourceCode = url app.IssueTracker = url + '/issues' - app.WebSite = "" - elif url.startswith('https://bitbucket.org/'): + elif parsed.netloc == 'notabug.org': + if url.endswith('.git'): + url = url[:-4] + app.Repo = url + '.git' + app.RepoType = 'git' + app.SourceCode = url + app.IssueTracker = url + '/issues' + elif parsed.netloc == 'bitbucket.org': if url.endswith('/'): url = url[:-1] - projecttype = 'bitbucket' app.SourceCode = url + '/src' app.IssueTracker = url + '/issues' # Figure out the repo type and adddress... - repotype, repo = getrepofrompage(url) - if not repotype: - raise FDroidException("Unable to determine vcs type. " + repo) + app.RepoType, app.Repo = getrepofrompage(url) elif url.startswith('https://') and url.endswith('.git'): - projecttype = 'git' - repo = url - repotype = 'git' - app.SourceCode = "" - app.WebSite = "" - if not projecttype: - raise FDroidException("Unable to determine the project type. " - + "The URL you supplied was not in one of the supported formats. " - + "Please consult the manual for a list of supported formats, " - + "and supply one of those.") + app.RepoType = 'git' - # 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 - # specifically don't want git@...) - if ((repotype != 'bzr' and (not repo.startswith('http://') - and not repo.startswith('https://') - and not repo.startswith('git://'))) - or ' ' in repo): - raise FDroidException("Repo address '{0}' does not seem to be valid".format(repo)) + if not parsed.netloc and parsed.scheme in ('git', 'http', 'https', 'ssh'): + invalid_url = True + if invalid_url: + raise ValueError(_('"{url}" is not a valid URL!'.format(url=url))) - app.RepoType = repotype - app.Repo = repo + if not app.RepoType: + raise FDroidException("Unable to determine vcs type. " + app.Repo) return app + def clone_to_tmp_dir(app): tmp_dir = 'tmp' if not os.path.isdir(tmp_dir): diff --git a/tests/import.TestCase b/tests/import.TestCase index 097befcf..30b660aa 100755 --- a/tests/import.TestCase +++ b/tests/import.TestCase @@ -52,7 +52,6 @@ class ImportTest(unittest.TestCase): app = import_proxy.get_app_from_url(url) import_proxy.clone_to_tmp_dir(app) self.assertEqual(app.RepoType, 'git') - self.assertEqual(app.WebSite, 'https://gitlab.com/fdroid/ci-test-app') self.assertEqual(app.Repo, 'https://gitlab.com/fdroid/ci-test-app.git') def test_get_all_gradle_and_manifests(self): @@ -86,6 +85,17 @@ class ImportTest(unittest.TestCase): subdir = import_proxy.get_gradle_subdir(build_dir, paths) self.assertEqual(subdirs[f], subdir) + def test_bad_urls(self): + for url in ('asdf', + 'file://thing.git', + 'https:///github.com/my/project', + 'git:///so/many/slashes', + 'ssh:/notabug.org/missing/a/slash', + 'git:notabug.org/missing/some/slashes', + 'https//github.com/bar/baz'): + with self.assertRaises(ValueError): + import_proxy.get_app_from_url(url) + def test_get_app_from_url(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) os.chdir(testdir) From e037ee5972f2e5d4c34e1261faf2e91c2dc147e0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 4 Feb 2020 00:22:24 +0100 Subject: [PATCH 0229/2775] import: generate skeleton build fields for react-native and flutter --- fdroidserver/import.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 7b42b458..a7dfaa49 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -19,14 +19,21 @@ import binascii import glob +import json import os import re import shutil import urllib.parse import urllib.request +import yaml from argparse import ArgumentParser import logging +try: + from yaml import CSafeLoader as SafeLoader +except ImportError: + from yaml import SafeLoader + from . import _ from . import common from . import metadata @@ -296,6 +303,36 @@ def main(): if os.path.exists(os.path.join(subdir, 'build.gradle')): build.gradle = ['yes'] + package_json = os.path.join(build_dir, 'package.json') # react-native + pubspec_yaml = os.path.join(build_dir, 'pubspec.yaml') # flutter + if os.path.exists(package_json): + build.sudo = ['apt-get install npm', 'npm install -g react-native-cli'] + build.init = ['npm install'] + with open(package_json) as fp: + data = json.load(fp) + app.AutoName = data.get('name', app.AutoName) + app.License = data.get('license', app.License) + app.Description = data.get('description', app.Description) + app.WebSite = data.get('homepage', app.WebSite) + app_json = os.path.join(build_dir, 'app.json') + if os.path.exists(app_json): + with open(app_json) as fp: + data = json.load(fp) + app.AutoName = data.get('name', app.AutoName) + if os.path.exists(pubspec_yaml): + with open(pubspec_yaml) as fp: + data = yaml.load(fp, Loader=SafeLoader) + app.AutoName = data.get('name', app.AutoName) + app.License = data.get('license', app.License) + app.Description = data.get('description', app.Description) + build.srclibs = ['flutter@stable'] + build.output = 'build/app/outputs/apk/release/app-release.apk' + build.build = [ + '$$flutter$$/bin/flutter config --no-analytics', + '$$flutter$$/bin/flutter packages pub get', + '$$flutter$$/bin/flutter build apk', + ] + metadata.post_metadata_parse(app) app.builds.append(build) From ad92b4c67873bf3fa94be1c87351a5f83a46158c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 5 Feb 2020 20:30:16 +0100 Subject: [PATCH 0230/2775] scanner: add --force option for scanning disabled apps/builds --- fdroidserver/scanner.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index ad23912e..db990f97 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -286,6 +286,8 @@ def main(): parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") common.setup_global_opts(parser) parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) + parser.add_argument("-f", "--force", action="store_true", default=False, + help=_("Force scan of disabled apps and builds.")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W @@ -307,7 +309,7 @@ def main(): for appid, app in apps.items(): - if app.Disabled: + if app.Disabled and not options.force: logging.info(_("Skipping {appid}: disabled").format(appid=appid)) continue @@ -334,7 +336,7 @@ def main(): for build in app.builds: - if build.disable: + if build.disable and not options.force: logging.info("...skipping version %s - %s" % ( build.versionName, build.get('disable', build.commit[1:]))) continue From d9722f44539de700b8f19eb5c2877c0e34280b1d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 12 Feb 2020 13:58:47 +0100 Subject: [PATCH 0231/2775] buildserver: use long timeouts for gradle downloads default is 30 seconds, this uses 10 minutes to avoid things like: * What went wrong: A problem occurred configuring root project 'org.fdroid.fdroid'. > Could not resolve all files for configuration ':classpath'. > Could not download auto-value.jar (com.google.auto.value:auto-value:1.5.2) > Could not get resource 'https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value/1.5.2/auto-value-1.5.2.jar'. > Read timed out * https://stackoverflow.com/a/49646993 * https://github.com/gradle/gradle/issues/4629#issuecomment-393182135 * https://github.com/gradle/gradle/pull/3371/files --- buildserver/provision-gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/buildserver/provision-gradle b/buildserver/provision-gradle index 6ec35f0b..a613e332 100644 --- a/buildserver/provision-gradle +++ b/buildserver/provision-gradle @@ -33,6 +33,13 @@ cat < $GRADLE_HOME/gradle.properties # builds are not reused, so the daemon is a waste of time org.gradle.daemon=false +# set network timeouts to 10 minutes +# https://github.com/gradle/gradle/pull/3371/files +systemProp.http.connectionTimeout=600000 +systemProp.http.socketTimeout=600000 +systemProp.org.gradle.internal.http.connectionTimeout=600000 +systemProp.org.gradle.internal.http.socketTimeout=600000 + # fake info to block HTTP repos systemProp.http.nonProxyHosts= systemProp.http.proxyHost=127.127.127.127 From 83ffeb855f694907be7e7539d27b9457264a3da6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 3 Feb 2020 21:13:26 +0100 Subject: [PATCH 0232/2775] prefer build.gradle with Android Plugin as source of package/version/code These days, the location that overrides all the others is in the android{} block of the build.gradle file that loads the com.android.application plugin. So this should be the preferred place to read these values. test files GPL licensed: https://github.com/Integreight/1Sheeld-Android-App --- fdroidserver/common.py | 13 + fdroidserver/import.py | 3 +- tests/common.TestCase | 21 ++ tests/scanner.TestCase | 1 + .../com.integreight.onesheeld/build.gradle | 16 + .../gradle/wrapper/gradle-wrapper.properties | 6 + .../localeapi/build.gradle | 22 ++ .../localeapi/src/main/AndroidManifest.xml | 9 + .../oneSheeld/build.gradle | 129 ++++++++ .../oneSheeld/src/main/AndroidManifest.xml | 280 ++++++++++++++++++ .../pagerIndicator/build.gradle | 22 ++ .../src/main/AndroidManifest.xml | 9 + .../pullToRefreshlibrary/build.gradle | 20 ++ .../src/main/AndroidManifest.xml | 11 + .../quickReturnHeader/build.gradle | 22 ++ .../src/main/AndroidManifest.xml | 11 + .../com.integreight.onesheeld/settings.gradle | 5 + 17 files changed, 598 insertions(+), 2 deletions(-) create mode 100644 tests/source-files/com.integreight.onesheeld/build.gradle create mode 100644 tests/source-files/com.integreight.onesheeld/gradle/wrapper/gradle-wrapper.properties create mode 100644 tests/source-files/com.integreight.onesheeld/localeapi/build.gradle create mode 100644 tests/source-files/com.integreight.onesheeld/localeapi/src/main/AndroidManifest.xml create mode 100644 tests/source-files/com.integreight.onesheeld/oneSheeld/build.gradle create mode 100644 tests/source-files/com.integreight.onesheeld/oneSheeld/src/main/AndroidManifest.xml create mode 100644 tests/source-files/com.integreight.onesheeld/pagerIndicator/build.gradle create mode 100644 tests/source-files/com.integreight.onesheeld/pagerIndicator/src/main/AndroidManifest.xml create mode 100644 tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/build.gradle create mode 100644 tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/src/main/AndroidManifest.xml create mode 100644 tests/source-files/com.integreight.onesheeld/quickReturnHeader/build.gradle create mode 100644 tests/source-files/com.integreight.onesheeld/quickReturnHeader/src/main/AndroidManifest.xml create mode 100644 tests/source-files/com.integreight.onesheeld/settings.gradle diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 946c0de1..d94c995b 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -81,6 +81,7 @@ FDROID_PACKAGE_NAME_REGEX = re.compile(r'''^[a-f0-9]+$''', re.IGNORECASE) STRICT_APPLICATION_ID_REGEX = re.compile(r'''(?:^[a-zA-Z]+(?:\d*[a-zA-Z_]*)*)(?:\.[a-zA-Z]+(?:\d*[a-zA-Z_]*)*)+$''') VALID_APPLICATION_ID_REGEX = re.compile(r'''(?:^[a-z_]+(?:\d*[a-zA-Z_]*)*)(?:\.[a-z_]+(?:\d*[a-zA-Z_]*)*)*$''', re.IGNORECASE) +ANDROID_PLUGIN_REGEX = re.compile(r'''\s*(:?apply plugin:|id)\(?\s*['"](android|com\.android\.application)['"]\s*\)?''') MAX_VERSION_CODE = 0x7fffffff # Java's Integer.MAX_VALUE (2147483647) @@ -1421,6 +1422,7 @@ def parse_androidmanifests(paths, app): if has_extension(path, 'gradle'): with open(path, 'r') as f: + android_plugin_file = False inside_flavour_group = 0 inside_required_flavour = 0 for line in f: @@ -1496,6 +1498,17 @@ def parse_androidmanifests(paths, app): matches = vcsearch_g(line) if matches: vercode = matches.group(1) + if not android_plugin_file and ANDROID_PLUGIN_REGEX.match(line): + android_plugin_file = True + if android_plugin_file: + if package: + max_package = package + if version: + max_version = version + if vercode: + max_vercode = vercode + if max_package and max_version and max_vercode: + break else: try: xml = parse_xml(path) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index a7dfaa49..1fbf9a5f 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -41,7 +41,6 @@ from .exception import FDroidException SETTINGS_GRADLE = re.compile(r'settings\.gradle(?:\.kts)?') GRADLE_SUBPROJECT = re.compile(r'''['"]:([^'"]+)['"]''') -ANDROID_PLUGIN = re.compile(r'''\s*(:?apply plugin:|id)\(?\s*['"](android|com\.android\.application)['"]\s*\)?''') # Get the repo type and address from the given web page. The page is scanned @@ -197,7 +196,7 @@ def get_gradle_subdir(build_dir, paths): line = fp.readline() if not line: break - if ANDROID_PLUGIN.match(line): + if common.ANDROID_PLUGIN_REGEX.match(line): return os.path.relpath(os.path.dirname(f), build_dir) if first_gradle_dir and first_gradle_dir != '.': return first_gradle_dir diff --git a/tests/common.TestCase b/tests/common.TestCase index bb4d78a6..e003d161 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -840,6 +840,27 @@ class CommonTest(unittest.TestCase): self.assertEqual(('0.6.9', '23', 'cn.wildfirechat.chat'), fdroidserver.common.parse_androidmanifests(paths, app)) + app = fdroidserver.metadata.App() + app.Repo = 'https://github.com/Integreight/1Sheeld-Android-App' + paths = [ + os.path.join('source-files', 'com.integreight.onesheeld', 'pagerIndicator', 'src', 'main', 'AndroidManifest.xml'), + os.path.join('source-files', 'com.integreight.onesheeld', 'pagerIndicator', 'build.gradle'), + os.path.join('source-files', 'com.integreight.onesheeld', 'oneSheeld', 'src', 'main', 'AndroidManifest.xml'), + os.path.join('source-files', 'com.integreight.onesheeld', 'oneSheeld', 'build.gradle'), + os.path.join('source-files', 'com.integreight.onesheeld', 'localeapi', 'src', 'main', 'AndroidManifest.xml'), + os.path.join('source-files', 'com.integreight.onesheeld', 'localeapi', 'build.gradle'), + os.path.join('source-files', 'com.integreight.onesheeld', 'build.gradle'), + os.path.join('source-files', 'com.integreight.onesheeld', 'settings.gradle'), + os.path.join('source-files', 'com.integreight.onesheeld', 'quickReturnHeader', 'src', 'main', 'AndroidManifest.xml'), + os.path.join('source-files', 'com.integreight.onesheeld', 'quickReturnHeader', 'build.gradle'), + os.path.join('source-files', 'com.integreight.onesheeld', 'pullToRefreshlibrary', 'src', 'main', 'AndroidManifest.xml'), + os.path.join('source-files', 'com.integreight.onesheeld', 'pullToRefreshlibrary', 'build.gradle'), + ] + for path in paths: + self.assertTrue(os.path.isfile(path)) + self.assertEqual(('1.9.0', '170521', 'com.integreight.onesheeld'), + fdroidserver.common.parse_androidmanifests(paths, app)) + def test_parse_androidmanifests_ignore(self): app = fdroidserver.metadata.App() app.id = 'org.fdroid.fdroid' diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index b8f46af9..6017a999 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -29,6 +29,7 @@ class ScannerTest(unittest.TestCase): source_files = os.path.join(self.basedir, 'source-files') projects = { 'cn.wildfirechat.chat': 4, + 'com.integreight.onesheeld': 11, 'Zillode': 1, 'firebase-suspect': 1, 'org.mozilla.rocket': 3, diff --git a/tests/source-files/com.integreight.onesheeld/build.gradle b/tests/source-files/com.integreight.onesheeld/build.gradle new file mode 100644 index 00000000..4aa9de97 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/build.gradle @@ -0,0 +1,16 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.2' + classpath 'com.google.gms:google-services:3.0.0' + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/tests/source-files/com.integreight.onesheeld/gradle/wrapper/gradle-wrapper.properties b/tests/source-files/com.integreight.onesheeld/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..c88a02a7 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Mar 15 14:07:53 EET 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip diff --git a/tests/source-files/com.integreight.onesheeld/localeapi/build.gradle b/tests/source-files/com.integreight.onesheeld/localeapi/build.gradle new file mode 100644 index 00000000..83e327f8 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/localeapi/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.3" + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 17 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +dependencies { + compile 'com.android.support:support-v4:25.1.0' +} diff --git a/tests/source-files/com.integreight.onesheeld/localeapi/src/main/AndroidManifest.xml b/tests/source-files/com.integreight.onesheeld/localeapi/src/main/AndroidManifest.xml new file mode 100644 index 00000000..3178f4f4 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/localeapi/src/main/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/tests/source-files/com.integreight.onesheeld/oneSheeld/build.gradle b/tests/source-files/com.integreight.onesheeld/oneSheeld/build.gradle new file mode 100644 index 00000000..60559586 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/oneSheeld/build.gradle @@ -0,0 +1,129 @@ +buildscript { + repositories { + jcenter() + maven { url 'https://maven.fabric.io/public' } + } + + dependencies { + classpath 'io.fabric.tools:gradle:1.+' + } +} +apply plugin: 'com.android.application' +apply plugin: 'io.fabric' + +repositories { + jcenter() + maven { url 'https://maven.fabric.io/public' } + maven { url "https://jitpack.io" } +} + + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.3" + + defaultConfig { + applicationId "com.integreight.onesheeld" + minSdkVersion 9 + targetSdkVersion 25 + versionCode 170521 + versionName "1.9.0" + archivesBaseName = "1Sheeld.v$versionName.$versionCode" + buildConfigField "long", "TIMESTAMP", System.currentTimeMillis() + "L" + } + + buildTypes.all { + ext.enableCrashlytics = isCrashlyticsPropertiesAvailable() + } + + buildTypes { + debug { + versionNameSuffix getWorkingBranchSuffix() + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + release { + minifyEnabled true + debuggable false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + packagingOptions { + exclude 'META-INF/LICENSE' + exclude 'META-INF/NOTICE' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + } + + lintOptions { + abortOnError false + } + + useLibrary 'org.apache.http.legacy' +} + +dependencies { + compile project(':localeapi') + compile project(':pullToRefreshlibrary') + compile project(':quickReturnHeader') + compile project(':pagerIndicator') + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:support-v4:25.3.1' + compile 'com.facebook.android:facebook-android-sdk:4.5.0' + compile 'com.google.android.gms:play-services-analytics:10.0.1' + compile 'com.google.android.gms:play-services-location:10.0.1' + compile 'com.google.android.gms:play-services-auth:10.0.1' + compile 'com.google.android.gms:play-services-vision:10.0.1' + compile 'com.loopj.android:android-async-http:1.4.9' + compile 'com.snappydb:snappydb-lib:0.5.0' + compile 'com.esotericsoftware.kryo:kryo:2.24.0' + compile 'com.github.hotchemi:android-rate:0.5.0' + compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') { + transitive = true; + } + + compile('com.google.android.gms:play-services-identity:10.0.1') { + transitive = true; + } + compile('com.google.api-client:google-api-client-android:1.22.0') { + exclude group: 'org.apache.httpcomponents' + } + compile('com.google.apis:google-api-services-gmail:v1-rev48-1.22.0') { + exclude group: 'org.apache.httpcomponents' + } + compile 'org.twitter4j:twitter4j-core:4.0.4' + compile 'org.twitter4j:twitter4j-async:4.0.4' + compile 'org.twitter4j:twitter4j-stream:4.0.4' + compile 'cz.msebera.android:httpclient:4.4.1.1' + compile 'net.sf.supercsv:super-csv:2.4.0' + compile 'com.github.amlcurran.showcaseview:library:5.4.3' + compile 'com.github.emanzanoaxa:RippleEffect:52ea2a0ab6' + compile 'com.drewnoakes:metadata-extractor:2.8.1' + compile 'com.integreight.onesheeld:sdk:2.2.0' + compile 'com.google.firebase:firebase-core:10.0.1' + compile 'com.google.firebase:firebase-messaging:10.0.1' +} + +def isCrashlyticsPropertiesAvailable() { + return new File("./oneSheeld/fabric.properties").exists() +} + +def getWorkingBranchSuffix() { + def workingBranchSuffix = "" + try { + def workingBranch = "git --git-dir=${rootDir}/.git --work-tree=${rootDir} rev-parse --abbrev-ref HEAD".execute().text.trim() + workingBranchSuffix = (workingBranch != "") ? " - branch:" + workingBranch : "" + } + catch (all) { + } + return workingBranchSuffix +} + +def isGoogleServicesFileAvailable() { + return new File("./oneSheeld/google-services.json").exists() +} + +if (isGoogleServicesFileAvailable()) { + apply plugin: 'com.google.gms.google-services' +} \ No newline at end of file diff --git a/tests/source-files/com.integreight.onesheeld/oneSheeld/src/main/AndroidManifest.xml b/tests/source-files/com.integreight.onesheeld/oneSheeld/src/main/AndroidManifest.xml new file mode 100644 index 00000000..05350254 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/oneSheeld/src/main/AndroidManifest.xml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/source-files/com.integreight.onesheeld/pagerIndicator/build.gradle b/tests/source-files/com.integreight.onesheeld/pagerIndicator/build.gradle new file mode 100644 index 00000000..254932bd --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/pagerIndicator/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.3" + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 9 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +dependencies { + compile 'com.android.support:support-v4:25.1.0' +} diff --git a/tests/source-files/com.integreight.onesheeld/pagerIndicator/src/main/AndroidManifest.xml b/tests/source-files/com.integreight.onesheeld/pagerIndicator/src/main/AndroidManifest.xml new file mode 100644 index 00000000..4314f1b3 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/pagerIndicator/src/main/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/build.gradle b/tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/build.gradle new file mode 100644 index 00000000..7db12afa --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/build.gradle @@ -0,0 +1,20 @@ +apply plugin: 'com.android.library' +android { + compileSdkVersion 25 + buildToolsVersion "25.0.3" + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 9 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +dependencies { +} \ No newline at end of file diff --git a/tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/src/main/AndroidManifest.xml b/tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/src/main/AndroidManifest.xml new file mode 100644 index 00000000..c3db5673 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/src/main/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/tests/source-files/com.integreight.onesheeld/quickReturnHeader/build.gradle b/tests/source-files/com.integreight.onesheeld/quickReturnHeader/build.gradle new file mode 100644 index 00000000..83e327f8 --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/quickReturnHeader/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.3" + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 17 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +dependencies { + compile 'com.android.support:support-v4:25.1.0' +} diff --git a/tests/source-files/com.integreight.onesheeld/quickReturnHeader/src/main/AndroidManifest.xml b/tests/source-files/com.integreight.onesheeld/quickReturnHeader/src/main/AndroidManifest.xml new file mode 100644 index 00000000..235aef0b --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/quickReturnHeader/src/main/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/tests/source-files/com.integreight.onesheeld/settings.gradle b/tests/source-files/com.integreight.onesheeld/settings.gradle new file mode 100644 index 00000000..fe8d1fea --- /dev/null +++ b/tests/source-files/com.integreight.onesheeld/settings.gradle @@ -0,0 +1,5 @@ +include ':pagerIndicator' +include ':pullToRefreshlibrary' +include ':quickReturnHeader' +include ':localeapi' +include ':oneSheeld' From 3de2d0f56f5ce797276d925387d6229383fac42a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 13 Feb 2020 10:22:24 +0100 Subject: [PATCH 0233/2775] add basic test suite for gradlew-fdroid !707 fdroiddata#6216 The se.manyver app is licensed MPL, the files came from: https://gitlab.com/staltz/manyverse/commit/81d247a6cd89399836778e9ee71f7a4373e16701 --- .gitlab-ci.yml | 1 + tests/scanner.TestCase | 1 + .../gradle/wrapper/gradle-wrapper.properties | 6 + .../se.manyver/android/app/build.gradle | 272 ++++++++++++++++++ .../se.manyver/android/build.gradle | 64 +++++ .../se.manyver/android/gradle.properties | 22 ++ .../gradle/wrapper/gradle-wrapper.properties | 5 + .../se.manyver/android/settings.gradle | 40 +++ tests/source-files/se.manyver/app.json | 4 + .../source-files/se.manyver/index.android.js | 17 ++ tests/source-files/se.manyver/package.json | 135 +++++++++ .../se.manyver/react-native.config.js | 18 ++ tests/test-gradlew-fdroid | 26 ++ 13 files changed, 611 insertions(+) create mode 100644 tests/source-files/osmandapp/osmand/gradle/wrapper/gradle-wrapper.properties create mode 100644 tests/source-files/se.manyver/android/app/build.gradle create mode 100644 tests/source-files/se.manyver/android/build.gradle create mode 100644 tests/source-files/se.manyver/android/gradle.properties create mode 100644 tests/source-files/se.manyver/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 tests/source-files/se.manyver/android/settings.gradle create mode 100644 tests/source-files/se.manyver/app.json create mode 100644 tests/source-files/se.manyver/index.android.js create mode 100644 tests/source-files/se.manyver/package.json create mode 100644 tests/source-files/se.manyver/react-native.config.js create mode 100755 tests/test-gradlew-fdroid diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8afae7b0..08af6e5c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -142,6 +142,7 @@ lint_format_safety_bandit_checks: - $pip install Babel 'bandit<1.6.0' pycodestyle pyflakes 'pylint<2.0' safety - export EXITVALUE=0 - ./hooks/pre-commit || export EXITVALUE=1 + - ./tests/test-gradlew-fdroid || export EXITVALUE=1 - bandit -ii -s B110,B322,B404,B408,B410,B603,B607 diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 6017a999..cbaa9de2 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -34,6 +34,7 @@ class ScannerTest(unittest.TestCase): 'firebase-suspect': 1, 'org.mozilla.rocket': 3, 'realm': 1, + 'se.manyver': 2, } for d in glob.glob(os.path.join(source_files, '*')): build = fdroidserver.metadata.Build() diff --git a/tests/source-files/osmandapp/osmand/gradle/wrapper/gradle-wrapper.properties b/tests/source-files/osmandapp/osmand/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..a3185c1e --- /dev/null +++ b/tests/source-files/osmandapp/osmand/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Sep 01 10:23:06 EEST 2014 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/tests/source-files/se.manyver/android/app/build.gradle b/tests/source-files/se.manyver/android/app/build.gradle new file mode 100644 index 00000000..1c77f965 --- /dev/null +++ b/tests/source-files/se.manyver/android/app/build.gradle @@ -0,0 +1,272 @@ +apply plugin: "com.android.application" + +import com.android.build.OutputFile + +/** + * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets + * and bundleReleaseJsAndAssets). + * These basically call `react-native bundle` with the correct arguments during the Android build + * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the + * bundle directly from the development server. Below you can see all the possible configurations + * and their defaults. If you decide to add a configuration block, make sure to add it before the + * `apply from: "../../node_modules/react-native/react.gradle"` line. + * + * project.ext.react = [ + * // the name of the generated asset file containing your JS bundle + * bundleAssetName: "index.android.bundle", + * + * // the entry file for bundle generation + * entryFile: "index.android.js", + * + * // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format + * bundleCommand: "ram-bundle", + * + * // whether to bundle JS and assets in debug mode + * bundleInDebug: false, + * + * // whether to bundle JS and assets in release mode + * bundleInRelease: true, + * + * // whether to bundle JS and assets in another build variant (if configured). + * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants + * // The configuration property can be in the following formats + * // 'bundleIn${productFlavor}${buildType}' + * // 'bundleIn${buildType}' + * // bundleInFreeDebug: true, + * // bundleInPaidRelease: true, + * // bundleInBeta: true, + * + * // whether to disable dev mode in custom build variants (by default only disabled in release) + * // for example: to disable dev mode in the staging build type (if configured) + * devDisabledInStaging: true, + * // The configuration property can be in the following formats + * // 'devDisabledIn${productFlavor}${buildType}' + * // 'devDisabledIn${buildType}' + * + * // the root of your project, i.e. where "package.json" lives + * root: "../../", + * + * // where to put the JS bundle asset in debug mode + * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", + * + * // where to put the JS bundle asset in release mode + * jsBundleDirRelease: "$buildDir/intermediates/assets/release", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in debug mode + * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in release mode + * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", + * + * // by default the gradle tasks are skipped if none of the JS files or assets change; this means + * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to + * // date; if you have any other folders that you want to ignore for performance reasons (gradle + * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ + * // for example, you might want to remove it from here. + * inputExcludes: ["android/**", "ios/**"], + * + * // override which node gets called and with what additional arguments + * nodeExecutableAndArgs: ["node"], + * + * // supply additional arguments to the packager + * extraPackagerArgs: [] + * ] + */ + +project.ext.vectoricons = [ + iconFontNames: [ 'MaterialIcons.ttf', 'MaterialCommunityIcons.ttf' ] +] +project.ext.react = [ + entryFile: "index.android.js", + enableHermes: false, // clean and rebuild if changing + hermesCommand: "../../node_modules/hermes-engine/%OS-BIN%/hermes", +] +apply from: "../../node_modules/react-native-vector-icons/fonts.gradle" +apply from: "../../node_modules/react-native/react.gradle" + +/** + * Set this to true to create two separate APKs instead of one: + * - An APK that only works on ARM devices + * - An APK that only works on x86 devices + * The advantage is the size of the APK is reduced by about 4MB. + * Upload all the APKs to the Play Store and people will download + * the correct one based on the CPU architecture of their device. + */ +def enableSeparateBuildPerCPUArchitecture = false + +/** + * Run Proguard to shrink the Java bytecode in release builds. + */ +def enableProguardInReleaseBuilds = false + +/** + * The preferred build flavor of JavaScriptCore. + * + * For example, to use the international variant, you can use: + * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` + * + * The international variant includes ICU i18n library and necessary data + * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that + * give correct results when using with locales other than en-US. Note that + * this variant is about 6MiB larger per architecture than default. + */ +def jscFlavor = 'org.webkit:android-jsc:+' + +/** + * Whether to enable the Hermes VM. + * + * This should be set on project.ext.react and mirrored here. If it is not set + * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode + * and the benefits of using Hermes will therefore be sharply reduced. + */ +def enableHermes = project.ext.react.get("enableHermes", false); + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + flavorDimensions "store" + + defaultConfig { + versionCode 78 + versionName "0.1911.27-beta" + applicationId "se.manyver" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + missingDimensionStrategy "RNN.reactNativeVersion", "reactNative60" + ndk { + abiFilters "armeabi-v7a", "arm64-v8a" // , "x86", "x86_64" + } + aaptOptions { + ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~' + } + vectorDrawables.useSupportLibrary = true + } + + // dexOptions { + // javaMaxHeapSize "4g" + // } + + productFlavors { + indie { + dimension "store" + } + + googlePlay { + dimension "store" + versionNameSuffix "-googlePlay" + targetSdkVersion rootProject.ext.targetSdkVersionForGooglePlay + } + } + + signingConfigs { + // debug { + // storeFile file('debug.keystore') + // storePassword 'android' + // keyAlias 'androiddebugkey' + // keyPassword 'android' + // } + release { + if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) { + storeFile file(MYAPP_RELEASE_STORE_FILE) + storePassword MYAPP_RELEASE_STORE_PASSWORD + keyAlias MYAPP_RELEASE_KEY_ALIAS + keyPassword MYAPP_RELEASE_KEY_PASSWORD + } + } + } + + splits { + abi { + reset() + enable enableSeparateBuildPerCPUArchitecture + universalApk false // If true, also generate a universal APK + include "armeabi-v7a", "arm64-v8a"//, "x86", "x86_64" + } + } + + buildTypes { + debug { + signingConfig signingConfigs.debug + } + release { + // Caution! In production, you need to generate your own keystore file. + // see https://facebook.github.io/react-native/docs/signed-apk-android. + // signingConfig signingConfigs.debug + minifyEnabled enableProguardInReleaseBuilds + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) { + signingConfig signingConfigs.release + } + } + } + + // applicationVariants are e.g. debug, release + applicationVariants.all { variant -> + variant.outputs.each { output -> + // For each separate APK per architecture, set a unique version code as described here: + // https://developer.android.com/studio/build/configure-apk-splits.html + def versionCodes = ["armeabi-v7a": 1, "arm64-v8a": 2] //, "x86":3, "x86_64":4] + def abi = output.getFilter(OutputFile.ABI) + if (abi != null) { // null for the universal-debug, universal-release variants + output.versionCodeOverride = + versionCodes.get(abi) * 1048576 + defaultConfig.versionCode + } + } + } +} + +def acraVersion = '5.3.0' + +dependencies { + implementation "ch.acra:acra-core:$acraVersion" + implementation "ch.acra:acra-mail:$acraVersion" + implementation "ch.acra:acra-dialog:$acraVersion" + implementation project(':nodejs-mobile-react-native') + implementation project(':@react-native-community_async-storage') + implementation project(':react-native-bluetooth-socket-bridge') + implementation project(':react-native-bluetooth-status') + implementation project(':react-native-dialogs') + implementation project(':react-native-vector-icons') + implementation project(':react-native-os-staltz') + implementation project(':react-native-randombytes') + implementation project(':react-native-image-crop-picker') + implementation project(':react-native-navigation') + implementation project(':react-native-android-local-notification') + implementation project(':react-native-android-wifi') + implementation project(':react-native-has-internet') + implementation project(':react-native-flag-secure-android') + implementation project(':react-native-orientation-locker') + implementation project(':react-native-fs') + implementation project(':react-native-splash-screen') + implementation project(':@react-native-community_viewpager') + implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation("com.facebook.react:react-native:+") { + force = true + } + implementation 'com.facebook.fresco:animated-gif:1.3.0' + + if (enableHermes) { + def hermesPath = "../../node_modules/hermes-engine/android/"; + debugImplementation files(hermesPath + "hermes-debug.aar") + releaseImplementation files(hermesPath + "hermes-release.aar") + } else { + implementation jscFlavor + } +} + +// Run this once to be able to run the application with BUCK +// puts all compile dependencies into folder libs for BUCK to use +task copyDownloadableDepsToLibs(type: Copy) { + from configurations.compile + into 'libs' +} + +apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) \ No newline at end of file diff --git a/tests/source-files/se.manyver/android/build.gradle b/tests/source-files/se.manyver/android/build.gradle new file mode 100644 index 00000000..de8f5e77 --- /dev/null +++ b/tests/source-files/se.manyver/android/build.gradle @@ -0,0 +1,64 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + ext { + minSdkVersion = 21 + targetSdkVersion = 26 + targetSdkVersionForGooglePlay = 28 + compileSdkVersion = 28 + } + repositories { + google() + jcenter() + mavenLocal() + mavenCentral() + } + dependencies { + classpath("com.android.tools.build:gradle:3.4.2") + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + mavenCentral() + mavenLocal() + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url("$rootDir/../node_modules/react-native/android") + } + maven { + // Android JSC is installed from npm + url("$rootDir/../node_modules/jsc-android/dist") + } + maven { + url 'https://maven.google.com' + } + maven { + url "https://jitpack.io" + } + google() + jcenter() + } +} + +subprojects { subproject -> + afterEvaluate { + if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) { + android { + variantFilter { variant -> + def names = variant.flavors*.name + if (names.contains("reactNative51")) setIgnore(true) + if (names.contains("reactNative55")) setIgnore(true) + if (names.contains("reactNative56")) setIgnore(true) + if (names.contains("reactNative57")) setIgnore(true) + if (names.contains("reactNative57_5")) setIgnore(true) + if (names.contains("reactNative57WixFork")) setIgnore(true) + if (names.contains("reactNative59")) setIgnore(true) + } + } + } + } +} diff --git a/tests/source-files/se.manyver/android/gradle.properties b/tests/source-files/se.manyver/android/gradle.properties new file mode 100644 index 00000000..33fd4ac9 --- /dev/null +++ b/tests/source-files/se.manyver/android/gradle.properties @@ -0,0 +1,22 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +android.useAndroidX=true +android.enableJetifier=true +org.gradle.jvmargs=-Xmx4608M \ No newline at end of file diff --git a/tests/source-files/se.manyver/android/gradle/wrapper/gradle-wrapper.properties b/tests/source-files/se.manyver/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..a14cb8c9 --- /dev/null +++ b/tests/source-files/se.manyver/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip \ No newline at end of file diff --git a/tests/source-files/se.manyver/android/settings.gradle b/tests/source-files/se.manyver/android/settings.gradle new file mode 100644 index 00000000..6a4c91ed --- /dev/null +++ b/tests/source-files/se.manyver/android/settings.gradle @@ -0,0 +1,40 @@ +rootProject.name = 'Manyverse' +apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) +include ':@react-native-community_async-storage' +project(':@react-native-community_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android') +include ':react-native-bluetooth-status' +project(':react-native-bluetooth-status').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-bluetooth-status/android') +include ':react-native-bluetooth-socket-bridge' +project(':react-native-bluetooth-socket-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-bluetooth-socket-bridge/android') +include ':react-native-image-crop-picker' +project(':react-native-image-crop-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-crop-picker/android') +include ':nodejs-mobile-react-native' +project(':nodejs-mobile-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/nodejs-mobile-react-native/android') +include ':react-native-dialogs' +project(':react-native-dialogs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-dialogs/android') +include ':react-native-vector-icons' +project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') +include ':react-native-os-staltz' +project(':react-native-os-staltz').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-os-staltz/android') +include ':react-native-randombytes' +project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android') +include ':react-native-navigation' +project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/lib/android/app/') +include ':react-native-android-local-notification' +project(':react-native-android-local-notification').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-android-local-notification/android') +include ':react-native-android-wifi' +project(':react-native-android-wifi').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-android-wifi/android') +include ':react-native-has-internet' +project(':react-native-has-internet').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-has-internet/android') +include ':react-native-flag-secure-android' +project(':react-native-flag-secure-android').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-flag-secure-android/android') +include ':react-native-orientation-locker', ':app' +project(':react-native-orientation-locker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation-locker/android') +include ':react-native-fs' +project(':react-native-fs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fs/android') +include ':react-native-splash-screen' +project(':react-native-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-screen/android') +include ':@react-native-community_viewpager' +project(':@react-native-community_viewpager').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/viewpager/android') + +include ':app' diff --git a/tests/source-files/se.manyver/app.json b/tests/source-files/se.manyver/app.json new file mode 100644 index 00000000..8931f1dd --- /dev/null +++ b/tests/source-files/se.manyver/app.json @@ -0,0 +1,4 @@ +{ + "name": "Manyverse", + "displayName": "Manyverse" +} diff --git a/tests/source-files/se.manyver/index.android.js b/tests/source-files/se.manyver/index.android.js new file mode 100644 index 00000000..aac66bea --- /dev/null +++ b/tests/source-files/se.manyver/index.android.js @@ -0,0 +1,17 @@ +/* Copyright (C) 2018-2019 The Manyverse Authors. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import 'react-native-ssb-shims'; +import {run} from 'cycle-native-navigation'; +import { + screens, + drivers, + welcomeLayout, + defaultNavOptions, +} from './lib/frontend/index'; +// import './snoopy'; // Log and debug the React Native JS<-->Native Bridge + +run(screens, drivers, welcomeLayout, defaultNavOptions); diff --git a/tests/source-files/se.manyver/package.json b/tests/source-files/se.manyver/package.json new file mode 100644 index 00000000..08af1994 --- /dev/null +++ b/tests/source-files/se.manyver/package.json @@ -0,0 +1,135 @@ +{ + "name": "manyverse", + "version": "0.1911.27-beta", + "private": true, + "scripts": { + "postinstall": "patch-package", + "lib": "tsc", + "clean-bundler": "watchman watch-del-all && rm -rf $TMPDIR/react-*", + "clean-android": "adb uninstall se.manyver && cd android && ./gradlew clean", + "full-clean": "npm run clean-android && npm run clean-bundler && rm -rf node_modules && rm -rf lib", + "propagate-replacements": "propagate-replacement-fields --field=react-native", + "build-backend": "./tools/build-backend && ./tools/minify-backend", + "build-android-assets": "npm run lib && npm run propagate-replacements && npm run build-backend", + "build-android-debug": "npm run build-android-assets && react-native run-android --variant=indieDebug", + "build-android-release": "npm run build-android-assets && cd android && ./gradlew assembleRelease && cd ..", + "start": "npm run lib && npm run propagate-replacements && react-native start", + "psdr": "./tools/print-service-desk-report.js", + "test-e2e-android": "./tools/test-e2e-android", + "changelog": "npm run update-repo-changelog && npm run update-dat-latest-readme", + "update-repo-changelog": "./tools/update-repo-changelog.js", + "update-dat-latest-readme": "./tools/update-dat-latest-readme.js", + "echo-ssb-post": "./tools/echo-ssb-post.js", + "update-version": "./tools/update-version.js", + "dat-release": "./tools/dat-release", + "commit-release": "./tools/commit-release", + "release": "npm run update-version && npm run clean-bundler && npm run clean-android && npm run build-android-release && npm run test-e2e-android && npm run changelog && npm run commit-release && npm run dat-release && npm run echo-ssb-post" + }, + "dependencies": { + "@cycle/isolate": "5.1.0", + "@cycle/react": "2.6.0", + "@cycle/run": "5.3.0", + "@cycle/state": "1.3.0", + "@react-native-community/viewpager": "3.1.0", + "@types/node": "~12.7.5", + "@types/react": "16.9.x", + "@types/react-native": "0.60.23", + "@types/react-native-vector-icons": "6.4.3", + "buffer": "5.4.3", + "color-hash": "1.0.3", + "cycle-native-alert": "1.1.0", + "cycle-native-android-local-notification": "1.1.0", + "cycle-native-asyncstorage": "2.0.0", + "cycle-native-clipboard": "1.0.0", + "cycle-native-keyboard": "1.2.0", + "cycle-native-linking": "1.1.0", + "cycle-native-navigation": "6.1.0", + "cycle-native-share": "1.1.0", + "cycle-native-toastandroid": "1.1.0", + "mdast-normalize-react-native": "3.2.x", + "nodejs-mobile-react-native": "0.5.0", + "path": "~0.12.7", + "promisify-tuple": "1.0.0", + "pull-flat-list": "2.10.0", + "pull-pushable": "2.2.0", + "pull-stream": "3.6.14", + "pull-thenable": "1.0.0", + "react": "16.9.0", + "react-human-time": "^1.1.0", + "react-markdown": "4.0.2", + "react-native": "0.61.5", + "react-native-android-local-notification": "3.0.0", + "react-native-android-wifi": "0.0.41", + "react-native-bluetooth-socket-bridge": "1.2.0", + "react-native-bluetooth-status": "1.3.0", + "react-native-dialogs": "1.1.0", + "react-native-flag-secure-android": "1.0.2", + "react-native-floating-action": "1.19.1", + "react-native-fs": "~2.16.2", + "react-native-has-internet": "4.0.0", + "react-native-image-crop-picker": "~0.26.1", + "react-native-image-view": "~2.1.6", + "react-native-navigation": "4.0.2", + "react-native-orientation-locker": "1.1.7", + "react-native-popup-menu": "0.15.6", + "react-native-splash-screen": "^3.2.0", + "react-native-ssb-client": "7.0.0", + "react-native-ssb-shims": "4.6.0", + "react-native-swiper": "1.5.14", + "react-native-vector-icons": "6.6.0", + "react-propify-methods": "16.3.1", + "react-xstream-hoc": "1.0.0", + "remark": "~9.0.0", + "remark-gemoji-to-emoji": "1.1.0", + "remark-images-to-ssb-serve-blobs": "2.1.0-1", + "remark-linkify-regex": "1.0.0", + "remark-ssb-mentions": "~2.0.0", + "rn-viewpager": "1.2.9", + "ssb-cached-about": "~1.0.0", + "ssb-conn-query": "~0.4.4", + "ssb-ref": "2.13.9", + "ssb-room": "~1.1.1", + "ssb-serve-blobs": "2.1.0", + "ssb-threads": "3.6.0", + "ssb-typescript": "1.4.0", + "xstream": "11.11.0", + "xstream-backoff": "1.0", + "xstream-between": "1.0", + "xstream-from-callback": "1.0", + "xstream-from-pull-stream": "1.1", + "xstream-sample": "1.0" + }, + "devDependencies": { + "@babel/core": "~7.7.2", + "@babel/runtime": "~7.7.2", + "add-stream": "~1.0.0", + "conventional-changelog": "~3.1.15", + "husky": "^3.1.0", + "into-stream": "~5.1.1", + "jase": "1.2.0", + "left-pad": "1.3.0", + "metro-react-native-babel-preset": "^0.56.0", + "patch-package": "6.2.0", + "prettier": "~1.19.1", + "pretty-quick": "~2.0.1", + "propagate-replacement-fields": "1.2.0", + "react-native-version": "3.2.0", + "rn-snoopy": "2.0.2", + "tslint": "~5.20.1", + "typescript": "~3.7.2" + }, + "optionalDependencies": { + "appium": "1.14.0", + "tap-spec": "5.0.0", + "tape": "~4.9.1", + "wd": "1.11.3" + }, + "husky": { + "hooks": { + "pre-commit": "pretty-quick --staged --pattern \"**/*.*(ts|tsx|js|jsx)\"" + } + }, + "react-native": { + "os": "react-native-os-staltz" + } +} diff --git a/tests/source-files/se.manyver/react-native.config.js b/tests/source-files/se.manyver/react-native.config.js new file mode 100644 index 00000000..26adf2e4 --- /dev/null +++ b/tests/source-files/se.manyver/react-native.config.js @@ -0,0 +1,18 @@ +module.exports = { + dependencies: { + 'nodejs-mobile-react-native': { + // Ignored because we need to set this up manually in order to + // call some APIs of this library directly in our MainActivity.java + platforms: { + android: null, + }, + }, + 'react-native-bluetooth-socket-bridge': { + // This package needs some config passed as arguments to the constructor + // so we need to "link" it manually in MainApplication.java + platforms: { + android: null, + }, + }, + }, +}; diff --git a/tests/test-gradlew-fdroid b/tests/test-gradlew-fdroid new file mode 100755 index 00000000..d7f9884b --- /dev/null +++ b/tests/test-gradlew-fdroid @@ -0,0 +1,26 @@ +#!/bin/bash + +run_test() { + red='\033[0;31m' + green='\033[0;32m' + nocolor='\033[0m' + cd $basedir/tests/source-files/$1 + printf "\n${1}:\n" + if ($basedir/gradlew-fdroid 2>/dev/null || true) | grep -Fo "$2"; then + printf "${green}passed: $1\n" + else + printf "${red}ERROR: $2 not found in $1\n" + ((exit_value++)) + fi + printf $nocolor +} + +exit_value=0 +basedir=$(cd $(dirname $0)/..; pwd) +export https_proxy=127.7.7.7:7 # fake proxy to block downloading + +run_test osmandapp/osmand 2.2.1 +run_test com.integreight.onesheeld 3.3 +run_test se.manyver/android 5.5 + +exit $exit_value From 9ae41cc1fffd0ae8f7c2ce6988172f040abdc0ba Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 23 Dec 2019 02:02:28 +0100 Subject: [PATCH 0234/2775] add support for gradle kotlin scripts https://guides.gradle.org/migrating-build-logic-from-groovy-to-kotlin/ Closes fdroid/fdroidserver#613 cherry-picked from Bubu/fdroidserver@7d2e9f9c --- fdroidserver/build.py | 2 +- fdroidserver/checkupdates.py | 2 +- fdroidserver/common.py | 21 ++++++++++++++++----- fdroidserver/import.py | 3 ++- gradlew-fdroid | 2 +- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index a03fb2f3..6d8a1ce8 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -468,7 +468,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext if f in files: os.remove(os.path.join(root, f)) - if any(f in files for f in ['build.gradle', 'settings.gradle']): + if any(f in files for f in ['build.gradle', 'build.gradle.kts', 'settings.gradle', 'settings.gradle.kts']): # Even when running clean, gradle stores task/artifact caches in # .gradle/ as binary files. To avoid overcomplicating the scanner, # manually delete them, just like `gradle clean` should have removed diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 871ec98c..881f9f48 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -334,7 +334,7 @@ def try_init_submodules(app, last_build, vcs): def dirs_with_manifest(startdir): for root, dirs, files in os.walk(startdir): if any(m in files for m in [ - 'AndroidManifest.xml', 'pom.xml', 'build.gradle']): + 'AndroidManifest.xml', 'pom.xml', 'build.gradle', 'build.gradle.kts']): yield root diff --git a/fdroidserver/common.py b/fdroidserver/common.py index d94c995b..4fe72fdf 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1301,7 +1301,8 @@ def manifest_paths(app_dir, flavours): [os.path.join(app_dir, 'AndroidManifest.xml'), os.path.join(app_dir, 'src', 'main', 'AndroidManifest.xml'), os.path.join(app_dir, 'src', 'AndroidManifest.xml'), - os.path.join(app_dir, 'build.gradle')] + os.path.join(app_dir, 'build.gradle'), + os.path.join(app_dir, 'build.gradle.kts')] for flavour in flavours: if flavour == 'yes': @@ -1788,9 +1789,15 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= if build.target: n = build.target.split('-')[1] + build_gradle = os.path.join(root_dir, "build.gradle") + build_gradle_kts = build_gradle + ".kts" + if os.path.exists(build_gradle): + gradlefile = build_gradle + elif os.path.exist(build_gradle_kts): + gradlefile = build_gradle_kts regsub_file(r'compileSdkVersion[ =]+[0-9]+', r'compileSdkVersion %s' % n, - os.path.join(root_dir, 'build.gradle')) + gradlefile) # Remove forced debuggable flags remove_debuggable_flags(root_dir) @@ -2381,9 +2388,13 @@ gradle_line_matches = [ def remove_signing_keys(build_dir): for root, dirs, files in os.walk(build_dir): + gradlefile = None if 'build.gradle' in files: - path = os.path.join(root, 'build.gradle') - + gradlefile = "build.gradle" + elif 'build.gradle.kts' in files: + gradlefile = "build.gradle.kts" + if gradlefile: + path = os.path.join(root, gradlefile) with open(path, "r") as o: lines = o.readlines() @@ -2421,7 +2432,7 @@ def remove_signing_keys(build_dir): o.write(line) if changed: - logging.info("Cleaned build.gradle of keysigning configs at %s" % path) + logging.info("Cleaned %s of keysigning configs at %s" % (gradlefile, path)) for propfile in [ 'project.properties', diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 1fbf9a5f..e1d6ceda 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -299,7 +299,8 @@ def main(): app.Categories = options.categories.split(',') if os.path.exists(os.path.join(subdir, 'jni')): build.buildjni = ['yes'] - if os.path.exists(os.path.join(subdir, 'build.gradle')): + if os.path.exists(os.path.join(subdir, 'build.gradle')) \ + or os.path.exists(os.path.join(subdir, 'build.gradle')): build.gradle = ['yes'] package_json = os.path.join(build_dir, 'package.json') # react-native diff --git a/gradlew-fdroid b/gradlew-fdroid index c2f8955e..c42f1db0 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -174,7 +174,7 @@ if [[ -n $wrapper_ver ]]; then fi # Earliest takes priority -for f in {.,..}/build.gradle; do +for f in {.,..}/build.gradle{,.kts}; do [[ -f $f ]] || continue while IFS='' read -r line || [ -n "$line" ]; do if [[ -z "$plugin_pver" && $line == *'com.android.tools.build:gradle:'* ]]; then From 68b793e3082fcccf6c122c763a5b3c2841307752 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 13 Feb 2020 09:54:55 +0100 Subject: [PATCH 0235/2775] support kotlin "*.gradle.kts" files in more places closes #613 --- fdroidserver/common.py | 2 +- fdroidserver/import.py | 2 +- fdroidserver/update.py | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 4fe72fdf..9695e557 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1421,7 +1421,7 @@ def parse_androidmanifests(paths, app): if app.builds and 'gradle' in app.builds[-1] and app.builds[-1].gradle: flavour = app.builds[-1].gradle[-1] - if has_extension(path, 'gradle'): + if path.endswith('.gradle') or path.endswith('.gradle.kts'): with open(path, 'r') as f: android_plugin_file = False inside_flavour_group = 0 diff --git a/fdroidserver/import.py b/fdroidserver/import.py index e1d6ceda..44d6ec32 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -243,7 +243,7 @@ def main(): app.RepoType = 'git' app.UpdateCheckMode = "Tags" - if os.path.exists('build.gradle'): + if os.path.exists('build.gradle') or os.path.exists('build.gradle.kts'): build.gradle = ['yes'] import git diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 44d4b8c0..ae4a4bfa 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -825,9 +825,10 @@ def copy_triple_t_store_metadata(apps): setting_gradle_pattern = re.compile(r"""\s*include\s+["']:([^"']+)["'](?:,[\n\s]*["']:([^"']+)["'])*""") for packageName, app in apps.items(): - settings_gradle = os.path.join('build', packageName, 'settings.gradle') gradle_subdirs = set() - if os.path.exists(settings_gradle): + sg_list = glob.glob(os.path.join('build', packageName, 'settings.gradle*')) + if sg_list: + settings_gradle = sg_list[0] with open(settings_gradle) as fp: data = fp.read() for matches in setting_gradle_pattern.findall(data): From 271b74af7d506d154409cc28513e3d3718e0c9a2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 13 Feb 2020 22:28:39 +0100 Subject: [PATCH 0236/2775] fix remove_signing_keys() for Kotlin gradles files (*.gradle.kts) --- fdroidserver/common.py | 2 +- tests/common.TestCase | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 9695e557..a3e5108f 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2380,7 +2380,7 @@ def FDroidPopen(commands, cwd=None, envs=None, output=True, stderr_to_stdout=Tru gradle_comment = re.compile(r'[ ]*//') gradle_signing_configs = re.compile(r'^[\t ]*signingConfigs[ \t]*{[ \t]*$') gradle_line_matches = [ - re.compile(r'^[\t ]*signingConfig [^ ]*$'), + re.compile(r'^[\t ]*signingConfig\s*[= ]\s*[^ ]*$'), re.compile(r'.*android\.signingConfigs\.[^{]*$'), re.compile(r'.*release\.signingConfig *= *'), ] diff --git a/tests/common.TestCase b/tests/common.TestCase index e003d161..799455f0 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -992,6 +992,7 @@ class CommonTest(unittest.TestCase): 'source-files/info.guardianproject.ripple/build.gradle', 'source-files/open-keychain/open-keychain/build.gradle', 'source-files/open-keychain/open-keychain/OpenKeychain/build.gradle', + 'source-files/org.tasks/app/build.gradle.kts', 'source-files/osmandapp/osmand/build.gradle', 'source-files/ut.ewh.audiometrytest/app/build.gradle', ] From 32a29b33041cc5ee3eb5ae6eae4474f1819250d1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 17 Feb 2020 17:05:46 +0100 Subject: [PATCH 0237/2775] import: get git commit ID from git repo, e.g. master instead of '?' --- fdroidserver/import.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 44d6ec32..b028f27e 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -18,6 +18,7 @@ # along with this program. If not, see . import binascii +import git import glob import json import os @@ -241,32 +242,33 @@ def main(): app = metadata.App() app.AutoName = os.path.basename(os.getcwd()) app.RepoType = 'git' - app.UpdateCheckMode = "Tags" if os.path.exists('build.gradle') or os.path.exists('build.gradle.kts'): build.gradle = ['yes'] - import git - repo = git.repo.Repo(os.getcwd()) # git repo - for remote in git.Remote.iter_items(repo): + git_repo = git.repo.Repo(os.getcwd()) + for remote in git.Remote.iter_items(git_repo): if remote.name == 'origin': - url = repo.remotes.origin.url + url = git_repo.remotes.origin.url if url.startswith('https://git'): # github, gitlab app.SourceCode = url.rstrip('.git') app.Repo = url break - # repo.head.commit.binsha is a bytearray stored in a str - build.commit = binascii.hexlify(bytearray(repo.head.commit.binsha)) write_local_file = True elif options.url: app = get_app_from_url(options.url) build_dir = clone_to_tmp_dir(app) - build.commit = '?' + git_repo = git.repo.Repo(tmp_importer_dir) build.disable = 'Generated by import.py - check/set version fields and commit id' write_local_file = False else: raise FDroidException("Specify project url.") + app.UpdateCheckMode = 'Tags' + + # repo.head.commit.binsha is a bytearray stored in a str + build.commit = binascii.hexlify(bytearray(git_repo.head.commit.binsha)).decode() + # Extract some information... paths = get_all_gradle_and_manifests(build_dir) subdir = get_gradle_subdir(build_dir, paths) From 202602937d04179a417ff252c603946065fa520a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 17 Feb 2020 17:09:42 +0100 Subject: [PATCH 0238/2775] import: ignore results if build/appid dir already exists --- fdroidserver/import.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index b028f27e..68520881 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -24,6 +24,7 @@ import json import os import re import shutil +import sys import urllib.parse import urllib.request import yaml @@ -231,7 +232,7 @@ def main(): apps = metadata.read_metadata() app = None - build_dir = None + tmp_importer_dir = None local_metadata_files = common.get_local_metadata_files() if local_metadata_files != []: @@ -257,7 +258,7 @@ def main(): write_local_file = True elif options.url: app = get_app_from_url(options.url) - build_dir = clone_to_tmp_dir(app) + tmp_importer_dir = clone_to_tmp_dir(app) git_repo = git.repo.Repo(tmp_importer_dir) build.disable = 'Generated by import.py - check/set version fields and commit id' write_local_file = False @@ -270,8 +271,8 @@ def main(): build.commit = binascii.hexlify(bytearray(git_repo.head.commit.binsha)).decode() # Extract some information... - paths = get_all_gradle_and_manifests(build_dir) - subdir = get_gradle_subdir(build_dir, paths) + paths = get_all_gradle_and_manifests(tmp_importer_dir) + subdir = get_gradle_subdir(tmp_importer_dir, paths) if paths: versionName, versionCode, package = common.parse_androidmanifests(paths, app) if not package: @@ -305,8 +306,8 @@ def main(): or os.path.exists(os.path.join(subdir, 'build.gradle')): build.gradle = ['yes'] - package_json = os.path.join(build_dir, 'package.json') # react-native - pubspec_yaml = os.path.join(build_dir, 'pubspec.yaml') # flutter + package_json = os.path.join(tmp_importer_dir, 'package.json') # react-native + pubspec_yaml = os.path.join(tmp_importer_dir, 'pubspec.yaml') # flutter if os.path.exists(package_json): build.sudo = ['apt-get install npm', 'npm install -g react-native-cli'] build.init = ['npm install'] @@ -316,7 +317,7 @@ def main(): app.License = data.get('license', app.License) app.Description = data.get('description', app.Description) app.WebSite = data.get('homepage', app.WebSite) - app_json = os.path.join(build_dir, 'app.json') + app_json = os.path.join(tmp_importer_dir, 'app.json') if os.path.exists(app_json): with open(app_json) as fp: data = json.load(fp) @@ -345,8 +346,13 @@ def main(): # Keep the repo directory to save bandwidth... if not os.path.exists('build'): os.mkdir('build') - if build_dir is not None: - shutil.move(build_dir, os.path.join('build', package)) + build_dir = os.path.join('build', package) + if os.path.exists(build_dir): + logging.warning(_('{path} already exists, ignoring import results!') + .format(path=build_dir)) + sys.exit(1) + elif tmp_importer_dir is not None: + shutil.move(tmp_importer_dir, build_dir) with open('build/.fdroidvcs-' + package, 'w') as f: f.write(app.RepoType + ' ' + app.Repo) From fafaa8f81f76564dc4491c68a65bb51f1dec063c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 14 Feb 2020 08:48:30 +0100 Subject: [PATCH 0239/2775] standardize on path.endswith() for file extension checks Its already widely used, this just removes the exceptions. It is also more Pythonic --- fdroidserver/common.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index a3e5108f..ccd65f5a 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -587,17 +587,13 @@ def read_app_args(appid_versionCode_pairs, allapps, allow_vercodes=False): def get_extension(filename): + """get name and extension of filename, with extension always lower case""" base, ext = os.path.splitext(filename) if not ext: return base, '' return base, ext.lower()[1:] -def has_extension(filename, ext): - _ignored, f_ext = get_extension(filename) - return ext == f_ext - - publish_name_regex = re.compile(r"^(.+)_([0-9]+)\.(apk|zip)$") @@ -1316,7 +1312,7 @@ def manifest_paths(app_dir, flavours): def fetch_real_name(app_dir, flavours): '''Retrieve the package name. Returns the name, or None if not found.''' for path in manifest_paths(app_dir, flavours): - if not has_extension(path, 'xml') or not os.path.isfile(path): + if not path.endswith('.xml') or not os.path.isfile(path): continue logging.debug("fetch_real_name: Checking manifest at " + path) xml = parse_xml(path) @@ -1808,11 +1804,11 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= for path in manifest_paths(root_dir, flavours): if not os.path.isfile(path): continue - if has_extension(path, 'xml'): + if path.endswith('.xml'): regsub_file(r'android:versionName="[^"]*"', r'android:versionName="%s"' % build.versionName, path) - elif has_extension(path, 'gradle'): + elif path.endswith('.gradle'): regsub_file(r"""(\s*)versionName[\s'"=]+.*""", r"""\1versionName '%s'""" % build.versionName, path) @@ -1822,11 +1818,11 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= for path in manifest_paths(root_dir, flavours): if not os.path.isfile(path): continue - if has_extension(path, 'xml'): + if path.endswith('.xml'): regsub_file(r'android:versionCode="[^"]*"', r'android:versionCode="%s"' % build.versionCode, path) - elif has_extension(path, 'gradle'): + elif path.endswith('.gradle'): regsub_file(r'versionCode[ =]+[0-9]+', r'versionCode %s' % build.versionCode, path) From 5459a461dbfd7f894c22cc571b4bbf31c268e7d0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 10:36:28 +0100 Subject: [PATCH 0240/2775] common.get_head_commit_id() to get string commit ID from HEAD --- fdroidserver/common.py | 8 ++++++++ fdroidserver/import.py | 5 +---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index ccd65f5a..7fffabb0 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -670,6 +670,14 @@ def get_build_dir(app): return os.path.join('build', app.id) +def get_head_commit_id(git_repo): + """Get git commit ID for HEAD as a str + + repo.head.commit.binsha is a bytearray stored in a str + """ + return hexlify(bytearray(git_repo.head.commit.binsha)).decode() + + def setup_vcs(app): '''checkout code from VCS and return instance of vcs and the build dir''' build_dir = get_build_dir(app) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 68520881..42ba55e3 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import binascii import git import glob import json @@ -266,9 +265,7 @@ def main(): raise FDroidException("Specify project url.") app.UpdateCheckMode = 'Tags' - - # repo.head.commit.binsha is a bytearray stored in a str - build.commit = binascii.hexlify(bytearray(git_repo.head.commit.binsha)).decode() + build.commit = common.get_head_commit_id(git_repo) # Extract some information... paths = get_all_gradle_and_manifests(tmp_importer_dir) From d16478b10bda2c1440023593cfe43775a907c30d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 12:41:12 +0100 Subject: [PATCH 0241/2775] update: write status in JSON repo file, using new internal API --- fdroidserver/common.py | 48 +++++++++++++++++++++++++++++++++++++- fdroidserver/update.py | 52 ++++++++++++++++++++++++++++++++++++++++++ fdroidserver/verify.py | 9 +------- 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 7fffabb0..62f0187d 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -20,6 +20,7 @@ # common.py is imported by all modules, so do not import third-party # libraries here as they will become a requirement for all commands. +import git import io import os import sys @@ -47,7 +48,7 @@ except ImportError: import xml.etree.ElementTree as XMLElementTree # nosec this is a fallback only from binascii import hexlify -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from distutils.version import LooseVersion from queue import Queue from zipfile import ZipFile @@ -670,6 +671,51 @@ def get_build_dir(app): return os.path.join('build', app.id) +class Encoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, set): + return sorted(obj) + return super().default(obj) + + +def setup_status_output(start_timestamp): + """Create the common output dictionary for public status updates""" + output = { + 'commandLine': sys.argv, + 'startTimestamp': int(time.mktime(start_timestamp) * 1000), + 'subcommand': sys.argv[0].split()[1], + } + if os.path.isdir('.git'): + git_repo = git.repo.Repo(os.getcwd()) + output['fdroiddata'] = { + 'commitId': get_head_commit_id(git_repo), + 'isDirty': git_repo.is_dirty(), + } + fdroidserver_dir = os.path.dirname(sys.argv[0]) + if os.path.isdir(os.path.join(fdroidserver_dir, '.git')): + git_repo = git.repo.Repo(fdroidserver_dir) + output['fdroidserver'] = { + 'commitId': get_head_commit_id(git_repo), + 'isDirty': git_repo.is_dirty(), + } + return output + + +def write_status_json(output, pretty=False): + """Write status out as JSON, and rsync it to the repo server""" + + subcommand = sys.argv[0].split()[1] + status_dir = os.path.join('repo', 'status') + if not os.path.exists(status_dir): + os.mkdir(status_dir) + output['endTimestamp'] = int(datetime.now(timezone.utc).timestamp() * 1000) + with open(os.path.join(status_dir, subcommand + '.json'), 'w') as fp: + if pretty: + json.dump(output, fp, sort_keys=True, cls=Encoder, indent=2) + else: + json.dump(output, fp, sort_keys=True, cls=Encoder, separators=(',', ':')) + + def get_head_commit_id(git_repo): """Get git commit ID for HEAD as a str diff --git a/fdroidserver/update.py b/fdroidserver/update.py index ae4a4bfa..13947570 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -121,6 +121,57 @@ def disabled_algorithms_allowed(): return options.allow_disabled_algorithms or config['allow_disabled_algorithms'] +def status_update_json(apps, sortedids, apks): + """Output a JSON file with metadata about this `fdroid update` run + + :param apps: fully populated list of all applications + :param apks: all to be published apks + + """ + + logging.debug(_('Outputting JSON')) + output = common.setup_status_output(start_timestamp) + output['antiFeatures'] = dict() + output['disabled'] = [] + output['failedBuilds'] = dict() + output['noPackages'] = [] + + for appid in sortedids: + app = apps[appid] + for af in app.get('AntiFeatures', []): + antiFeatures = output['antiFeatures'] # JSON camelCase + if af not in antiFeatures: + antiFeatures[af] = dict() + if appid not in antiFeatures[af]: + antiFeatures[af]['apps'] = set() + antiFeatures[af]['apps'].add(appid) + + apklist = [] + for apk in apks: + if apk['packageName'] == appid: + apklist.append(apk) + builds = app.get('builds', []) + validapks = 0 + for build in builds: + if not build.get('disable'): + builtit = False + for apk in apklist: + if apk['versionCode'] == int(build.versionCode): + builtit = True + validapks += 1 + break + if not builtit: + failedBuilds = output['failedBuilds'] + if appid not in failedBuilds: + failedBuilds[appid] = [] + failedBuilds[appid].append(build.versionCode) + if validapks == 0: + output['noPackages'].append(appid) + if app.get('Disabled'): + output['disabled'].append(appid) + common.write_status_json(output, options.pretty) + + def update_wiki(apps, sortedids, apks): """Update the wiki @@ -2200,6 +2251,7 @@ def main(): # Update the wiki... if options.wiki: update_wiki(apps, sortedids, apks + archapks) + status_update_json(apps, sortedids, apks + archapks) logging.info(_("Finished")) diff --git a/fdroidserver/verify.py b/fdroidserver/verify.py index 8025b054..bd1433d2 100644 --- a/fdroidserver/verify.py +++ b/fdroidserver/verify.py @@ -64,13 +64,6 @@ class Decoder(json.JSONDecoder): return set(values), end -class Encoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, set): - return sorted(obj) - return super().default(obj) - - def write_json_report(url, remote_apk, unsigned_apk, compare_result): """write out the results of the verify run to JSON @@ -118,7 +111,7 @@ def write_json_report(url, remote_apk, unsigned_apk, compare_result): data['packages'][packageName] = set() data['packages'][packageName].add(output) with open(jsonfile, 'w') as fp: - json.dump(data, fp, cls=Encoder, sort_keys=True) + json.dump(data, fp, cls=common.Encoder, sort_keys=True) def main(): From e8a6d0f81314c6a6c276e1db16e232e818687320 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 12:48:43 +0100 Subject: [PATCH 0242/2775] checkupdates: write status JSON --- fdroidserver/checkupdates.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 881f9f48..52f1ceb4 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -543,6 +543,18 @@ def checkupdates_app(app): raise FDroidException("Git commit failed") +def status_update_json(processed, failed): + """Output a JSON file with metadata about this run""" + + logging.debug(_('Outputting JSON')) + output = common.setup_status_output(start_timestamp) + if processed: + output['processed'] = processed + if failed: + output['failed'] = failed + common.write_status_json(output) + + def update_wiki(gplaylog, locallog): if config.get('wiki_server') and config.get('wiki_path'): try: @@ -644,6 +656,8 @@ def main(): return locallog = '' + processed = [] + failed = dict() for appid, app in apps.items(): if options.autoonly and app.AutoUpdateMode in ('None', 'Static'): @@ -656,13 +670,15 @@ def main(): try: checkupdates_app(app) + processed.append(appid) except Exception as e: msg = _("...checkupdate failed for {appid} : {error}").format(appid=appid, error=e) logging.error(msg) locallog += msg + '\n' + failed[appid] = str(e) update_wiki(None, locallog) - + status_update_json(processed, failed) logging.info(_("Finished")) From 4bb590b6e5e34603b48229e1473618c2c18ee49d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 13:13:07 +0100 Subject: [PATCH 0243/2775] publish: write status JSON --- fdroidserver/publish.py | 27 +++++++++++++++++++++++++++ tests/publish.TestCase | 4 +++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index 1369d177..d69e3656 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -28,6 +28,7 @@ from collections import OrderedDict import logging from gettext import ngettext import json +import time import zipfile from . import _ @@ -38,6 +39,7 @@ from .exception import BuildException, FDroidException config = None options = None +start_timestamp = time.gmtime() def publish_source_tarball(apkfilename, unsigned_dir, output_dir): @@ -138,6 +140,20 @@ def store_stats_fdroid_signing_key_fingerprints(appids, indent=None): sign_sig_key_fingerprint_list(jar_file) +def status_update_json(newKeyAliases, generatedKeys, signedApks): + """Output a JSON file with metadata about this run""" + + logging.debug(_('Outputting JSON')) + output = common.setup_status_output(start_timestamp) + if newKeyAliases: + output['newKeyAliases'] = newKeyAliases + if generatedKeys: + output['generatedKeys'] = generatedKeys + if signedApks: + output['signedApks'] = signedApks + common.write_status_json(output) + + def main(): global config, options @@ -195,6 +211,9 @@ def main(): # collisions, and refuse to do any publishing if that's the case... allapps = metadata.read_metadata() vercodes = common.read_pkg_args(options.appid, True) + signed_apks = dict() + new_key_aliases = [] + generated_keys = dict() allaliases = [] for appid in allapps: m = hashlib.md5() # nosec just used to generate a keyalias @@ -314,6 +333,7 @@ def main(): m = hashlib.md5() # nosec just used to generate a keyalias m.update(appid.encode('utf-8')) keyalias = m.hexdigest()[:8] + new_key_aliases.append(keyalias) logging.info("Key alias: " + keyalias) # See if we already have a key for this application, and @@ -336,6 +356,9 @@ def main(): '-dname', config['keydname']], envs=env_vars) if p.returncode != 0: raise BuildException("Failed to generate key", p.output) + if appid not in generated_keys: + generated_keys[appid] = set() + generated_keys[appid].add(appid) signed_apk_path = os.path.join(output_dir, apkfilename) if os.path.exists(signed_apk_path): @@ -353,6 +376,9 @@ def main(): apkfile, keyalias], envs=env_vars) if p.returncode != 0: raise BuildException(_("Failed to sign application"), p.output) + if appid not in signed_apks: + signed_apks[appid] = [] + signed_apks[appid].append(apkfile) # Zipalign it... common._zipalign(apkfile, os.path.join(output_dir, apkfilename)) @@ -362,6 +388,7 @@ def main(): logging.info('Published ' + apkfilename) store_stats_fdroid_signing_key_fingerprints(allapps.keys()) + status_update_json(new_key_aliases, generated_keys, signed_apks) logging.info('published list signing-key fingerprints') diff --git a/tests/publish.TestCase b/tests/publish.TestCase index 2e658c1e..ac00d6d9 100755 --- a/tests/publish.TestCase +++ b/tests/publish.TestCase @@ -19,6 +19,7 @@ import sys import unittest import tempfile import textwrap +from unittest import mock localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) @@ -158,7 +159,8 @@ class PublishTest(unittest.TestCase): os.path.join(testdir, 'unsigned', 'binaries', 'com.politedroid_6.binary.apk')) os.chdir(testdir) - publish.main() + with mock.patch.object(sys, 'argv', ['fdroid fakesubcommand']): + publish.main() if __name__ == "__main__": From ddbdff83bde9d16eb14a1dd61a6b01bb73b03969 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 13:16:55 +0100 Subject: [PATCH 0244/2775] gpgsign: write status JSON --- fdroidserver/gpgsign.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fdroidserver/gpgsign.py b/fdroidserver/gpgsign.py index b942a21b..a224c3f7 100644 --- a/fdroidserver/gpgsign.py +++ b/fdroidserver/gpgsign.py @@ -20,6 +20,7 @@ import os import glob from argparse import ArgumentParser import logging +import time from . import _ from . import common @@ -28,6 +29,17 @@ from .exception import FDroidException config = None options = None +start_timestamp = time.gmtime() + + +def status_update_json(signed): + """Output a JSON file with metadata about this run""" + + logging.debug(_('Outputting JSON')) + output = common.setup_status_output(start_timestamp) + if signed: + output['signed'] = signed + common.write_status_json(output) def main(): @@ -45,6 +57,7 @@ def main(): if config['archive_older'] != 0: repodirs.append('archive') + signed = [] for output_dir in repodirs: if not os.path.isdir(output_dir): raise FDroidException(_("Missing output directory") + " '" + output_dir + "'") @@ -72,7 +85,9 @@ def main(): if p.returncode != 0: raise FDroidException("Signing failed.") + signed.append(filename) logging.info('Signed ' + filename) + status_update_json(signed) if __name__ == "__main__": From c965e7d969403c394cc67f141a569a523dc573d6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 13:27:38 +0100 Subject: [PATCH 0245/2775] deploy: write status JSON --- fdroidserver/server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index d00dd2da..c01c1f26 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -809,6 +809,7 @@ def main(): if config.get('wiki_server') and config.get('wiki_path'): update_wiki() + common.write_status_json(common.setup_status_output(start_timestamp)) sys.exit(0) From 55935d9a41d569754076fa7ed4ac053f412d1d41 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 13:29:21 +0100 Subject: [PATCH 0246/2775] signindex: write status JSON --- fdroidserver/signindex.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/fdroidserver/signindex.py b/fdroidserver/signindex.py index cbd55239..1f02d0f9 100644 --- a/fdroidserver/signindex.py +++ b/fdroidserver/signindex.py @@ -17,6 +17,7 @@ # along with this program. If not, see . import os +import time import zipfile from argparse import ArgumentParser import logging @@ -27,6 +28,7 @@ from .exception import FDroidException config = None options = None +start_timestamp = time.gmtime() def sign_jar(jar): @@ -75,6 +77,16 @@ def sign_index_v1(repodir, json_name): sign_jar(jar_file) +def status_update_json(signed): + """Output a JSON file with metadata about this run""" + + logging.debug(_('Outputting JSON')) + output = common.setup_status_output(start_timestamp) + if signed: + output['signed'] = signed + common.write_status_json(output) + + def main(): global config, options @@ -94,7 +106,7 @@ def main(): if config['archive_older'] != 0: repodirs.append('archive') - signed = 0 + signed = [] for output_dir in repodirs: if not os.path.isdir(output_dir): raise FDroidException("Missing output directory '" + output_dir + "'") @@ -102,9 +114,10 @@ def main(): unsigned = os.path.join(output_dir, 'index_unsigned.jar') if os.path.exists(unsigned): sign_jar(unsigned) - os.rename(unsigned, os.path.join(output_dir, 'index.jar')) + index_jar = os.path.join(output_dir, 'index.jar') + os.rename(unsigned, index_jar) logging.info('Signed index in ' + output_dir) - signed += 1 + signed.append(index_jar) json_name = 'index-v1.json' index_file = os.path.join(output_dir, json_name) @@ -112,10 +125,11 @@ def main(): sign_index_v1(output_dir, json_name) os.remove(index_file) logging.info('Signed ' + index_file) - signed += 1 + signed.append(index_file) - if signed == 0: + if not signed: logging.info(_("Nothing to do")) + status_update_json(signed) if __name__ == "__main__": From c19ef45fd5c8025e6e3cd68647611764564a20c2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 23:16:18 +0100 Subject: [PATCH 0247/2775] build: write status JSON --- fdroidserver/build.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 6d8a1ce8..733af34a 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -83,6 +83,7 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): buildserverid = subprocess.check_output(['vagrant', 'ssh', '-c', 'cat /home/vagrant/buildserverid'], cwd='builder').strip().decode() + status_output['buildserverid'] = buildserverid logging.debug(_('Fetched buildserverid from VM: {buildserverid}') .format(buildserverid=buildserverid)) except Exception as e: @@ -912,6 +913,7 @@ config = None buildserverid = None fdroidserverid = None start_timestamp = time.gmtime() +status_output = None timeout_event = threading.Event() @@ -978,6 +980,8 @@ def main(): else: also_check_dir = None + status_output = common.setup_status_output(start_timestamp) + repo_dir = 'repo' build_dir = 'build' @@ -1029,6 +1033,8 @@ def main(): # Build applications... failed_apps = {} build_succeeded = [] + status_output['failedBuilds'] = failed_apps + status_output['successfulBuilds'] = build_succeeded # Only build for 36 hours, then stop gracefully. endtime = time.time() + 36 * 60 * 60 max_build_time_reached = False @@ -1201,10 +1207,12 @@ def main(): except Exception as e: logging.error("Error while attempting to publish build log: %s" % e) + common.write_running_status_json(status_output) if timer: timer.cancel() # kill the watchdog timer if max_build_time_reached: + status_output['maxBuildTimeReached'] = True logging.info("Stopping after global build timeout...") break @@ -1263,6 +1271,8 @@ def main(): newpage = site.Pages['build'] newpage.save('#REDIRECT [[' + wiki_page_path + ']]', summary='Update redirect') + common.write_status_json(status_output, options.pretty) + # hack to ensure this exits, even is some threads are still running common.force_exit() From bf6004b08ee3080c1f0c6e3c3dd00f077f03adf3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 15:21:52 +0100 Subject: [PATCH 0248/2775] rsync status JSON as first and last steps of command runs --- examples/config.py | 12 +++++++---- fdroidserver/common.py | 48 ++++++++++++++++++++++++++---------------- jenkins-test | 2 ++ 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/examples/config.py b/examples/config.py index 1ed0de51..e46116db 100644 --- a/examples/config.py +++ b/examples/config.py @@ -173,10 +173,14 @@ The repository of older versions of applications from the main demo repository. # 'bar.info:/var/www/fdroid', # } -# Uncomment this option if you want to logs of builds and other processes to -# your repository server(s). Logs get published to all servers configured in -# 'serverwebroot'. The name scheme is: .../repo/$APPID_$VERCODE.log.gz -# Only logs from build-jobs running inside a buildserver VM are supported. +# When running fdroid processes on a remote server, it is possible to +# publish extra information about the status. Each fdroid sub-command +# can create repo/status/running.json when it starts, then a +# repo/status/.json when it completes. The builds logs +# and other processes will also get published, if they are running in +# a buildserver VM. The build logs name scheme is: +# .../repo/$APPID_$VERCODE.log.gz. These files are also pushed to all +# servers configured in 'serverwebroot'. # # deploy_process_logs = True diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 62f0187d..3697fec4 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -698,22 +698,29 @@ def setup_status_output(start_timestamp): 'commitId': get_head_commit_id(git_repo), 'isDirty': git_repo.is_dirty(), } + write_running_status_json(output) return output -def write_status_json(output, pretty=False): - """Write status out as JSON, and rsync it to the repo server""" +def write_running_status_json(output): + write_status_json(output, pretty=True, name='running') - subcommand = sys.argv[0].split()[1] + +def write_status_json(output, pretty=False, name=None): + """Write status out as JSON, and rsync it to the repo server""" status_dir = os.path.join('repo', 'status') if not os.path.exists(status_dir): os.mkdir(status_dir) - output['endTimestamp'] = int(datetime.now(timezone.utc).timestamp() * 1000) - with open(os.path.join(status_dir, subcommand + '.json'), 'w') as fp: + if not name: + output['endTimestamp'] = int(datetime.now(timezone.utc).timestamp() * 1000) + name = sys.argv[0].split()[1] # fdroid subcommand + path = os.path.join(status_dir, name + '.json') + with open(path, 'w') as fp: if pretty: json.dump(output, fp, sort_keys=True, cls=Encoder, indent=2) else: json.dump(output, fp, sort_keys=True, cls=Encoder, separators=(',', ':')) + rsync_status_file_to_repo(path, repo_subdir='status') def get_head_commit_id(git_repo): @@ -3350,11 +3357,6 @@ def deploy_build_log_with_rsync(appid, vercode, log_content): be decoded as 'utf-8') """ - # check if deploying logs is enabled in config - if not config.get('deploy_process_logs', False): - logging.debug(_('skip deploying full build logs: not enabled in config')) - return - if not log_content: logging.warning(_('skip deploying full build logs: log content is empty')) return @@ -3372,13 +3374,17 @@ def deploy_build_log_with_rsync(appid, vercode, log_content): f.write(bytes(log_content, 'utf-8')) else: f.write(log_content) + rsync_status_file_to_repo(log_gz_path) - # TODO: sign compressed log file, if a signing key is configured + +def rsync_status_file_to_repo(path, repo_subdir=None): + """Copy a build log or status JSON to the repo using rsync""" + + if not config.get('deploy_process_logs', False): + logging.debug(_('skip deploying full build logs: not enabled in config')) + return for webroot in config.get('serverwebroot', []): - dest_path = os.path.join(webroot, "repo") - if not dest_path.endswith('/'): - dest_path += '/' # make sure rsync knows this is a directory cmd = ['rsync', '--archive', '--delete-after', @@ -3389,15 +3395,21 @@ def deploy_build_log_with_rsync(appid, vercode, log_content): cmd += ['--quiet'] if 'identity_file' in config: cmd += ['-e', 'ssh -oBatchMode=yes -oIdentitiesOnly=yes -i ' + config['identity_file']] - cmd += [log_gz_path, dest_path] - # TODO: also deploy signature file if present + dest_path = os.path.join(webroot, "repo") + if repo_subdir is not None: + dest_path = os.path.join(dest_path, repo_subdir) + if not dest_path.endswith('/'): + dest_path += '/' # make sure rsync knows this is a directory + cmd += [path, dest_path] retcode = subprocess.call(cmd) if retcode: - logging.warning(_("failed deploying build logs to '{path}'").format(path=webroot)) + logging.error(_('process log deploy {path} to {dest} failed!') + .format(path=path, dest=webroot)) else: - logging.info(_("deployed build logs to '{path}'").format(path=webroot)) + logging.debug(_('deployed process log {path} to {dest}') + .format(path=path, dest=webroot)) def get_per_app_repos(): diff --git a/jenkins-test b/jenkins-test index d6ce9659..945d5d37 100755 --- a/jenkins-test +++ b/jenkins-test @@ -55,6 +55,7 @@ fi gpg --import $GNUPGHOME/secring.gpg echo "build_server_always = True" >> config.py +echo "deploy_process_logs = True" >> config.py echo "make_current_version_link = False" >> config.py echo "gpghome = '$GNUPGHOME'" >> config.py echo "gpgkey = 'CE71F7FB'" >> config.py @@ -66,6 +67,7 @@ test -d repo || mkdir repo test -d archive || mkdir archive # when everything is copied over to run on SIGN machine ../fdroid publish + ../fdroid gpgsign # when everything is copied over to run on BUILD machine, # which does not have a keyring, only a cached pubkey From 202291d66c197633e0691db9f5358f25617e4886 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Feb 2020 23:50:52 +0100 Subject: [PATCH 0249/2775] integration test for creating and deploying status JSON files ---------------------------- --- tests/common.TestCase | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/common.TestCase b/tests/common.TestCase index 799455f0..856b71e7 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -5,13 +5,16 @@ import difflib import glob import inspect +import json import logging import optparse import os import re import shutil +import subprocess import sys import tempfile +import time import unittest import textwrap import yaml @@ -1131,6 +1134,55 @@ class CommonTest(unittest.TestCase): with gzip.open(expected_log_path, 'r') as f: self.assertEqual(f.read(), mocklogcontent) + def test_deploy_status_json(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + + fakesubcommand = 'fakesubcommand' + fake_timestamp = 1234567890 + fakeserver = 'example.com:/var/www/fbot/' + expected_dir = os.path.join(testdir, fakeserver.replace(':', ''), 'repo', 'status') + + fdroidserver.common.options = mock.Mock() + fdroidserver.common.config = {} + fdroidserver.common.config['serverwebroot'] = [fakeserver] + fdroidserver.common.config['identity_file'] = 'ssh/id_rsa' + + def assert_subprocess_call(cmd): + dest_path = os.path.join(testdir, cmd[-1].replace(':', '')) + if not os.path.exists(dest_path): + os.makedirs(dest_path) + return subprocess.run(cmd[:-1] + [dest_path]).returncode + + with mock.patch('subprocess.call', side_effect=assert_subprocess_call): + with mock.patch.object(sys, 'argv', ['fdroid ' + fakesubcommand]): + output = fdroidserver.common.setup_status_output(time.localtime(fake_timestamp)) + self.assertFalse(os.path.exists(os.path.join(expected_dir, 'running.json'))) + with mock.patch.object(sys, 'argv', ['fdroid ' + fakesubcommand]): + fdroidserver.common.write_status_json(output) + self.assertFalse(os.path.exists(os.path.join(expected_dir, fakesubcommand + '.json'))) + + fdroidserver.common.config['deploy_process_logs'] = True + + output = fdroidserver.common.setup_status_output(time.localtime(fake_timestamp)) + expected_path = os.path.join(expected_dir, 'running.json') + self.assertTrue(os.path.isfile(expected_path)) + with open(expected_path) as fp: + data = json.load(fp) + self.assertEqual(fake_timestamp * 1000, data['startTimestamp']) + self.assertFalse('endTimestamp' in data) + + testvalue = 'asdfasd' + output['testvalue'] = testvalue + + fdroidserver.common.write_status_json(output) + expected_path = os.path.join(expected_dir, fakesubcommand + '.json') + self.assertTrue(os.path.isfile(expected_path)) + with open(expected_path) as fp: + data = json.load(fp) + self.assertEqual(fake_timestamp * 1000, data['startTimestamp']) + self.assertTrue('endTimestamp' in data) + self.assertEqual(testvalue, output.get('testvalue')) + def test_string_is_integer(self): self.assertTrue(fdroidserver.common.string_is_integer('0x10')) self.assertTrue(fdroidserver.common.string_is_integer('010')) From 21f5bd73a76bdf56c650e681fabc80a98b8d8a74 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 19 Feb 2020 20:18:18 +0100 Subject: [PATCH 0250/2775] build: fix logging failed builds to the status JSON (closes #741) --- fdroidserver/build.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 733af34a..d269e46d 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -324,6 +324,10 @@ def transform_first_char(string, method): return method(string[0]) + string[1:] +def add_failed_builds_entry(failed_builds, appid, build, entry): + failed_builds.append([appid, int(build.versionCode), str(entry)]) + + def get_metadata_from_apk(app, build, apkfile): """get the required metadata from the built APK @@ -1031,9 +1035,9 @@ def main(): site.login(config['wiki_user'], config['wiki_password']) # Build applications... - failed_apps = {} + failed_builds = [] build_succeeded = [] - status_output['failedBuilds'] = failed_apps + status_output['failedBuilds'] = failed_builds status_output['successfulBuilds'] = build_succeeded # Only build for 36 hours, then stop gracefully. endtime = time.time() + 36 * 60 * 60 @@ -1156,7 +1160,7 @@ def main(): if options.stop: logging.debug("Error encoutered, stopping by user request.") common.force_exit(1) - failed_apps[appid] = vcse + add_failed_builds_entry(failed_builds, appid, build, vcse) wikilog = str(vcse) except FDroidException as e: with open(os.path.join(log_dir, appid + '.log'), 'a+') as f: @@ -1171,7 +1175,7 @@ def main(): if options.stop: logging.debug("Error encoutered, stopping by user request.") common.force_exit(1) - failed_apps[appid] = e + add_failed_builds_entry(failed_builds, appid, build, e) wikilog = e.get_wikitext() except Exception as e: logging.error("Could not build app %s due to unknown error: %s" % ( @@ -1179,7 +1183,7 @@ def main(): if options.stop: logging.debug("Error encoutered, stopping by user request.") common.force_exit(1) - failed_apps[appid] = e + add_failed_builds_entry(failed_builds, appid, build, e) wikilog = str(e) if options.wiki and wikilog: @@ -1220,16 +1224,16 @@ def main(): logging.info("success: %s" % (app.id)) if not options.verbose: - for fa in failed_apps: - logging.info("Build for app %s failed:\n%s" % (fa, failed_apps[fa])) + for fb in failed_builds: + logging.info('Build for app {}:{} failed:\n{}'.format(*fb)) logging.info(_("Finished")) if len(build_succeeded) > 0: logging.info(ngettext("{} build succeeded", "{} builds succeeded", len(build_succeeded)).format(len(build_succeeded))) - if len(failed_apps) > 0: + if len(failed_builds) > 0: logging.info(ngettext("{} build failed", - "{} builds failed", len(failed_apps)).format(len(failed_apps))) + "{} builds failed", len(failed_builds)).format(len(failed_builds))) if options.wiki: wiki_page_path = 'build_' + time.strftime('%s', start_timestamp) @@ -1265,7 +1269,7 @@ def main(): if m: txt += "* guest RAM: %s MB\n" % m.group(1) txt += "* successful builds: %d\n" % len(build_succeeded) - txt += "* failed builds: %d\n" % len(failed_apps) + txt += "* failed builds: %d\n" % len(failed_builds) txt += "\n\n" newpage.save(txt, summary='Run log') newpage = site.Pages['build'] From b6e6ce87cb4cd80f7eb98f9f3d79644b41fb909b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 19 Feb 2020 20:19:14 +0100 Subject: [PATCH 0251/2775] build: has no pretty option (closes #742) --- fdroidserver/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index d269e46d..ebcdc861 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -1275,7 +1275,7 @@ def main(): newpage = site.Pages['build'] newpage.save('#REDIRECT [[' + wiki_page_path + ']]', summary='Update redirect') - common.write_status_json(status_output, options.pretty) + common.write_status_json(status_output) # hack to ensure this exits, even is some threads are still running common.force_exit() From b5bce9f17822ef7bf4f53797ea73d0d8bee96d56 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 20 Feb 2020 09:02:39 +0100 Subject: [PATCH 0252/2775] build: do not write/rsync status JSON when running --on-server !717 !716 --- fdroidserver/build.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index ebcdc861..dbcccde6 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -984,7 +984,10 @@ def main(): else: also_check_dir = None - status_output = common.setup_status_output(start_timestamp) + if options.onserver: + status_output = dict() # HACK dummy placeholder + else: + status_output = common.setup_status_output(start_timestamp) repo_dir = 'repo' @@ -1069,6 +1072,7 @@ def main(): tools_version_log = '' if not options.onserver: tools_version_log = common.get_android_tools_version_log(build.ndk_path()) + common.write_running_status_json(status_output) try: # For the first build of a particular app, we need to set up @@ -1211,7 +1215,6 @@ def main(): except Exception as e: logging.error("Error while attempting to publish build log: %s" % e) - common.write_running_status_json(status_output) if timer: timer.cancel() # kill the watchdog timer @@ -1275,7 +1278,8 @@ def main(): newpage = site.Pages['build'] newpage.save('#REDIRECT [[' + wiki_page_path + ']]', summary='Update redirect') - common.write_status_json(status_output) + if not options.onserver: + common.write_status_json(status_output) # hack to ensure this exits, even is some threads are still running common.force_exit() From ed46afe2621512c7a060070dbfbd982cb5b9ee53 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 20 Feb 2020 09:12:31 +0100 Subject: [PATCH 0253/2775] gitlab-ci: ensure git is installed for pip_install job --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 08af6e5c..73614d2a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -118,7 +118,7 @@ pip_install: only: - master@fdroid/fdroidserver script: - - pacman --sync --sysupgrade --refresh --noconfirm grep python-pip python-virtualenv tar + - pacman --sync --sysupgrade --refresh --noconfirm git grep python-pip python-virtualenv tar # setup venv to act as release build machine - python -m venv sdist-env - . sdist-env/bin/activate From b4720665b9224115368fc37c5f5e044359006c05 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 25 Feb 2020 12:46:47 +0100 Subject: [PATCH 0254/2775] add gradle 6.2{,.1} and AGP 3.6 --- gradlew-fdroid | 8 +++++--- makebuildserver | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index c42f1db0..597dc093 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -131,6 +131,8 @@ get_sha() { '6.0.1') echo 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44' ;; '6.1') echo 'd0c43d14e1c70a48b82442f435d06186351a2d290d72afd5b8866f15e6d7038a' ;; '6.1.1') echo '9d94e6e4a28ad328072ef6e56bce79a810494ae756751fdcedffdeaf27c093b1' ;; + '6.2') echo 'b93a5f30d01195ec201e240f029c8b42d59c24086b8d1864112c83558e23cf8a' ;; + '6.2.1') echo 'a68ca7ba57f3404c3f6fc1f70a02d3a7d78652e6b46bbfaff83fc9a17168c279' ;; *) exit 1 esac } @@ -147,11 +149,11 @@ contains() { # (key) should accept. plugin versions are actually prefixes and catch sub- # versions as well. Pairs are taken from: # https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle -d_plugin_k=(3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2) -d_plugin_v=(5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) +d_plugin_k=(3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2) +d_plugin_v=(5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 8195983f..1e7be112 100755 --- a/makebuildserver +++ b/makebuildserver @@ -364,6 +364,8 @@ CACHE_FILES = [ 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44'), ('https://services.gradle.org/distributions/gradle-6.1.1-bin.zip', '9d94e6e4a28ad328072ef6e56bce79a810494ae756751fdcedffdeaf27c093b1'), + ('https://services.gradle.org/distributions/gradle-6.2.1-bin.zip', + 'a68ca7ba57f3404c3f6fc1f70a02d3a7d78652e6b46bbfaff83fc9a17168c279'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 14208a6761cd4499bea349748600d9bb5f49afec Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 2 Mar 2020 14:17:42 -0300 Subject: [PATCH 0255/2775] Add stats support to nightly repo This will keep track of when APKs were added and show these dates properly in the client instead of always resetting all dates to the latest update. --- fdroidserver/nightly.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 0a3a8012..ae3aa0e3 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -170,6 +170,7 @@ def main(): git_mirror_path = os.path.join(repo_basedir, 'git-mirror') git_mirror_repodir = os.path.join(git_mirror_path, 'fdroid', 'repo') git_mirror_metadatadir = os.path.join(git_mirror_path, 'fdroid', 'metadata') + git_mirror_statsdir = os.path.join(git_mirror_path, 'fdroid', 'stats') if not os.path.isdir(git_mirror_repodir): logging.debug(_('cloning {url}').format(url=clone_url)) try: @@ -217,6 +218,8 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, common.local_rsync(options, git_mirror_repodir + '/', 'repo/') if os.path.isdir(git_mirror_metadatadir): common.local_rsync(options, git_mirror_metadatadir + '/', 'metadata/') + if os.path.isdir(git_mirror_statsdir): + common.local_rsync(options, git_mirror_statsdir + '/', 'stats/') ssh_private_key_file = _ssh_key_from_debug_keystore() # this is needed for GitPython to find the SSH key @@ -246,7 +249,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, config += "keydname = '%s'\n" % DISTINGUISHED_NAME config += "make_current_version_link = False\n" config += "accepted_formats = ('txt', 'yml')\n" - # TODO add update_stats = True + config += "update_stats = True\n" with open('config.py', 'w') as fp: fp.write(config) os.chmod('config.py', 0o600) @@ -293,6 +296,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, subprocess.check_call(['fdroid', 'update', '--rename-apks', '--create-metadata', '--verbose'], cwd=repo_basedir) common.local_rsync(options, repo_basedir + '/metadata/', git_mirror_metadatadir + '/') + common.local_rsync(options, repo_basedir + '/stats/', git_mirror_statsdir + '/') mirror_git_repo.git.add(all=True) mirror_git_repo.index.commit("update app metadata") From 2d63ab66f5c7a7944f7a07ca52a0ed0c9c335f46 Mon Sep 17 00:00:00 2001 From: fuwa Date: Mon, 9 Mar 2020 15:06:19 +0000 Subject: [PATCH 0256/2775] libvirt: various fixes related to the `makebuildserver` and `fdroid build` commands --- fdroidserver/common.py | 2 +- fdroidserver/vmtools.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 3697fec4..7b256476 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -710,7 +710,7 @@ def write_status_json(output, pretty=False, name=None): """Write status out as JSON, and rsync it to the repo server""" status_dir = os.path.join('repo', 'status') if not os.path.exists(status_dir): - os.mkdir(status_dir) + os.makedirs(status_dir) if not name: output['endTimestamp'] = int(datetime.now(timezone.utc).timestamp() * 1000) name = sys.argv[0].split()[1] # fdroid subcommand diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index 6456accb..ca65a2e5 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -122,6 +122,7 @@ def get_build_vm(srvdir, provider=None): # try guessing provider from installed software kvm_installed = shutil.which('kvm') is not None kvm_installed |= shutil.which('qemu') is not None + kvm_installed |= shutil.which('qemu-kvm') is not None vbox_installed = shutil.which('VBoxHeadless') is not None if kvm_installed and vbox_installed: logging.debug('both kvm and vbox are installed.') From 9d24f2e4a710e2b132fb495bf5eb5123335cfe1b Mon Sep 17 00:00:00 2001 From: Marcus Date: Tue, 10 Mar 2020 14:56:03 +0000 Subject: [PATCH 0257/2775] add opencollective metadata and index field --- .gitlab-ci.yml | 1 + fdroidserver/index.py | 1 + fdroidserver/metadata.py | 8 ++++++++ tests/metadata/dump/com.politedroid.yaml | 1 + tests/metadata/dump/org.adaway.yaml | 1 + tests/metadata/dump/org.smssecure.smssecure.yaml | 1 + tests/metadata/dump/org.videolan.vlc.yaml | 1 + tests/metadata/info.guardianproject.urzip.yml | 2 ++ tests/repo/index-v1.json | 4 +++- tests/repo/index.xml | 2 ++ 10 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 73614d2a..9f597f64 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -38,6 +38,7 @@ metadata_v0: - ../tests/dump_internal_metadata_format.py - sed -i -e '/kivy:\sfalse/d' + -e '/OpenCollective/d' metadata/dump_*/*.yaml - diff -uw metadata/dump_* diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 95f7f256..87ab340e 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -442,6 +442,7 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing addElementNonEmpty('litecoin', app.Litecoin, doc, apel) addElementNonEmpty('flattr', app.FlattrID, doc, apel) addElementNonEmpty('liberapay', app.LiberapayID, doc, apel) + addElementNonEmpty('openCollective', app.OpenCollective, doc, apel) # These elements actually refer to the current version (i.e. which # one is recommended. They are historically mis-named, and need diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 18fe6318..0a8bf5ff 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -71,6 +71,7 @@ app_fields = set([ 'Donate', 'FlattrID', 'LiberapayID', + 'OpenCollective', 'Bitcoin', 'Litecoin', 'Name', @@ -114,6 +115,7 @@ yaml_app_field_order = [ 'Donate', 'FlattrID', 'LiberapayID', + 'OpenCollective', 'Bitcoin', 'Litecoin', '\n', @@ -173,6 +175,7 @@ class App(dict): self.Donate = None self.FlattrID = None self.LiberapayID = None + self.OpenCollective = None self.Bitcoin = None self.Litecoin = None self.Name = None @@ -448,6 +451,10 @@ valuetypes = { r'^[0-9]+$', ['LiberapayID']), + FieldValidator("Open Collective", + r'^[0-9a-z-]+$', + ['OpenCollective']), + FieldValidator("HTTP link", r'^http[s]?://', ["WebSite", "SourceCode", "IssueTracker", "Translation", "Changelog", "Donate"]), @@ -1464,6 +1471,7 @@ def write_plaintext_metadata(mf, app, w_comment, w_field, w_build): w_field_nonempty('Donate') w_field_nonempty('FlattrID') w_field_nonempty('LiberapayID') + w_field_nonempty('OpenCollective') w_field_nonempty('Bitcoin') w_field_nonempty('Litecoin') mf.write('\n') diff --git a/tests/metadata/dump/com.politedroid.yaml b/tests/metadata/dump/com.politedroid.yaml index cc1bebbe..5d80e30e 100644 --- a/tests/metadata/dump/com.politedroid.yaml +++ b/tests/metadata/dump/com.politedroid.yaml @@ -23,6 +23,7 @@ Litecoin: null MaintainerNotes: '' Name: null NoSourceSince: '1.5' +OpenCollective: null Provides: null Repo: https://github.com/miguelvps/PoliteDroid.git RepoType: git diff --git a/tests/metadata/dump/org.adaway.yaml b/tests/metadata/dump/org.adaway.yaml index 577d0449..6412aaa3 100644 --- a/tests/metadata/dump/org.adaway.yaml +++ b/tests/metadata/dump/org.adaway.yaml @@ -46,6 +46,7 @@ Litecoin: null MaintainerNotes: '' Name: null NoSourceSince: '' +OpenCollective: null Provides: org.sufficientlysecure.adaway Repo: https://github.com/dschuermann/ad-away.git RepoType: git diff --git a/tests/metadata/dump/org.smssecure.smssecure.yaml b/tests/metadata/dump/org.smssecure.smssecure.yaml index 42e59f07..688e7d26 100644 --- a/tests/metadata/dump/org.smssecure.smssecure.yaml +++ b/tests/metadata/dump/org.smssecure.smssecure.yaml @@ -43,6 +43,7 @@ Litecoin: null MaintainerNotes: '' Name: null NoSourceSince: '' +OpenCollective: null Provides: null Repo: https://github.com/SMSSecure/SMSSecure RepoType: git diff --git a/tests/metadata/dump/org.videolan.vlc.yaml b/tests/metadata/dump/org.videolan.vlc.yaml index 70638ad5..5ab8783d 100644 --- a/tests/metadata/dump/org.videolan.vlc.yaml +++ b/tests/metadata/dump/org.videolan.vlc.yaml @@ -45,6 +45,7 @@ MaintainerNotes: 'Instructions and dependencies here: http://wiki.videolan.org/A ' Name: null NoSourceSince: '' +OpenCollective: null Provides: null Repo: git://git.videolan.org/vlc-ports/android.git RepoType: git diff --git a/tests/metadata/info.guardianproject.urzip.yml b/tests/metadata/info.guardianproject.urzip.yml index 8bb3cd1e..bab1d763 100644 --- a/tests/metadata/info.guardianproject.urzip.yml +++ b/tests/metadata/info.guardianproject.urzip.yml @@ -1,6 +1,8 @@ AutoName: Urzip:本地应用的信息 AutoUpdateMode: None Bitcoin: 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk +LiberapayID: '9999999' +OpenCollective: f-droid-just-testing Categories: - Development - GuardianProject diff --git a/tests/repo/index-v1.json b/tests/repo/index-v1.json index 32d76b7d..bf6626d1 100644 --- a/tests/repo/index-v1.json +++ b/tests/repo/index-v1.json @@ -184,8 +184,10 @@ "suggestedVersionCode": "2147483647", "description": "

It\u2019s Urzip \u662f\u4e00\u4e2a\u83b7\u5f97\u5df2\u5b89\u88c5 APK \u76f8\u5173\u4fe1\u606f\u7684\u5b9e\u7528\u5de5\u5177\u3002\u5b83\u4ece\u60a8\u7684\u8bbe\u5907\u4e0a\u5df2\u5b89\u88c5\u7684\u6240\u6709\u5e94\u7528\u5f00\u59cb\uff0c\u4e00\u952e\u89e6\u6478\u5373\u53ef\u663e\u793a APK \u7684\u6307\u7eb9\uff0c\u5e76\u4e14\u63d0\u4f9b\u5230\u8fbe virustotal.com \u548c androidobservatory.org \u7684\u5feb\u6377\u94fe\u63a5\uff0c\u8ba9\u60a8\u65b9\u4fbf\u5730\u4e86\u89e3\u7279\u5b9a APK \u7684\u6863\u6848\u3002\u5b83\u8fd8\u53ef\u4ee5\u8ba9\u60a8\u5bfc\u51fa\u7b7e\u540d\u8bc1\u4e66\u548c\u751f\u6210 ApkSignaturePin Pin \u6587\u4ef6\u4f9b TrustedIntents \u5e93\u4f7f\u7528\u3002

\u2605 Urzip \u652f\u6301\u4e0b\u5217\u8bed\u8a00\uff1a Deutsch, English, espa\u00f1ol, suomi, \u65e5\u672c\u8a9e, \ud55c\uad6d\uc5b4, Norsk, portugu\u00eas (Portugal), \u0420\u0443\u0441\u0441\u043a\u0438\u0439, Sloven\u0161\u010dina, T\u00fcrk\u00e7e \u6ca1\u770b\u5230\u60a8\u7684\u8bed\u8a00\uff1f\u5e2e\u5fd9\u7ffb\u8bd1\u672c\u5e94\u7528\u5427\uff1a https://www.transifex.com/projects/p/urzip

\u2605 \u81f4\u7528\u6237\uff1a\u6211\u4eec\u8fd8\u7f3a\u5c11\u4f60\u559c\u6b22\u7684\u529f\u80fd\uff1f\u53d1\u73b0\u4e86\u4e00\u4e2a bug\uff1f\u8bf7\u544a\u8bc9\u6211\u4eec\uff01\u6211\u4eec\u4e50\u4e8e\u542c\u53d6\u60a8\u7684\u610f\u89c1\u3002\u8bf7\u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u81f3: support@guardianproject.info \u6216\u8005\u52a0\u5165\u6211\u4eec\u7684\u804a\u5929\u5ba4 https://guardianproject.info/contact

", "issueTracker": "https://dev.guardianproject.info/projects/urzip/issues", + "liberapayID": "9999999", "license": "GPL-3.0-only", "name": "urzip-\u03c0\u00c7\u00c7\u03c0\u00c7\u00c7\u73b0\u4ee3\u6c49\u8bed\u901a\u7528\u5b57-\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438-\u0639\u0631\u0628\u064a1234", + "openCollective": "f-droid-just-testing", "sourceCode": "https://github.com/guardianproject/urzip", "summary": "\u4e00\u4e2a\u5b9e\u7528\u5de5\u5177\uff0c\u83b7\u53d6\u5df2\u5b89\u88c5\u5728\u60a8\u7684\u8bbe\u5907\u4e0a\u7684\u5e94\u7528\u7684\u6709\u5173\u4fe1\u606f", "webSite": "https://dev.guardianproject.info/projects/urzip", @@ -677,4 +679,4 @@ } ] } -} \ No newline at end of file +} diff --git a/tests/repo/index.xml b/tests/repo/index.xml index 313e8876..20b526dc 100644 --- a/tests/repo/index.xml +++ b/tests/repo/index.xml @@ -357,6 +357,8 @@ https://github.com/guardianproject/urzip https://dev.guardianproject.info/projects/urzip/issues 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk + 9999999 + f-droid-just-testing 2147483647 From 56ee7fe7657bbf66a164b9e241240d4dca4ff942 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 10 Mar 2020 16:26:34 +0100 Subject: [PATCH 0258/2775] opencollecive: fix allowed characters The url slug used by opencollective allows case variations, they all lead back to the canonical lowercase variant though. Apart from ascii characters and numbers only - and _ are allowed. --- fdroidserver/metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 0a8bf5ff..26bdcf22 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -452,7 +452,7 @@ valuetypes = { ['LiberapayID']), FieldValidator("Open Collective", - r'^[0-9a-z-]+$', + r'^[0-9a-zA-Z_-]+$', ['OpenCollective']), FieldValidator("HTTP link", From 87e825bf3e31b95d21894e8b42581cbd1effec32 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 10 Mar 2020 16:44:53 +0100 Subject: [PATCH 0259/2775] add gradle 6.2.2 --- gradlew-fdroid | 3 ++- makebuildserver | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 597dc093..5425393a 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -133,6 +133,7 @@ get_sha() { '6.1.1') echo '9d94e6e4a28ad328072ef6e56bce79a810494ae756751fdcedffdeaf27c093b1' ;; '6.2') echo 'b93a5f30d01195ec201e240f029c8b42d59c24086b8d1864112c83558e23cf8a' ;; '6.2.1') echo 'a68ca7ba57f3404c3f6fc1f70a02d3a7d78652e6b46bbfaff83fc9a17168c279' ;; + '6.2.2') echo '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17' ;; *) exit 1 esac } @@ -153,7 +154,7 @@ d_plugin_k=(3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 d_plugin_v=(5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 1e7be112..dae45f10 100755 --- a/makebuildserver +++ b/makebuildserver @@ -364,8 +364,8 @@ CACHE_FILES = [ 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44'), ('https://services.gradle.org/distributions/gradle-6.1.1-bin.zip', '9d94e6e4a28ad328072ef6e56bce79a810494ae756751fdcedffdeaf27c093b1'), - ('https://services.gradle.org/distributions/gradle-6.2.1-bin.zip', - 'a68ca7ba57f3404c3f6fc1f70a02d3a7d78652e6b46bbfaff83fc9a17168c279'), + ('https://services.gradle.org/distributions/gradle-6.2.2-bin.zip', + '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From ab2291475bee32c22a00630bcd62cbef97513566 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 26 Feb 2020 17:07:12 +0100 Subject: [PATCH 0260/2775] import: mv reusable functions to common.py to avoid import_proxy.py import is a strict keyword in Python, so it is not possible to import a module called 'import', even with things like: * import fdroidserver.import * from fdroidserver import import --- fdroidserver/common.py | 151 +++++++++++++++++++++++++++++++++++++++ fdroidserver/import.py | 155 ++--------------------------------------- tests/common.TestCase | 42 +++++++++++ tests/import.TestCase | 48 +------------ tests/import_proxy.py | 3 - 5 files changed, 200 insertions(+), 199 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 7b256476..b1b4f1c1 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -37,6 +37,8 @@ import logging import hashlib import socket import base64 +import urllib.parse +import urllib.request import zipfile import tempfile import json @@ -84,6 +86,9 @@ VALID_APPLICATION_ID_REGEX = re.compile(r'''(?:^[a-z_]+(?:\d*[a-zA-Z_]*)*)(?:\.[ re.IGNORECASE) ANDROID_PLUGIN_REGEX = re.compile(r'''\s*(:?apply plugin:|id)\(?\s*['"](android|com\.android\.application)['"]\s*\)?''') +SETTINGS_GRADLE_REGEX = re.compile(r'settings\.gradle(?:\.kts)?') +GRADLE_SUBPROJECT_REGEX = re.compile(r'''['"]:([^'"]+)['"]''') + MAX_VERSION_CODE = 0x7fffffff # Java's Integer.MAX_VALUE (2147483647) XMLNS_ANDROID = '{http://schemas.android.com/apk/res/android}' @@ -1653,6 +1658,152 @@ def is_strict_application_id(name): and '.' in name +def get_all_gradle_and_manifests(build_dir): + paths = [] + for root, dirs, files in os.walk(build_dir): + for f in sorted(files): + if f == 'AndroidManifest.xml' \ + or f.endswith('.gradle') or f.endswith('.gradle.kts'): + full = os.path.join(root, f) + paths.append(full) + return paths + + +def get_gradle_subdir(build_dir, paths): + """get the subdir where the gradle build is based""" + first_gradle_dir = None + for path in paths: + if not first_gradle_dir: + first_gradle_dir = os.path.relpath(os.path.dirname(path), build_dir) + if os.path.exists(path) and SETTINGS_GRADLE_REGEX.match(os.path.basename(path)): + with open(path) as fp: + for m in GRADLE_SUBPROJECT_REGEX.finditer(fp.read()): + for f in glob.glob(os.path.join(os.path.dirname(path), m.group(1), 'build.gradle*')): + with open(f) as fp: + while True: + line = fp.readline() + if not line: + break + if ANDROID_PLUGIN_REGEX.match(line): + return os.path.relpath(os.path.dirname(f), build_dir) + if first_gradle_dir and first_gradle_dir != '.': + return first_gradle_dir + + return '' + + +def getrepofrompage(url): + """Get the repo type and address from the given web page. + + The page is scanned in a rather naive manner for 'git clone xxxx', + 'hg clone xxxx', etc, and when one of these is found it's assumed + that's the information we want. Returns repotype, address, or + None, reason + + """ + if not url.startswith('http'): + return (None, _('{url} does not start with "http"!'.format(url=url))) + req = urllib.request.urlopen(url) # nosec B310 non-http URLs are filtered out + if req.getcode() != 200: + return (None, 'Unable to get ' + url + ' - return code ' + str(req.getcode())) + page = req.read().decode(req.headers.get_content_charset()) + + # Works for BitBucket + m = re.search('data-fetch-url="(.*)"', page) + if m is not None: + repo = m.group(1) + + if repo.endswith('.git'): + return ('git', repo) + + return ('hg', repo) + + # Works for BitBucket (obsolete) + index = page.find('hg clone') + if index != -1: + repotype = 'hg' + repo = page[index + 9:] + index = repo.find('<') + if index == -1: + return (None, _("Error while getting repo address")) + repo = repo[:index] + repo = repo.split('"')[0] + return (repotype, repo) + + # Works for BitBucket (obsolete) + index = page.find('git clone') + if index != -1: + repotype = 'git' + repo = page[index + 10:] + index = repo.find('<') + if index == -1: + return (None, _("Error while getting repo address")) + repo = repo[:index] + repo = repo.split('"')[0] + return (repotype, repo) + + return (None, _("No information found.") + page) + + +def get_app_from_url(url): + """Guess basic app metadata from the URL. + + The URL must include a network hostname, unless it is an lp:, + file:, or git/ssh URL. This throws ValueError on bad URLs to + match urlparse(). + + """ + + parsed = urllib.parse.urlparse(url) + invalid_url = False + if not parsed.scheme or not parsed.path: + invalid_url = True + + app = fdroidserver.metadata.App() + app.Repo = url + if url.startswith('git://') or url.startswith('git@'): + app.RepoType = 'git' + elif parsed.netloc == 'github.com': + app.RepoType = 'git' + app.SourceCode = url + app.IssueTracker = url + '/issues' + elif parsed.netloc == 'gitlab.com': + # git can be fussy with gitlab URLs unless they end in .git + if url.endswith('.git'): + url = url[:-4] + app.Repo = url + '.git' + app.RepoType = 'git' + app.SourceCode = url + app.IssueTracker = url + '/issues' + elif parsed.netloc == 'notabug.org': + if url.endswith('.git'): + url = url[:-4] + app.Repo = url + '.git' + app.RepoType = 'git' + app.SourceCode = url + app.IssueTracker = url + '/issues' + elif parsed.netloc == 'bitbucket.org': + if url.endswith('/'): + url = url[:-1] + app.SourceCode = url + '/src' + app.IssueTracker = url + '/issues' + # Figure out the repo type and adddress... + app.RepoType, app.Repo = getrepofrompage(url) + elif url.startswith('https://') and url.endswith('.git'): + app.RepoType = 'git' + + if not parsed.netloc and parsed.scheme in ('git', 'http', 'https', 'ssh'): + invalid_url = True + + if invalid_url: + raise ValueError(_('"{url}" is not a valid URL!'.format(url=url))) + + if not app.RepoType: + raise FDroidException("Unable to determine vcs type. " + app.Repo) + + return app + + def getsrclib(spec, srclib_dir, subdir=None, basepath=False, raw=False, prepare=True, preponly=False, refresh=True, build=None): diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 42ba55e3..cca3063c 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -18,14 +18,10 @@ # along with this program. If not, see . import git -import glob import json import os -import re import shutil import sys -import urllib.parse -import urllib.request import yaml from argparse import ArgumentParser import logging @@ -40,121 +36,12 @@ from . import common from . import metadata from .exception import FDroidException -SETTINGS_GRADLE = re.compile(r'settings\.gradle(?:\.kts)?') -GRADLE_SUBPROJECT = re.compile(r'''['"]:([^'"]+)['"]''') - - -# Get the repo type and address from the given web page. The page is scanned -# in a rather naive manner for 'git clone xxxx', 'hg clone xxxx', etc, and -# when one of these is found it's assumed that's the information we want. -# Returns repotype, address, or None, reason -def getrepofrompage(url): - if not url.startswith('http'): - return (None, _('{url} does not start with "http"!'.format(url=url))) - req = urllib.request.urlopen(url) # nosec B310 non-http URLs are filtered out - if req.getcode() != 200: - return (None, 'Unable to get ' + url + ' - return code ' + str(req.getcode())) - page = req.read().decode(req.headers.get_content_charset()) - - # Works for BitBucket - m = re.search('data-fetch-url="(.*)"', page) - if m is not None: - repo = m.group(1) - - if repo.endswith('.git'): - return ('git', repo) - - return ('hg', repo) - - # Works for BitBucket (obsolete) - index = page.find('hg clone') - if index != -1: - repotype = 'hg' - repo = page[index + 9:] - index = repo.find('<') - if index == -1: - return (None, _("Error while getting repo address")) - repo = repo[:index] - repo = repo.split('"')[0] - return (repotype, repo) - - # Works for BitBucket (obsolete) - index = page.find('git clone') - if index != -1: - repotype = 'git' - repo = page[index + 10:] - index = repo.find('<') - if index == -1: - return (None, _("Error while getting repo address")) - repo = repo[:index] - repo = repo.split('"')[0] - return (repotype, repo) - - return (None, _("No information found.") + page) - config = None options = None -def get_app_from_url(url): - """Guess basic app metadata from the URL. - - The URL must include a network hostname, unless it is an lp:, - file:, or git/ssh URL. This throws ValueError on bad URLs to - match urlparse(). - - """ - - parsed = urllib.parse.urlparse(url) - invalid_url = False - if not parsed.scheme or not parsed.path: - invalid_url = True - - app = metadata.App() - app.Repo = url - if url.startswith('git://') or url.startswith('git@'): - app.RepoType = 'git' - elif parsed.netloc == 'github.com': - app.RepoType = 'git' - app.SourceCode = url - app.IssueTracker = url + '/issues' - elif parsed.netloc == 'gitlab.com': - # git can be fussy with gitlab URLs unless they end in .git - if url.endswith('.git'): - url = url[:-4] - app.Repo = url + '.git' - app.RepoType = 'git' - app.SourceCode = url - app.IssueTracker = url + '/issues' - elif parsed.netloc == 'notabug.org': - if url.endswith('.git'): - url = url[:-4] - app.Repo = url + '.git' - app.RepoType = 'git' - app.SourceCode = url - app.IssueTracker = url + '/issues' - elif parsed.netloc == 'bitbucket.org': - if url.endswith('/'): - url = url[:-1] - app.SourceCode = url + '/src' - app.IssueTracker = url + '/issues' - # Figure out the repo type and adddress... - app.RepoType, app.Repo = getrepofrompage(url) - elif url.startswith('https://') and url.endswith('.git'): - app.RepoType = 'git' - - if not parsed.netloc and parsed.scheme in ('git', 'http', 'https', 'ssh'): - invalid_url = True - - if invalid_url: - raise ValueError(_('"{url}" is not a valid URL!'.format(url=url))) - - if not app.RepoType: - raise FDroidException("Unable to determine vcs type. " + app.Repo) - - return app - +# WARNING! This cannot be imported as a Python module, so reuseable functions need to go into common.py! def clone_to_tmp_dir(app): tmp_dir = 'tmp' @@ -171,40 +58,6 @@ def clone_to_tmp_dir(app): return tmp_dir -def get_all_gradle_and_manifests(build_dir): - paths = [] - for root, dirs, files in os.walk(build_dir): - for f in sorted(files): - if f == 'AndroidManifest.xml' \ - or f.endswith('.gradle') or f.endswith('.gradle.kts'): - full = os.path.join(root, f) - paths.append(full) - return paths - - -def get_gradle_subdir(build_dir, paths): - """get the subdir where the gradle build is based""" - first_gradle_dir = None - for path in paths: - if not first_gradle_dir: - first_gradle_dir = os.path.relpath(os.path.dirname(path), build_dir) - if os.path.exists(path) and SETTINGS_GRADLE.match(os.path.basename(path)): - with open(path) as fp: - for m in GRADLE_SUBPROJECT.finditer(fp.read()): - for f in glob.glob(os.path.join(os.path.dirname(path), m.group(1), 'build.gradle*')): - with open(f) as fp: - while True: - line = fp.readline() - if not line: - break - if common.ANDROID_PLUGIN_REGEX.match(line): - return os.path.relpath(os.path.dirname(f), build_dir) - if first_gradle_dir and first_gradle_dir != '.': - return first_gradle_dir - - return '' - - def main(): global config, options @@ -256,7 +109,7 @@ def main(): break write_local_file = True elif options.url: - app = get_app_from_url(options.url) + app = common.get_app_from_url(options.url) tmp_importer_dir = clone_to_tmp_dir(app) git_repo = git.repo.Repo(tmp_importer_dir) build.disable = 'Generated by import.py - check/set version fields and commit id' @@ -268,8 +121,8 @@ def main(): build.commit = common.get_head_commit_id(git_repo) # Extract some information... - paths = get_all_gradle_and_manifests(tmp_importer_dir) - subdir = get_gradle_subdir(tmp_importer_dir, paths) + paths = common.get_all_gradle_and_manifests(tmp_importer_dir) + subdir = common.get_gradle_subdir(tmp_importer_dir, paths) if paths: versionName, versionCode, package = common.parse_androidmanifests(paths, app) if not package: diff --git a/tests/common.TestCase b/tests/common.TestCase index 856b71e7..268d5dd4 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -983,6 +983,48 @@ class CommonTest(unittest.TestCase): self.assertEqual(('1.0-free', '1', 'com.kunzisoft.fdroidtest.applicationidsuffix'), fdroidserver.common.parse_androidmanifests(paths, app)) + def test_get_all_gradle_and_manifests(self): + a = fdroidserver.common.get_all_gradle_and_manifests(os.path.join('source-files', 'cn.wildfirechat.chat')) + paths = [ + os.path.join('source-files', 'cn.wildfirechat.chat', 'avenginekit', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'chat', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'src', 'main', 'AndroidManifest.xml'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'emojilibrary', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'gradle', 'build_libraries.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'imagepicker', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'mars-core-release', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'push', 'build.gradle'), + os.path.join('source-files', 'cn.wildfirechat.chat', 'settings.gradle'), + ] + self.assertEqual(sorted(paths), sorted(a)) + + def test_get_gradle_subdir(self): + subdirs = { + 'cn.wildfirechat.chat': 'chat', + 'com.anpmech.launcher': 'app', + 'org.tasks': 'app', + 'ut.ewh.audiometrytest': 'app', + } + for f in ('cn.wildfirechat.chat', 'com.anpmech.launcher', 'org.tasks', 'ut.ewh.audiometrytest'): + build_dir = os.path.join('source-files', f) + paths = fdroidserver.common.get_all_gradle_and_manifests(build_dir) + logging.info(paths) + subdir = fdroidserver.common.get_gradle_subdir(build_dir, paths) + self.assertEqual(subdirs[f], subdir) + + def test_bad_urls(self): + for url in ('asdf', + 'file://thing.git', + 'https:///github.com/my/project', + 'git:///so/many/slashes', + 'ssh:/notabug.org/missing/a/slash', + 'git:notabug.org/missing/some/slashes', + 'https//github.com/bar/baz'): + with self.assertRaises(ValueError): + fdroidserver.common.get_app_from_url(url) + def test_remove_signing_keys(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) print(testdir) diff --git a/tests/import.TestCase b/tests/import.TestCase index 30b660aa..70fe83df 100755 --- a/tests/import.TestCase +++ b/tests/import.TestCase @@ -49,53 +49,11 @@ class ImportTest(unittest.TestCase): print('Skipping ImportTest!') return - app = import_proxy.get_app_from_url(url) + app = fdroidserver.common.get_app_from_url(url) import_proxy.clone_to_tmp_dir(app) self.assertEqual(app.RepoType, 'git') self.assertEqual(app.Repo, 'https://gitlab.com/fdroid/ci-test-app.git') - def test_get_all_gradle_and_manifests(self): - a = import_proxy.get_all_gradle_and_manifests(os.path.join('source-files', 'cn.wildfirechat.chat')) - paths = [ - os.path.join('source-files', 'cn.wildfirechat.chat', 'avenginekit', 'build.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'build.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'chat', 'build.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'build.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'src', 'main', 'AndroidManifest.xml'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'emojilibrary', 'build.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'gradle', 'build_libraries.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'imagepicker', 'build.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'mars-core-release', 'build.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'push', 'build.gradle'), - os.path.join('source-files', 'cn.wildfirechat.chat', 'settings.gradle'), - ] - self.assertEqual(sorted(paths), sorted(a)) - - def test_get_gradle_subdir(self): - subdirs = { - 'cn.wildfirechat.chat': 'chat', - 'com.anpmech.launcher': 'app', - 'org.tasks': 'app', - 'ut.ewh.audiometrytest': 'app', - } - for f in ('cn.wildfirechat.chat', 'com.anpmech.launcher', 'org.tasks', 'ut.ewh.audiometrytest'): - build_dir = os.path.join('source-files', f) - paths = import_proxy.get_all_gradle_and_manifests(build_dir) - logging.info(paths) - subdir = import_proxy.get_gradle_subdir(build_dir, paths) - self.assertEqual(subdirs[f], subdir) - - def test_bad_urls(self): - for url in ('asdf', - 'file://thing.git', - 'https:///github.com/my/project', - 'git:///so/many/slashes', - 'ssh:/notabug.org/missing/a/slash', - 'git:notabug.org/missing/some/slashes', - 'https//github.com/bar/baz'): - with self.assertRaises(ValueError): - import_proxy.get_app_from_url(url) - def test_get_app_from_url(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) os.chdir(testdir) @@ -111,7 +69,7 @@ class ImportTest(unittest.TestCase): shutil.copytree(os.path.join(self.basedir, 'source-files', appid), tmp_importer) - app = import_proxy.get_app_from_url(url) + app = fdroidserver.common.get_app_from_url(url) with mock.patch('fdroidserver.common.getvcs', lambda a, b, c: fdroidserver.common.vcs(url, testdir)): with mock.patch('fdroidserver.common.vcs.gotorevision', @@ -122,7 +80,7 @@ class ImportTest(unittest.TestCase): self.assertEqual(url, app.Repo) self.assertEqual(url, app.SourceCode) logging.info(build_dir) - paths = import_proxy.get_all_gradle_and_manifests(build_dir) + paths = fdroidserver.common.get_all_gradle_and_manifests(build_dir) self.assertNotEqual(paths, []) versionName, versionCode, package = fdroidserver.common.parse_androidmanifests(paths, app) self.assertEqual(vn, versionName) diff --git a/tests/import_proxy.py b/tests/import_proxy.py index afe9544e..f230fdb1 100644 --- a/tests/import_proxy.py +++ b/tests/import_proxy.py @@ -19,9 +19,6 @@ module = __import__('fdroidserver.import') for name, obj in inspect.getmembers(module): if name == 'import': clone_to_tmp_dir = obj.clone_to_tmp_dir - get_all_gradle_and_manifests = obj.get_all_gradle_and_manifests - get_app_from_url = obj.get_app_from_url - get_gradle_subdir = obj.get_gradle_subdir obj.options = Options() options = obj.options break From 733e7be1b3cb774c1d4589f9085593d6b7f0d5da Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Mar 2020 14:37:17 +0100 Subject: [PATCH 0261/2775] set F-Droid HTTP Headers globally --- fdroidserver/net.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fdroidserver/net.py b/fdroidserver/net.py index b9ddf72b..3f497999 100644 --- a/fdroidserver/net.py +++ b/fdroidserver/net.py @@ -17,16 +17,17 @@ # along with this program. If not, see . import os - import requests +HEADERS = {'User-Agent': 'F-Droid'} + def download_file(url, local_filename=None, dldir='tmp'): filename = url.split('/')[-1] if local_filename is None: local_filename = os.path.join(dldir, filename) # the stream=True parameter keeps memory usage low - r = requests.get(url, stream=True, allow_redirects=True) + r = requests.get(url, stream=True, allow_redirects=True, headers=HEADERS) r.raise_for_status() with open(local_filename, 'wb') as f: for chunk in r.iter_content(chunk_size=1024): @@ -48,16 +49,15 @@ def http_get(url, etag=None, timeout=600): - The raw content that was downloaded or None if it did not change - The new eTag as returned by the HTTP request """ - headers = {'User-Agent': 'F-Droid'} # TODO disable TLS Session IDs and TLS Session Tickets # (plain text cookie visible to anyone who can see the network traffic) if etag: - r = requests.head(url, headers=headers, timeout=timeout) + r = requests.head(url, headers=HEADERS, timeout=timeout) r.raise_for_status() if 'ETag' in r.headers and etag == r.headers['ETag']: return None, etag - r = requests.get(url, headers=headers, timeout=timeout) + r = requests.get(url, headers=HEADERS, timeout=timeout) r.raise_for_status() new_etag = None From b7901952a18dcc1b387e6102e5ed6ded5760090c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Mar 2020 14:38:14 +0100 Subject: [PATCH 0262/2775] deploy: make androidobservatory and virustotal functions reusable This should not change the logic at all, just make the loop runs into standalone functions. --- .gitignore | 1 + fdroidserver/server.py | 232 ++++++++++++++++++++++------------------- tests/server.TestCase | 6 ++ 3 files changed, 134 insertions(+), 105 deletions(-) diff --git a/.gitignore b/.gitignore index 25aab3b3..57da9fb8 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ makebuildserver.config.py /tests/repo/obb.mainpatch.current/en-US/icon_WI0pkO3LsklrsTAnRr-OQSxkkoMY41lYe2-fAvXLiLg=.png /tests/repo/org.videolan.vlc/en-US/icon_yAfSvPRJukZzMMfUzvbYqwaD1XmHXNtiPBtuPVHW-6s=.png /tests/urzip-πÇÇπÇÇ现代汉语通用字-български-عربي1234.apk +/tests/virustotal/ /unsigned/ # generated by gettext diff --git a/fdroidserver/server.py b/fdroidserver/server.py index c01c1f26..57acd9ca 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -19,6 +19,7 @@ import sys import glob import hashlib +import json import os import paramiko import pwd @@ -447,9 +448,8 @@ def update_servergitmirrors(servergitmirrors, repo_section): def upload_to_android_observatory(repo_section): - # depend on requests and lxml only if users enable AO import requests - from lxml.html import fromstring + requests # stop unused import warning if options.verbose: logging.getLogger("requests").setLevel(logging.INFO) @@ -460,44 +460,53 @@ def upload_to_android_observatory(repo_section): if repo_section == 'repo': for f in sorted(glob.glob(os.path.join(repo_section, '*.apk'))): - fpath = f - fname = os.path.basename(f) - r = requests.post('https://androidobservatory.org/', - data={'q': update.sha256sum(f), 'searchby': 'hash'}) - if r.status_code == 200: - # from now on XPath will be used to retrieve the message in the HTML - # androidobservatory doesn't have a nice API to talk with - # so we must scrape the page content - tree = fromstring(r.text) + upload_apk_to_android_observatory(f) - href = None - for element in tree.xpath("//html/body/div/div/table/tbody/tr/td/a"): - a = element.attrib.get('href') - if a: - m = re.match(r'^/app/[0-9A-F]{40}$', a) - if m: - href = m.group() - page = 'https://androidobservatory.org' - message = '' - if href: - message = (_('Found {apkfilename} at {url}') - .format(apkfilename=fname, url=(page + href))) - if message: - logging.debug(message) - continue +def upload_apk_to_android_observatory(path): + # depend on requests and lxml only if users enable AO + import requests + from . import net + from lxml.html import fromstring - # upload the file with a post request - logging.info(_('Uploading {apkfilename} to androidobservatory.org') - .format(apkfilename=fname)) - r = requests.post('https://androidobservatory.org/upload', - files={'apk': (fname, open(fpath, 'rb'))}, - allow_redirects=False) + apkfilename = os.path.basename(path) + r = requests.post('https://androidobservatory.org/', + data={'q': update.sha256sum(path), 'searchby': 'hash'}, + headers=net.HEADERS) + if r.status_code == 200: + # from now on XPath will be used to retrieve the message in the HTML + # androidobservatory doesn't have a nice API to talk with + # so we must scrape the page content + tree = fromstring(r.text) + + href = None + for element in tree.xpath("//html/body/div/div/table/tbody/tr/td/a"): + a = element.attrib.get('href') + if a: + m = re.match(r'^/app/[0-9A-F]{40}$', a) + if m: + href = m.group() + + page = 'https://androidobservatory.org' + message = '' + if href: + message = (_('Found {apkfilename} at {url}') + .format(apkfilename=apkfilename, url=(page + href))) + if message: + logging.debug(message) + + # upload the file with a post request + logging.info(_('Uploading {apkfilename} to androidobservatory.org') + .format(apkfilename=apkfilename)) + r = requests.post('https://androidobservatory.org/upload', + files={'apk': (apkfilename, open(path, 'rb'))}, + headers=net.HEADERS, + allow_redirects=False) def upload_to_virustotal(repo_section, virustotal_apikey): - import json import requests + requests # stop unused import warning logging.getLogger("urllib3").setLevel(logging.WARNING) logging.getLogger("requests").setLevel(logging.WARNING) @@ -514,82 +523,95 @@ def upload_to_virustotal(repo_section, virustotal_apikey): for packageName, packages in data['packages'].items(): for package in packages: - outputfilename = os.path.join('virustotal', - packageName + '_' + str(package.get('versionCode')) - + '_' + package['hash'] + '.json') - if os.path.exists(outputfilename): - logging.debug(package['apkName'] + ' results are in ' + outputfilename) - continue - filename = package['apkName'] - repofilename = os.path.join(repo_section, filename) - logging.info('Checking if ' + repofilename + ' is on virustotal') + upload_apk_to_virustotal(virustotal_apikey, **package) - headers = { - "User-Agent": "F-Droid" - } - data = { - 'apikey': virustotal_apikey, - 'resource': package['hash'], - } - needs_file_upload = False - while True: - r = requests.get('https://www.virustotal.com/vtapi/v2/file/report?' - + urllib.parse.urlencode(data), headers=headers) - if r.status_code == 200: - response = r.json() - if response['response_code'] == 0: - needs_file_upload = True - else: - response['filename'] = filename - response['packageName'] = packageName - response['versionCode'] = package.get('versionCode') - response['versionName'] = package.get('versionName') - with open(outputfilename, 'w') as fp: - json.dump(response, fp, indent=2, sort_keys=True) - if response.get('positives', 0) > 0: - logging.warning(repofilename + ' has been flagged by virustotal ' - + str(response['positives']) + ' times:' - + '\n\t' + response['permalink']) - break - elif r.status_code == 204: - time.sleep(10) # wait for public API rate limiting +def upload_apk_to_virustotal(virustotal_apikey, packageName, apkName, hash, + versionCode, **kwargs): + import requests - upload_url = None - if needs_file_upload: - manual_url = 'https://www.virustotal.com/' - size = os.path.getsize(repofilename) - if size > 200000000: - # VirusTotal API 200MB hard limit - logging.error(_('{path} more than 200MB, manually upload: {url}') - .format(path=repofilename, url=manual_url)) - elif size > 32000000: - # VirusTotal API requires fetching a URL to upload bigger files - r = requests.get('https://www.virustotal.com/vtapi/v2/file/scan/upload_url?' - + urllib.parse.urlencode(data), headers=headers) - if r.status_code == 200: - upload_url = r.json().get('upload_url') - elif r.status_code == 403: - logging.error(_('VirusTotal API key cannot upload files larger than 32MB, ' - + 'use {url} to upload {path}.') - .format(path=repofilename, url=manual_url)) - else: - r.raise_for_status() - else: - upload_url = 'https://www.virustotal.com/vtapi/v2/file/scan' + outputfilename = os.path.join('virustotal', + packageName + '_' + str(versionCode) + + '_' + hash + '.json') + if os.path.exists(outputfilename): + logging.debug(apkName + ' results are in ' + outputfilename) + return outputfilename + repofilename = os.path.join('repo', apkName) + logging.info('Checking if ' + repofilename + ' is on virustotal') - if upload_url: - logging.info(_('Uploading {apkfilename} to virustotal') - .format(apkfilename=repofilename)) - files = { - 'file': (filename, open(repofilename, 'rb')) - } - r = requests.post(upload_url, data=data, headers=headers, files=files) - logging.debug(_('If this upload fails, try manually uploading to {url}') - .format(url=manual_url)) - r.raise_for_status() - response = r.json() - logging.info(response['verbose_msg'] + " " + response['permalink']) + headers = { + "User-Agent": "F-Droid" + } + if 'headers' in kwargs: + for k, v in kwargs['headers'].items(): + headers[k] = v + + data = { + 'apikey': virustotal_apikey, + 'resource': hash, + } + needs_file_upload = False + while True: + r = requests.get('https://www.virustotal.com/vtapi/v2/file/report?' + + urllib.parse.urlencode(data), headers=headers) + if r.status_code == 200: + response = r.json() + if response['response_code'] == 0: + needs_file_upload = True + else: + response['filename'] = apkName + response['packageName'] = packageName + response['versionCode'] = versionCode + if kwargs.get('versionName'): + response['versionName'] = kwargs.get('versionName') + with open(outputfilename, 'w') as fp: + json.dump(response, fp, indent=2, sort_keys=True) + + if response.get('positives', 0) > 0: + logging.warning(repofilename + ' has been flagged by virustotal ' + + str(response['positives']) + ' times:' + + '\n\t' + response['permalink']) + break + elif r.status_code == 204: + time.sleep(10) # wait for public API rate limiting + + upload_url = None + if needs_file_upload: + manual_url = 'https://www.virustotal.com/' + size = os.path.getsize(repofilename) + if size > 200000000: + # VirusTotal API 200MB hard limit + logging.error(_('{path} more than 200MB, manually upload: {url}') + .format(path=repofilename, url=manual_url)) + elif size > 32000000: + # VirusTotal API requires fetching a URL to upload bigger files + r = requests.get('https://www.virustotal.com/vtapi/v2/file/scan/upload_url?' + + urllib.parse.urlencode(data), headers=headers) + if r.status_code == 200: + upload_url = r.json().get('upload_url') + elif r.status_code == 403: + logging.error(_('VirusTotal API key cannot upload files larger than 32MB, ' + + 'use {url} to upload {path}.') + .format(path=repofilename, url=manual_url)) + else: + r.raise_for_status() + else: + upload_url = 'https://www.virustotal.com/vtapi/v2/file/scan' + + if upload_url: + logging.info(_('Uploading {apkfilename} to virustotal') + .format(apkfilename=repofilename)) + files = { + 'file': (apkName, open(repofilename, 'rb')) + } + r = requests.post(upload_url, data=data, headers=headers, files=files) + logging.debug(_('If this upload fails, try manually uploading to {url}') + .format(url=manual_url)) + r.raise_for_status() + response = r.json() + logging.info(response['verbose_msg'] + " " + response['permalink']) + + return outputfilename def push_binary_transparency(git_repo_path, git_remote): diff --git a/tests/server.TestCase b/tests/server.TestCase index 5d058153..8bd769ea 100755 --- a/tests/server.TestCase +++ b/tests/server.TestCase @@ -142,6 +142,12 @@ class ServerTest(unittest.TestCase): repo_section) self.assertEqual(call_iteration, 2, 'expected 2 invocations of subprocess.call') + @unittest.skipIf(not os.getenv('VIRUSTOTAL_API_KEY'), 'VIRUSTOTAL_API_KEY is not set') + def test_upload_to_virustotal(self): + fdroidserver.server.options.verbose = True + virustotal_apikey = os.getenv('VIRUSTOTAL_API_KEY') + fdroidserver.server.upload_to_virustotal('repo', virustotal_apikey) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From a1e17d2b2c048cb16130ee6414f2fde2ba60458b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Mar 2020 14:41:38 +0100 Subject: [PATCH 0263/2775] deploy: retry virustotal 30 seconds after rate limiting, and log --- fdroidserver/server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index 57acd9ca..eb1d8236 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -573,7 +573,8 @@ def upload_apk_to_virustotal(virustotal_apikey, packageName, apkName, hash, + '\n\t' + response['permalink']) break elif r.status_code == 204: - time.sleep(10) # wait for public API rate limiting + logging.warning(_('virustotal.com is rate limiting, waiting to retry...')) + time.sleep(30) # wait for public API rate limiting upload_url = None if needs_file_upload: From 1bb9cf43e1bff9b9ce9e5c7a52c0da072fefa174 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Mar 2020 21:32:04 +0100 Subject: [PATCH 0264/2775] import: ensure gradle: yes is added for detected Gradle builds --- fdroidserver/import.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index cca3063c..772220ec 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -143,8 +143,10 @@ def main(): build.versionCode = versionCode or '0' # TODO heinous but this is still a str if options.subdir: build.subdir = options.subdir + build.gradle = ['yes'] elif subdir: build.subdir = subdir + build.gradle = ['yes'] if options.license: app.License = options.license From 138bc7366821d4159529b8e01d3787fe10fa10b4 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 3 Mar 2020 21:33:23 +0100 Subject: [PATCH 0265/2775] import: --omit-disable option to easily work with generated files --- fdroidserver/import.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 772220ec..23d06d57 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -73,6 +73,8 @@ def main(): help=_("Comma separated list of categories.")) parser.add_argument("-l", "--license", default=None, help=_("Overall license of the project.")) + parser.add_argument("--omit-disable", default=False, + help=_("Do not add 'disable:' to the generated build entries")) parser.add_argument("--rev", default=None, help=_("Allows a different revision (or git branch) to be specified for the initial import")) metadata.add_metadata_arguments(parser) @@ -112,7 +114,8 @@ def main(): app = common.get_app_from_url(options.url) tmp_importer_dir = clone_to_tmp_dir(app) git_repo = git.repo.Repo(tmp_importer_dir) - build.disable = 'Generated by import.py - check/set version fields and commit id' + if not options.omit_disable: + build.disable = 'Generated by import.py - check/set version fields and commit id' write_local_file = False else: raise FDroidException("Specify project url.") From 1b001cf1b53d4d8ccd74ed7b71b536d08e7ec91e Mon Sep 17 00:00:00 2001 From: relan Date: Sun, 15 Mar 2020 17:34:25 +0300 Subject: [PATCH 0266/2775] provision-gradle: remove fake proxy configuration The prohibition of HTTP causes connection errors on some builds: IOException: https://dl.google.com/android/repository/addons_list-3.xml java.net.ConnectException: Connection refused (Connection refused) IOException: https://dl.google.com/android/repository/addons_list-2.xml java.net.ConnectException: Connection refused (Connection refused) IOException: https://dl.google.com/android/repository/addons_list-1.xml java.net.ConnectException: Connection refused (Connection refused) Failed to download any source lists! Partly revert a746917022cc7412ac8f922cbab64d1bf6b5f2d5. --- buildserver/provision-gradle | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/buildserver/provision-gradle b/buildserver/provision-gradle index a613e332..ce8aefa1 100644 --- a/buildserver/provision-gradle +++ b/buildserver/provision-gradle @@ -39,11 +39,7 @@ systemProp.http.connectionTimeout=600000 systemProp.http.socketTimeout=600000 systemProp.org.gradle.internal.http.connectionTimeout=600000 systemProp.org.gradle.internal.http.socketTimeout=600000 - -# fake info to block HTTP repos -systemProp.http.nonProxyHosts= -systemProp.http.proxyHost=127.127.127.127 -systemProp.http.proxyPort=12345 EOF + chown -R vagrant.vagrant $GRADLE_HOME/ chmod -R a+rX $GRADLE_HOME/ From 6a06551b732fdd784b32cda3fa9a880cb9e8ab2f Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 17 Mar 2020 12:01:41 +0100 Subject: [PATCH 0267/2775] add build tools 29.0.3 Closes fdroid/fdroidserver#753 --- makebuildserver | 2 ++ 1 file changed, 2 insertions(+) diff --git a/makebuildserver b/makebuildserver index dae45f10..ce608e33 100755 --- a/makebuildserver +++ b/makebuildserver @@ -256,6 +256,8 @@ CACHE_FILES = [ '7954956a40633c88f693d638cbc23f68e9e2499dc7a4b7dfdaf6a3e91387749a'), ('https://dl.google.com/android/repository/build-tools_r29.0.2-linux.zip', '1e9393cbfd4a4b82e30e7f55ab38db4a5a3259db93d5821c63597bc74522fa08'), + ('https://dl.google.com/android/repository/build-tools_r29.0.3-linux.zip', + '5652d8cd5eaaade0b853bfe0ae6cbfa0706a6f70a0ebb25ca24a6f484ec3d855'), ('https://services.gradle.org/distributions/gradle-2.2.1-bin.zip', '420aa50738299327b611c10b8304b749e8d3a579407ee9e755b15921d95ff418'), ('https://services.gradle.org/distributions/gradle-2.3-bin.zip', From a9d0a42c7c9232c848e26aeed8c604ca4b93de62 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 20 Mar 2020 14:26:02 +0100 Subject: [PATCH 0268/2775] use default org wide FUNDING.yml https://github.com/f-droid/.github/blob/master/FUNDING.yml --- FUNDING.yml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 FUNDING.yml diff --git a/FUNDING.yml b/FUNDING.yml deleted file mode 100644 index 83d4c2b7..00000000 --- a/FUNDING.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -liberapay: F-Droid-Data -github: - - eighthave -tidelift: pypi/fdroidserver -custom: - - https://f-droid.org/about/ - - https://www.hellotux.com/f-droid - - https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=E2FCXCT6837GL From 3113b890b5f7224c1dbfdb3161e9935ac98b7c33 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 26 Mar 2020 16:09:05 +0100 Subject: [PATCH 0269/2775] add gradle 6.3 --- gradlew-fdroid | 3 ++- makebuildserver | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 5425393a..eacfc759 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -134,6 +134,7 @@ get_sha() { '6.2') echo 'b93a5f30d01195ec201e240f029c8b42d59c24086b8d1864112c83558e23cf8a' ;; '6.2.1') echo 'a68ca7ba57f3404c3f6fc1f70a02d3a7d78652e6b46bbfaff83fc9a17168c279' ;; '6.2.2') echo '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17' ;; + '6.3') echo '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768' ;; *) exit 1 esac } @@ -154,7 +155,7 @@ d_plugin_k=(3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 d_plugin_v=(5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index ce608e33..38b56d0d 100755 --- a/makebuildserver +++ b/makebuildserver @@ -368,6 +368,8 @@ CACHE_FILES = [ '9d94e6e4a28ad328072ef6e56bce79a810494ae756751fdcedffdeaf27c093b1'), ('https://services.gradle.org/distributions/gradle-6.2.2-bin.zip', '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17'), + ('https://services.gradle.org/distributions/gradle-6.3-bin.zip', + '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 9e8aef677100ff31b17dcacfbfdefaad6d98abb2 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Mon, 30 Mar 2020 07:10:51 -0400 Subject: [PATCH 0270/2775] Add stretch-backports-sloppy repo too --- buildserver/provision-apt-get-install | 1 + 1 file changed, 1 insertion(+) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index df318bbc..2ec3d2f9 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -38,6 +38,7 @@ deb http://security.debian.org/debian-security stretch/updates main deb ${debian_mirror} stretch-updates main EOF echo "deb ${debian_mirror} stretch-backports main" > /etc/apt/sources.list.d/stretch-backports.list +echo "deb ${debian_mirror} stretch-backports-sloppy main" > /etc/apt/sources.list.d/stretch-backports-sloppy.list echo "deb ${debian_mirror} testing main" > /etc/apt/sources.list.d/testing.list printf "Package: *\nPin: release o=Debian,a=testing\nPin-Priority: -300\n" > /etc/apt/preferences.d/debian-testing From 463f6823de774fb982b35df584d4fd0ee2d7cd72 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Wed, 8 Apr 2020 10:25:53 +0000 Subject: [PATCH 0271/2775] Import - sudo refresh repos too and use the newer npm --- fdroidserver/import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 23d06d57..40746b99 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -164,7 +164,7 @@ def main(): package_json = os.path.join(tmp_importer_dir, 'package.json') # react-native pubspec_yaml = os.path.join(tmp_importer_dir, 'pubspec.yaml') # flutter if os.path.exists(package_json): - build.sudo = ['apt-get install npm', 'npm install -g react-native-cli'] + build.sudo = ['apt-get update || apt-get update', 'apt-get install -t stretch-backports npm', 'npm install -g react-native-cli'] build.init = ['npm install'] with open(package_json) as fp: data = json.load(fp) From 7d69f04b94de4b1bc696842664130d34666908e3 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 10 Apr 2020 13:34:46 -0300 Subject: [PATCH 0272/2775] Show debug messages to give clue why pushing git mirror failed --- fdroidserver/server.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index eb1d8236..e261222b 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -438,6 +438,10 @@ def update_servergitmirrors(servergitmirrors, repo_section): | git.remote.PushInfo.REJECTED | git.remote.PushInfo.REMOTE_FAILURE | git.remote.PushInfo.REMOTE_REJECTED): + # Show potentially useful messages from git remote + for line in progress.other_lines: + if line.startswith('remote:'): + logging.debug(line) raise FDroidException(remote.url + ' push failed: ' + str(pushinfo.flags) + ' ' + pushinfo.summary) else: From c000d450ca88807bbe797f6d9eb3063e528b8a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sat, 11 Apr 2020 15:15:20 +0200 Subject: [PATCH 0273/2775] add debugging output for makebs buildserverid --- makebuildserver | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/makebuildserver b/makebuildserver index 38b56d0d..36999e45 100755 --- a/makebuildserver +++ b/makebuildserver @@ -674,7 +674,9 @@ def main(): universal_newlines=True) buildserverid = p.communicate()[0].strip() logging.info("Writing buildserver ID ...ID is %s", buildserverid) - run_via_vagrant_ssh(v, 'sh -c "echo %s >/home/vagrant/buildserverid"' % buildserverid) + write_bsid_cmd = 'sh -c "echo \'{}\' >/home/vagrant/buildserverid"'.format(buildserverid) + run_via_vagrant_ssh(v, write_bsid_cmd) + logging.debug("+ {}".format(write_bsid_cmd)) logging.info("Stopping build server VM") v.halt() From af4eb86fca1ebe57954064b653a16750790e2139 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sat, 11 Apr 2020 23:53:37 +0200 Subject: [PATCH 0274/2775] Add sync to make sure buildserverid is written --- makebuildserver | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/makebuildserver b/makebuildserver index 36999e45..64d53fbb 100755 --- a/makebuildserver +++ b/makebuildserver @@ -674,7 +674,8 @@ def main(): universal_newlines=True) buildserverid = p.communicate()[0].strip() logging.info("Writing buildserver ID ...ID is %s", buildserverid) - write_bsid_cmd = 'sh -c "echo \'{}\' >/home/vagrant/buildserverid"'.format(buildserverid) + # sync data before we halt() the machine, we had an empty buildserverid otherwise + write_bsid_cmd = 'sh -c "echo \'{}\' >/home/vagrant/buildserverid; sync"'.format(buildserverid) run_via_vagrant_ssh(v, write_bsid_cmd) logging.debug("+ {}".format(write_bsid_cmd)) From 46a464a74b102d6c33f286a6149e097d88857549 Mon Sep 17 00:00:00 2001 From: Izzy Date: Wed, 15 Apr 2020 09:13:08 +0200 Subject: [PATCH 0275/2775] get_app_from_url: add codeberg.org as git url --- fdroidserver/common.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index b1b4f1c1..bab6c3b9 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1789,6 +1789,10 @@ def get_app_from_url(url): app.IssueTracker = url + '/issues' # Figure out the repo type and adddress... app.RepoType, app.Repo = getrepofrompage(url) + elif parsed.netloc == 'codeberg.org': + app.RepoType = 'git' + app.SourceCode = url + app.IssueTracker = url + '/issues' elif url.startswith('https://') and url.endswith('.git'): app.RepoType = 'git' From 86beac22e2d8ec8f010c9586de83935f19b373b6 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Wed, 15 Apr 2020 18:27:13 +0000 Subject: [PATCH 0276/2775] Use libarchive instead of the Python implementation --- .gitlab-ci.yml | 2 +- fdroidserver/vmtools.py | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9f597f64..e3ce7be9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -105,7 +105,7 @@ ubuntu_xenial_pip: only: - master@fdroid/fdroidserver script: - - apt-get install git default-jdk-headless python3-pip python3-venv rsync zipalign + - apt-get install git default-jdk-headless python3-pip python3-venv rsync zipalign libarchive13 - rm -rf env - pyvenv env - . env/bin/activate diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index ca65a2e5..64d630e3 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -430,13 +430,19 @@ class LibvirtBuildVm(FDroidBuildVm): end""".format_map({'memory': str(int(domainInfo[1] / 1024)), 'cpus': str(domainInfo[3])})) with open('Vagrantfile', 'w') as fp: fp.write(vagrantfile) - with tarfile.open(output, 'w:gz') as tar: - logging.debug('adding metadata.json to box %s ...', output) - tar.add('metadata.json') - logging.debug('adding Vagrantfile to box %s ...', output) - tar.add('Vagrantfile') - logging.debug('adding box.img to box %s ...', output) - tar.add('box.img') + try: + import libarchive + with libarchive.file_writer(output, 'gnutar', 'gzip') as tar: + logging.debug('adding files to box %s ...', output) + tar.add_files('metadata.json', 'Vagrantfile', 'box.img') + except (ModuleNotFoundError, AttributeError): + with tarfile.open(output, 'w:gz') as tar: + logging.debug('adding metadata.json to box %s ...', output) + tar.add('metadata.json') + logging.debug('adding Vagrantfile to box %s ...', output) + tar.add('Vagrantfile') + logging.debug('adding box.img to box %s ...', output) + tar.add('box.img') if not keep_box_file: logging.debug('box packaging complete, removing temporary files.') From c47f9ef123de43ca512157fbbf413d7d4f80c92e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 15 Apr 2020 21:43:41 +0200 Subject: [PATCH 0277/2775] index: xml.dom.minidom no longer sorts attribs It seems now that xml.dom.minidom preserves the order of attributes, rather than sorting them. We assume alpha-sort, so this manually This diff in the test suite running on Debian/testing pointed it out: https://gitlab.com/fdroid/fdroidserver/-/jobs/486970383 ```diff --- /builds/fdroid/fdroidserver/tests/repo/index.xml 2020-04-11 13:36:57.000000000 +0000 +++ repo/index.xml 2020-04-11 13:41:44.000000000 +0000 @@ -1,6 +1,6 @@ - + This is a repository of apps to be used with F-Droid. Applications in this repository are either official binaries built by the original application developers, or are binaries built from source by the admin of f-droid.org using the tools on https://gitlab.com/u/fdroid. http://foobarfoobarfoobar.onion/fdroid/repo https://foo.bar/fdroid/repo @@ -94,9 +94,9 @@ 2017-12-22 056c9f1554c40ba59a2103009c82b420 ACCESS_NETWORK_STATE,ACCESS_WIFI_STATE,CHANGE_WIFI_MULTICAST_STATE,INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE - - - + + + @@ -182,9 +182,9 @@ 2013-12-31 eb41d4d6082bb3e81c3d58dbf7fc7332 ACCESS_NETWORK_STATE,ACCESS_WIFI_STATE,BLUETOOTH,BLUETOOTH_ADMIN,CHANGE_NETWORK_STATE,CHANGE_WIFI_MULTICAST_STATE,CHANGE_WIFI_STATE,INTERNET,NFC,RECEIVE_BOOT_COMPLETED - - - + + +
``` --- fdroidserver/index.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 87ab340e..c19b6277 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -317,13 +317,17 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing parent.appendChild(el) def addElementCheckLocalized(name, app, key, doc, parent, default=''): - '''Fill in field from metadata or localized block + """Fill in field from metadata or localized block For name/summary/description, they can come only from the app source, or from a dir in fdroiddata. They can be entirely missing from the metadata file if there is localized versions. This will fetch those from the localized version if its not available in the metadata file. - ''' + + Attributes should be alpha-sorted, so they must be added in + alpha- sort order. + + """ el = doc.createElement(name) value = app.get(key) @@ -349,21 +353,20 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing doc.appendChild(root) repoel = doc.createElement("repo") - - repoel.setAttribute("name", repodict['name']) + repoel.setAttribute("icon", os.path.basename(repodict['icon'])) if 'maxage' in repodict: repoel.setAttribute("maxage", str(repodict['maxage'])) - repoel.setAttribute("icon", os.path.basename(repodict['icon'])) + repoel.setAttribute("name", repodict['name']) + pubkey, repo_pubkey_fingerprint = extract_pubkey() + repoel.setAttribute("pubkey", pubkey.decode('utf-8')) + repoel.setAttribute("timestamp", '%d' % repodict['timestamp'].timestamp()) repoel.setAttribute("url", repodict['address']) + repoel.setAttribute("version", str(repodict['version'])) + addElement('description', repodict['description'], doc, repoel) for mirror in repodict.get('mirrors', []): addElement('mirror', mirror, doc, repoel) - repoel.setAttribute("version", str(repodict['version'])) - repoel.setAttribute("timestamp", '%d' % repodict['timestamp'].timestamp()) - - pubkey, repo_pubkey_fingerprint = extract_pubkey() - repoel.setAttribute("pubkey", pubkey.decode('utf-8')) root.appendChild(repoel) for command in ('install', 'uninstall'): @@ -542,16 +545,16 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing for permission in sorted_permissions: permel = doc.createElement('uses-permission') - permel.setAttribute('name', permission[0]) if permission[1] is not None: permel.setAttribute('maxSdkVersion', '%d' % permission[1]) apkel.appendChild(permel) + permel.setAttribute('name', permission[0]) for permission_sdk_23 in sorted(apk['uses-permission-sdk-23']): permel = doc.createElement('uses-permission-sdk-23') - permel.setAttribute('name', permission_sdk_23[0]) if permission_sdk_23[1] is not None: permel.setAttribute('maxSdkVersion', '%d' % permission_sdk_23[1]) apkel.appendChild(permel) + permel.setAttribute('name', permission_sdk_23[0]) if 'nativecode' in apk: addElement('nativecode', ','.join(sorted(apk['nativecode'])), doc, apkel) addElementNonEmpty('features', ','.join(sorted(apk['features'])), doc, apkel) From c6a97939f1254f44318d1496c21a828bb5ed1d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 13 Dec 2019 23:51:18 +0100 Subject: [PATCH 0278/2775] rename parse_srclib to parese_txt_srclib + test case --- fdroidserver/metadata.py | 6 +++--- tests/metadata.TestCase | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 26bdcf22..fbf11a44 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -704,7 +704,7 @@ def description_html(s, linkres): return ps.text_html -def parse_srclib(metadatapath): +def parse_txt_srclib(metadatapath): thisinfo = {} @@ -746,7 +746,7 @@ def read_srclibs(): The information read will be accessible as metadata.srclibs, which is a dictionary, keyed on srclib name, with the values each being a dictionary - in the same format as that returned by the parse_srclib function. + in the same format as that returned by the parse_txt_srclib function. A MetaDataException is raised if there are any problems with the srclib metadata. @@ -765,7 +765,7 @@ def read_srclibs(): for metadatapath in sorted(glob.glob(os.path.join(srcdir, '*.txt'))): srclibname = os.path.basename(metadatapath[:-4]) - srclibs[srclibname] = parse_srclib(metadatapath) + srclibs[srclibname] = parse_txt_srclib(metadatapath) def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 686301db..08d4137c 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -23,6 +23,8 @@ print('localmodule: ' + localmodule) if localmodule not in sys.path: sys.path.insert(0, localmodule) +from testcommon import TmpCwd + import fdroidserver.common import fdroidserver.metadata from fdroidserver.exception import MetaDataException @@ -568,6 +570,29 @@ class MetadataTest(unittest.TestCase): UpdateCheckMode: None """)) + def test_parse_txt_srclib(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('JSoup.txt', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + # Source details (the only mandatory fields) + Repo Type:git + Repo:https://github.com/jhy/jsoup.git + + # Comma-separated list of subdirs to use. The first existing subdirectory + # found between those given will be used. If none is found or provided, the + # root of the repo directory will be used instead. + Subdir: + + # Any extra commands to prepare the source library + Prepare: + ''')) + srclib = fdroidserver.metadata.parse_txt_srclib('JSoup.txt') + self.assertDictEqual({'Repo': 'https://github.com/jhy/jsoup.git', + 'Repo Type': 'git', + 'Subdir': [''], + 'Prepare': ''}, + srclib) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 2c86d3802855cacdab5f08a99009fa19e4e09e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sun, 15 Dec 2019 17:27:27 +0100 Subject: [PATCH 0279/2775] srclib: no spaces in dict key --- fdroidserver/common.py | 4 ++-- fdroidserver/metadata.py | 5 ++++- tests/metadata.TestCase | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index bab6c3b9..59b58e34 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -773,7 +773,7 @@ def getvcs(vcstype, remote, local): def getsrclibvcs(name): if name not in fdroidserver.metadata.srclibs: raise VCSException("Missing srclib " + name) - return fdroidserver.metadata.srclibs[name]['Repo Type'] + return fdroidserver.metadata.srclibs[name]['RepoType'] class vcs: @@ -1838,7 +1838,7 @@ def getsrclib(spec, srclib_dir, subdir=None, basepath=False, sdir = os.path.join(srclib_dir, name) if not preponly: - vcs = getvcs(srclib["Repo Type"], srclib["Repo"], sdir) + vcs = getvcs(srclib["RepoType"], srclib["Repo"], sdir) vcs.srclib = (name, number, sdir) if ref: vcs.gotorevision(ref, refresh) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index fbf11a44..a17e4d69 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -709,7 +709,7 @@ def parse_txt_srclib(metadatapath): thisinfo = {} # Defaults for fields that come from metadata - thisinfo['Repo Type'] = '' + thisinfo['RepoType'] = '' thisinfo['Repo'] = '' thisinfo['Subdir'] = None thisinfo['Prepare'] = None @@ -731,6 +731,9 @@ def parse_txt_srclib(metadatapath): except ValueError: warn_or_exception(_("Invalid metadata in %s:%d") % (line, n)) + # collapse whitespaces in field names + f = f.replace(' ', '') + if f == "Subdir": thisinfo[f] = v.split(',') else: diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 08d4137c..0f3e3cfe 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -588,7 +588,7 @@ class MetadataTest(unittest.TestCase): ''')) srclib = fdroidserver.metadata.parse_txt_srclib('JSoup.txt') self.assertDictEqual({'Repo': 'https://github.com/jhy/jsoup.git', - 'Repo Type': 'git', + 'RepoType': 'git', 'Subdir': [''], 'Prepare': ''}, srclib) From 286220fe1101c7eb94e36dbdad6c471e8c5d8b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 16 Dec 2019 19:17:46 +0100 Subject: [PATCH 0280/2775] srclib: add test for getsrclibvcs --- tests/common.TestCase | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/common.TestCase b/tests/common.TestCase index 268d5dd4..acd0e887 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -34,7 +34,7 @@ import fdroidserver.signindex import fdroidserver.common import fdroidserver.metadata from testcommon import TmpCwd -from fdroidserver.exception import FDroidException +from fdroidserver.exception import FDroidException, VCSException class CommonTest(unittest.TestCase): @@ -1241,6 +1241,16 @@ class CommonTest(unittest.TestCase): self.assertEqual(123, fdroidserver.common.version_code_string_to_int('0000123')) self.assertEqual(-42, fdroidserver.common.version_code_string_to_int('-42')) + def test_getsrclibvcs(self): + fdroidserver.metadata.srclibs = {'somelib': {'RepoType': 'git'}, + 'yeslib': {'RepoType': 'hg'}, + 'nolib': {'RepoType': 'git-svn'}} + self.assertEqual(fdroidserver.common.getsrclibvcs('somelib'), 'git') + self.assertEqual(fdroidserver.common.getsrclibvcs('yeslib'), 'hg') + self.assertEqual(fdroidserver.common.getsrclibvcs('nolib'), 'git-svn') + with self.assertRaises(VCSException): + fdroidserver.common.getsrclibvcs('nonexistentlib') + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From fa7885063b568feea02adf9ec4929b25a24154b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 19 Dec 2019 22:55:14 +0100 Subject: [PATCH 0281/2775] scrlib: add test for getsrclib --- tests/common.TestCase | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/common.TestCase b/tests/common.TestCase index acd0e887..2ee7852f 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1251,6 +1251,53 @@ class CommonTest(unittest.TestCase): with self.assertRaises(VCSException): fdroidserver.common.getsrclibvcs('nonexistentlib') + def test_getsrclib_not_found(self): + fdroidserver.common.config = {'sdk_path': '', + 'java_paths': {}} + fdroidserver.metadata.srclibs = {} + + with self.assertRaisesRegex(VCSException, 'srclib SDL not found.'): + fdroidserver.common.getsrclib('SDL@release-2.0.3', 'srclib') + + def test_getsrclib_gotorevision_raw(self): + fdroidserver.common.config = {'sdk_path': '', + 'java_paths': {}} + fdroidserver.metadata.srclibs = {'SDL': {'RepoType': 'git', + 'Repo': ''}} + + vcs = mock.Mock() + + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.makedirs(os.path.join('srclib', 'SDL')) + with mock.patch('fdroidserver.common.getvcs', return_value=vcs): + ret = fdroidserver.common.getsrclib('SDL', 'srclib', raw=True) + self.assertEqual(vcs.srclib, ('SDL', None, 'srclib/SDL')) + self.assertEqual(ret, vcs) + + def test_getsrclib_gotorevision_ref(self): + fdroidserver.common.config = {'sdk_path': '', + 'java_paths': {}} + fdroidserver.metadata.srclibs = {'ACRA': {'RepoType': 'git', + 'Repo': 'https://github.com/ACRA/acra.git', + 'Subdir': None, + 'Prepare': None}} + + vcs = mock.Mock() + skm = mock.Mock() + dfm = mock.Mock() + + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.makedirs(os.path.join('srclib', 'ACRA')) + with mock.patch('fdroidserver.common.getvcs', return_value=vcs): + with mock.patch('fdroidserver.common.remove_signing_keys', skm): + with mock.patch('fdroidserver.common.remove_debuggable_flags', dfm): + ret = fdroidserver.common.getsrclib('ACRA@acra-4.6.2', 'srclib') + self.assertEqual(vcs.srclib, ('ACRA', None, 'srclib/ACRA')) + vcs.gotorevision.assert_called_once_with('acra-4.6.2', True) + skm.assert_called_once_with('srclib/ACRA') + dfm.assert_called_once_with('srclib/ACRA') + self.assertEqual(ret, ('ACRA', None, 'srclib/ACRA')) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From ee3d8d2f1833c91acee08f9ec5d04cb182c801fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 24 Dec 2019 00:42:29 +0100 Subject: [PATCH 0282/2775] srclib: yml parsing + tests for yml and txt --- fdroidserver/metadata.py | 41 ++++++++++ tests/metadata.TestCase | 170 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index a17e4d69..52c00d85 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -744,6 +744,43 @@ def parse_txt_srclib(metadatapath): return thisinfo +def parse_yml_srclib(metadatapath): + + thisinfo = {'RepoType': '', + 'Repo': '', + 'Subdir': None, + 'Prepare': None} + + if not os.path.exists(metadatapath): + warn_or_exception(_("Invalid scrlib metadata: '{file}' " + "does not exist" + .format(file=metadatapath))) + return thisinfo + + with open(metadatapath, "r", encoding="utf-8") as f: + try: + data = yaml.load(f, Loader=SafeLoader) + except yaml.error.YAMLError as e: + warn_or_exception(_("Invalid srclib metadata: could not " + "parse '{file}'" + .format(file=metadatapath))) + return thisinfo + + for key in data.keys(): + if key not in thisinfo.keys(): + warn_or_exception(_("Invalid srclib metadata: unknown key " + "'{key}' in '{file}'") + .format(key=key, file=metadatapath)) + return thisinfo + else: + if key == 'Subdir': + thisinfo[key] = str(data[key] or '').split(',') + else: + thisinfo[key] = str(data[key] or '') + + return thisinfo + + def read_srclibs(): """Read all srclib metadata. @@ -770,6 +807,10 @@ def read_srclibs(): srclibname = os.path.basename(metadatapath[:-4]) srclibs[srclibname] = parse_txt_srclib(metadatapath) + for metadatapath in sorted(glob.glob(os.path.join(srcdir, '*.yml'))): + srclibname = os.path.basename(metadatapath[:-4]) + srclibs[srclibname] = parse_yml_srclib(metadatapath) + def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): """Return a list of App instances sorted newest first diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 0f3e3cfe..844de8ae 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -571,6 +571,7 @@ class MetadataTest(unittest.TestCase): """)) def test_parse_txt_srclib(self): + fdroidserver.metadata.warnings_action = 'error' with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('JSoup.txt', 'w', encoding='utf-8') as f: f.write(textwrap.dedent('''\ @@ -593,6 +594,175 @@ class MetadataTest(unittest.TestCase): 'Prepare': ''}, srclib) + def test_parse_txt_srclib_simple(self): + fdroidserver.metadata.warnings_action = 'error' + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('simple.txt', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + # this should be simple + Repo Type:git + Repo:https://git.host/repo.git + ''')) + srclib = fdroidserver.metadata.parse_txt_srclib('simple.txt') + self.assertDictEqual({'Repo': 'https://git.host/repo.git', + 'RepoType': 'git', + 'Subdir': None, + 'Prepare': None}, + srclib) + + def test_parse_txt_srclib_simple_blanks(self): + fdroidserver.metadata.warnings_action = 'error' + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('simple.txt', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + # this should be simple + + Repo Type:git + + Repo:https://git.host/repo.git + + Subdir: + + Prepare: + ''')) + srclib = fdroidserver.metadata.parse_txt_srclib('simple.txt') + self.assertDictEqual({'Repo': 'https://git.host/repo.git', + 'RepoType': 'git', + 'Subdir': [''], + 'Prepare': ''}, + srclib) + + def test_parse_txt_srclib_Changelog_cketti(self): + fdroidserver.metadata.warnings_action = 'error' + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('Changelog-cketti.txt', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + Repo Type:git + Repo:https://github.com/cketti/ckChangeLog + + Subdir:library,ckChangeLog/src/main + Prepare:[ -f project.properties ] || echo 'source.dir=java' > ant.properties && echo -e 'android.library=true\\ntarget=android-19' > project.properties + ''')) + srclib = fdroidserver.metadata.parse_txt_srclib('Changelog-cketti.txt') + self.assertDictEqual({'Repo': 'https://github.com/cketti/ckChangeLog', + 'RepoType': 'git', + 'Subdir': ['library', 'ckChangeLog/src/main'], + 'Prepare': "[ -f project.properties ] || echo 'source.dir=java' > " + "ant.properties && echo -e " + "'android.library=true\\ntarget=android-19' > project.properties"}, + srclib) + + def test_parse_yml_srclib_unknown_key(self): + fdroidserver.metadata.warnings_action = 'error' + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('test.yml', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + RepoType: git + Repo: https://example.com/test.git + Evil: I should not be here. + ''')) + with self.assertRaisesRegex(MetaDataException, + "Invalid srclib metadata: " + "unknown key 'Evil' in " + "'test.yml'"): + fdroidserver.metadata.parse_yml_srclib('test.yml') + + def test_parse_yml_srclib_does_not_exists(self): + fdroidserver.metadata.warnings_action = 'error' + with self.assertRaisesRegex(MetaDataException, + "Invalid scrlib metadata: " + "'non/existent-test-srclib.yml' " + "does not exist"): + fdroidserver.metadata.parse_yml_srclib('non/existent-test-srclib.yml') + + def test_parse_yml_srclib_simple(self): + fdroidserver.metadata.warnings_action = 'error' + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('simple.yml', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + # this should be simple + RepoType: git + Repo: https://git.host/repo.git + ''')) + srclib = fdroidserver.metadata.parse_yml_srclib('simple.yml') + self.assertDictEqual({'Repo': 'https://git.host/repo.git', + 'RepoType': 'git', + 'Subdir': None, + 'Prepare': None}, + srclib) + + def test_parse_yml_srclib_simple_with_blanks(self): + fdroidserver.metadata.warnings_action = 'error' + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('simple.yml', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + # this should be simple + + RepoType: git + + Repo: https://git.host/repo.git + + Subdir: + + Prepare: + ''')) + srclib = fdroidserver.metadata.parse_yml_srclib('simple.yml') + self.assertDictEqual({'Repo': 'https://git.host/repo.git', + 'RepoType': 'git', + 'Subdir': [''], + 'Prepare': ''}, + srclib) + + def test_parse_yml_srclib_Changelog_cketti(self): + fdroidserver.metadata.warnings_action = 'error' + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('Changelog-cketti.yml', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + RepoType: git + Repo: https://github.com/cketti/ckChangeLog + + Subdir: library,ckChangeLog/src/main + Prepare: "[ -f project.properties ] || echo 'source.dir=java' > ant.properties && echo -e 'android.library=true\\\\ntarget=android-19' > project.properties" + ''')) + srclib = fdroidserver.metadata.parse_yml_srclib('Changelog-cketti.yml') + self.assertDictEqual({'Repo': 'https://github.com/cketti/ckChangeLog', + 'RepoType': 'git', + 'Subdir': ['library', 'ckChangeLog/src/main'], + 'Prepare': "[ -f project.properties ] || echo 'source.dir=java' > " + "ant.properties && echo -e " + "'android.library=true\\ntarget=android-19' > project.properties"}, + srclib) + + def test_read_srclibs(self): + fdroidserver.metadata.warnings_action = 'error' + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir('srclibs') + with open('srclibs/simple.yml', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + RepoType: git + Repo: https://git.host/repo.git + ''')) + with open('srclibs/simple-wb.txt', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + # this should be simple + Repo Type:git + Repo:https://git.host/repo.git + + Subdir: + Prepare: + ''')) + fdroidserver.metadata.read_srclibs() + print(fdroidserver.metadata.srclibs) + self.assertDictEqual(fdroidserver.metadata.srclibs, + {'simple-wb': {'RepoType': 'git', + 'Repo': 'https://git.host/repo.git', + 'Subdir': [''], + 'Prepare': ''}, + 'simple': {'RepoType': 'git', + 'Repo': 'https://git.host/repo.git', + 'Subdir': None, + 'Prepare': None}}) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From aa020af040e087c97eb4fa5ed85fda52bbc45217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 24 Dec 2019 08:35:27 +0100 Subject: [PATCH 0283/2775] srclibs: forward yml parsing error cause --- fdroidserver/metadata.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 52c00d85..d01736cf 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -42,12 +42,15 @@ srclibs = None warnings_action = None -def warn_or_exception(value): +def warn_or_exception(value, cause=None): '''output warning or Exception depending on -W''' if warnings_action == 'ignore': pass elif warnings_action == 'error': - raise MetaDataException(value) + if cause: + raise MetaDataException(value) from cause + else: + raise MetaDataException(value) else: logging.warning(value) @@ -763,14 +766,15 @@ def parse_yml_srclib(metadatapath): except yaml.error.YAMLError as e: warn_or_exception(_("Invalid srclib metadata: could not " "parse '{file}'" - .format(file=metadatapath))) + .format(file=metadatapath)), + e) return thisinfo for key in data.keys(): if key not in thisinfo.keys(): warn_or_exception(_("Invalid srclib metadata: unknown key " "'{key}' in '{file}'") - .format(key=key, file=metadatapath)) + .format(key=key, file=metadatapath)) return thisinfo else: if key == 'Subdir': From 58776da694c86a7b09c629fa04b6a7f5dc391ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Mon, 3 Feb 2020 23:30:23 +0100 Subject: [PATCH 0284/2775] get tests working --- tests/metadata.TestCase | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 844de8ae..bc141246 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -725,16 +725,17 @@ class MetadataTest(unittest.TestCase): Prepare: "[ -f project.properties ] || echo 'source.dir=java' > ant.properties && echo -e 'android.library=true\\\\ntarget=android-19' > project.properties" ''')) srclib = fdroidserver.metadata.parse_yml_srclib('Changelog-cketti.yml') - self.assertDictEqual({'Repo': 'https://github.com/cketti/ckChangeLog', + self.assertDictEqual(srclib, + {'Repo': 'https://github.com/cketti/ckChangeLog', 'RepoType': 'git', 'Subdir': ['library', 'ckChangeLog/src/main'], 'Prepare': "[ -f project.properties ] || echo 'source.dir=java' > " "ant.properties && echo -e " - "'android.library=true\\ntarget=android-19' > project.properties"}, - srclib) + "'android.library=true\\ntarget=android-19' > project.properties"}) def test_read_srclibs(self): fdroidserver.metadata.warnings_action = 'error' + fdroidserver.metadata.srclibs = None with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): os.mkdir('srclibs') with open('srclibs/simple.yml', 'w', encoding='utf-8') as f: @@ -752,7 +753,6 @@ class MetadataTest(unittest.TestCase): Prepare: ''')) fdroidserver.metadata.read_srclibs() - print(fdroidserver.metadata.srclibs) self.assertDictEqual(fdroidserver.metadata.srclibs, {'simple-wb': {'RepoType': 'git', 'Repo': 'https://git.host/repo.git', From 1ac7d612b10094bb8ee1ad3ad92599d804fb8023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sat, 29 Feb 2020 13:42:12 +0100 Subject: [PATCH 0285/2775] yml srclibs: support multiline Prepare --- fdroidserver/metadata.py | 2 ++ tests/metadata.TestCase | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index d01736cf..e86faa70 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -779,6 +779,8 @@ def parse_yml_srclib(metadatapath): else: if key == 'Subdir': thisinfo[key] = str(data[key] or '').split(',') + elif key == 'Prepare' and isinstance(data[key], list): + thisinfo[key] = ' && '.join(data[key]) else: thisinfo[key] = str(data[key] or '') diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index bc141246..7e7edcf8 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -733,6 +733,43 @@ class MetadataTest(unittest.TestCase): "ant.properties && echo -e " "'android.library=true\\ntarget=android-19' > project.properties"}) + def test_read_srclibs_yml_prepare_list(self): + fdroidserver.metadata.warnings_action = 'error' + fdroidserver.metadata.srclibs = None + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir('srclibs') + with open('srclibs/with-list.yml', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + # this should be simple + RepoType: git + Repo: https://git.host/repo.git + + Subdir: + Prepare: + - The Matrix is a system, Neo. + - That system is our enemy. + - But when you're inside, you look around, what do you see? + - Businessmen, teachers, lawyers, carpenters. + - The very minds of the people we are trying to save. + - But until we do, these people are still a part of that system and that makes them our enemy. + - You have to understand, most of these people are not ready to be unplugged. + - And many of them are so inert, so hopelessly dependent on the system that they will fight to protect it. + ''')) + fdroidserver.metadata.read_srclibs() + self.maxDiff = None + self.assertDictEqual(fdroidserver.metadata.srclibs, + {'with-list': {'RepoType': 'git', + 'Repo': 'https://git.host/repo.git', + 'Subdir': [''], + 'Prepare': 'The Matrix is a system, Neo. && ' + 'That system is our enemy. && ' + 'But when you\'re inside, you look around, what do you see? && ' + 'Businessmen, teachers, lawyers, carpenters. && ' + 'The very minds of the people we are trying to save. && ' + 'But until we do, these people are still a part of that system and that makes them our enemy. && ' + 'You have to understand, most of these people are not ready to be unplugged. && ' + 'And many of them are so inert, so hopelessly dependent on the system that they will fight to protect it.'}}) + def test_read_srclibs(self): fdroidserver.metadata.warnings_action = 'error' fdroidserver.metadata.srclibs = None From 5741e6930b853a97c14bb36b561c4eacd76ad414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sat, 29 Feb 2020 15:50:06 +0100 Subject: [PATCH 0286/2775] yml srclibs: support Subdir as list --- fdroidserver/metadata.py | 7 ++++++- tests/metadata.TestCase | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index e86faa70..3f79db43 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -778,7 +778,12 @@ def parse_yml_srclib(metadatapath): return thisinfo else: if key == 'Subdir': - thisinfo[key] = str(data[key] or '').split(',') + if isinstance(data[key], str): + thisinfo[key] = data[key].split(',') + elif isinstance(data[key], list): + thisinfo[key] = data[key] + elif data[key] is None: + thisinfo[key] = [''] elif key == 'Prepare' and isinstance(data[key], list): thisinfo[key] = ' && '.join(data[key]) else: diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 7e7edcf8..dedbdd3f 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -733,6 +733,44 @@ class MetadataTest(unittest.TestCase): "ant.properties && echo -e " "'android.library=true\\ntarget=android-19' > project.properties"}) + def test_read_srclibs_yml_subdir_list(self): + fdroidserver.metadata.warnings_action = 'error' + fdroidserver.metadata.srclibs = None + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir('srclibs') + with open('srclibs/with-list.yml', 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + # this should be simple + RepoType: git + Repo: https://git.host/repo.git + + Subdir: + - This is your last chance. + - After this, there is no turning back. + - You take the blue pill—the story ends, + - you wake up in your bed + - and believe whatever you want to believe. + - You take the red pill—you stay in Wonderland + - and I show you how deep the rabbit-hole goes. + Prepare: + There is a difference between knowing the path + and walking the path. + ''')) + fdroidserver.metadata.read_srclibs() + self.maxDiff = None + self.assertDictEqual(fdroidserver.metadata.srclibs, + {'with-list': {'RepoType': 'git', + 'Repo': 'https://git.host/repo.git', + 'Subdir': ['This is your last chance.', + 'After this, there is no turning back.', + 'You take the blue pill—the story ends,', + 'you wake up in your bed', + 'and believe whatever you want to believe.', + 'You take the red pill—you stay in Wonderland', + 'and I show you how deep the rabbit-hole goes.'], + 'Prepare': 'There is a difference between knowing the path ' + 'and walking the path.'}}) + def test_read_srclibs_yml_prepare_list(self): fdroidserver.metadata.warnings_action = 'error' fdroidserver.metadata.srclibs = None From 8344e510f6d202b2f3c987e15512dee9590c40ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 9 Apr 2020 11:41:15 +0200 Subject: [PATCH 0287/2775] yml srclibs: changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10cf3c6f..32ff73dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ([!656](https://gitlab.com/fdroid/fdroidserver/merge_requests/656)) * add SHA256 to filename of repo graphics ([!669](https://gitlab.com/fdroid/fdroidserver/merge_requests/669)) +* support for srclibs metadata in YAML format + ([!700](https://gitlab.com/fdroid/fdroidserver/merge_requests/700)) ### Fixed * fix build-logs dissapearing when deploying From 911e86fc874f7721ad53f3bf48618e88949c1692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 16 Apr 2020 11:32:37 +0200 Subject: [PATCH 0288/2775] support copying yml srclibs to buildserver vm during builds --- fdroidserver/build.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index dbcccde6..41467533 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -203,8 +203,18 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): send_dir(lib) # Copy the metadata file too... ftp.chdir(posixpath.join(homedir, 'srclibs')) - ftp.put(os.path.join('srclibs', name + '.txt'), - name + '.txt') + if os.path.isfile(os.path.join('srclibs', name + '.yml')): + ftp.put(os.path.join('srclibs', name + '.yml'), + name + '.yml') + elif os.path.isfile(os.path.join('srclibs', name + '.txt')): + ftp.put(os.path.join('srclibs', name + '.txt'), + name + '.txt') + else: + raise BuildException("can not find metadata file for " + "'{name}', please make sure it is " + "present in your 'srclibs' folder." + "(supported formats: txt, yml)" + .format(name=name)) # Copy the main app source code # (no need if it's a srclib) if (not basesrclib) and os.path.exists(build_dir): From 30c654459ff76ccbd05d4545621b1242353ff8ac Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Fri, 17 Apr 2020 23:26:06 +0200 Subject: [PATCH 0289/2775] Use ImportError for Python < 3.6 (Closes: !734) ModuleNotFoundError is a subclass of ImportError, so this should not change anything. --- fdroidserver/vmtools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index 64d630e3..829d22ca 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -435,7 +435,7 @@ class LibvirtBuildVm(FDroidBuildVm): with libarchive.file_writer(output, 'gnutar', 'gzip') as tar: logging.debug('adding files to box %s ...', output) tar.add_files('metadata.json', 'Vagrantfile', 'box.img') - except (ModuleNotFoundError, AttributeError): + except (ImportError, AttributeError): with tarfile.open(output, 'w:gz') as tar: logging.debug('adding metadata.json to box %s ...', output) tar.add('metadata.json') From 4e69ff582f9f032e9c4204e1d69c14cd55621363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 24 Apr 2020 15:47:31 +0200 Subject: [PATCH 0290/2775] run yamllint when parsing failed and also on fdroid lint runs --- fdroidserver/common.py | 17 +++++++++++++++++ fdroidserver/lint.py | 7 +++++++ fdroidserver/metadata.py | 21 +++++++++++++++------ tests/metadata.TestCase | 20 ++++++++++---------- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 59b58e34..23942b49 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -42,6 +42,8 @@ import urllib.request import zipfile import tempfile import json +import yamllint.config +import yamllint.linter # TODO change to only import defusedxml once its installed everywhere try: @@ -3734,3 +3736,18 @@ def force_exit(exitvalue=0): sys.stdout.flush() sys.stderr.flush() os._exit(exitvalue) + + +YAML_LINT_CONFIG = {'extends': 'default', + 'rules': {'document-start': 'disable', + 'line-length': 'disable', + 'truthy': 'disable'}} + + +def run_yamllint(path, indent=0): + result = [] + with open(path, 'r', encoding='utf-8') as f: + problems = yamllint.linter.run(f, yamllint.config.YamlLintConfig(json.dumps(YAML_LINT_CONFIG))) + for problem in problems: + result.append(' ' * indent + path + ':' + str(problem.line) + ': ' + problem.message) + return '\n'.join(result) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 276bf555..4e097b2a 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -600,6 +600,13 @@ def main(): if app.Disabled: continue + if len(options.appid) > 0: + ymlpath = os.path.join('metadata', appid + '.yml') + if os.path.isfile(ymlpath): + yamllintresult = common.run_yamllint(ymlpath) + if yamllintresult != '': + print(yamllintresult) + app_check_funcs = [ check_app_field_types, check_regexes, diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 3f79db43..99764ac4 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -747,7 +747,7 @@ def parse_txt_srclib(metadatapath): return thisinfo -def parse_yml_srclib(metadatapath): +def parse_yaml_srclib(metadatapath): thisinfo = {'RepoType': '', 'Repo': '', @@ -765,9 +765,11 @@ def parse_yml_srclib(metadatapath): data = yaml.load(f, Loader=SafeLoader) except yaml.error.YAMLError as e: warn_or_exception(_("Invalid srclib metadata: could not " - "parse '{file}'" - .format(file=metadatapath)), - e) + "parse '{file}'") + .format(file=metadatapath) + '\n' + + fdroidserver.common.run_yamllint(metadatapath, + indent=4), + cause=e) return thisinfo for key in data.keys(): @@ -820,7 +822,7 @@ def read_srclibs(): for metadatapath in sorted(glob.glob(os.path.join(srcdir, '*.yml'))): srclibname = os.path.basename(metadatapath[:-4]) - srclibs[srclibname] = parse_yml_srclib(metadatapath) + srclibs[srclibname] = parse_yaml_srclib(metadatapath) def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): @@ -1102,7 +1104,14 @@ def parse_json_metadata(mf, app): def parse_yaml_metadata(mf, app): - yamldata = yaml.load(mf, Loader=SafeLoader) + try: + yamldata = yaml.load(mf, Loader=SafeLoader) + except yaml.YAMLError as e: + warn_or_exception(_("could not parse '{path}'") + .format(path=mf.name) + '\n' + + fdroidserver.common.run_yamllint(mf.name, + indent=4), + cause=e) deprecated_in_yaml = ['Provides'] diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index dedbdd3f..d52cd991 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -652,7 +652,7 @@ class MetadataTest(unittest.TestCase): "'android.library=true\\ntarget=android-19' > project.properties"}, srclib) - def test_parse_yml_srclib_unknown_key(self): + def test_parse_yaml_srclib_unknown_key(self): fdroidserver.metadata.warnings_action = 'error' with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('test.yml', 'w', encoding='utf-8') as f: @@ -665,17 +665,17 @@ class MetadataTest(unittest.TestCase): "Invalid srclib metadata: " "unknown key 'Evil' in " "'test.yml'"): - fdroidserver.metadata.parse_yml_srclib('test.yml') + fdroidserver.metadata.parse_yaml_srclib('test.yml') - def test_parse_yml_srclib_does_not_exists(self): + def test_parse_yaml_srclib_does_not_exists(self): fdroidserver.metadata.warnings_action = 'error' with self.assertRaisesRegex(MetaDataException, "Invalid scrlib metadata: " "'non/existent-test-srclib.yml' " "does not exist"): - fdroidserver.metadata.parse_yml_srclib('non/existent-test-srclib.yml') + fdroidserver.metadata.parse_yaml_srclib('non/existent-test-srclib.yml') - def test_parse_yml_srclib_simple(self): + def test_parse_yaml_srclib_simple(self): fdroidserver.metadata.warnings_action = 'error' with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('simple.yml', 'w', encoding='utf-8') as f: @@ -684,14 +684,14 @@ class MetadataTest(unittest.TestCase): RepoType: git Repo: https://git.host/repo.git ''')) - srclib = fdroidserver.metadata.parse_yml_srclib('simple.yml') + srclib = fdroidserver.metadata.parse_yaml_srclib('simple.yml') self.assertDictEqual({'Repo': 'https://git.host/repo.git', 'RepoType': 'git', 'Subdir': None, 'Prepare': None}, srclib) - def test_parse_yml_srclib_simple_with_blanks(self): + def test_parse_yaml_srclib_simple_with_blanks(self): fdroidserver.metadata.warnings_action = 'error' with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('simple.yml', 'w', encoding='utf-8') as f: @@ -706,14 +706,14 @@ class MetadataTest(unittest.TestCase): Prepare: ''')) - srclib = fdroidserver.metadata.parse_yml_srclib('simple.yml') + srclib = fdroidserver.metadata.parse_yaml_srclib('simple.yml') self.assertDictEqual({'Repo': 'https://git.host/repo.git', 'RepoType': 'git', 'Subdir': [''], 'Prepare': ''}, srclib) - def test_parse_yml_srclib_Changelog_cketti(self): + def test_parse_yaml_srclib_Changelog_cketti(self): fdroidserver.metadata.warnings_action = 'error' with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('Changelog-cketti.yml', 'w', encoding='utf-8') as f: @@ -724,7 +724,7 @@ class MetadataTest(unittest.TestCase): Subdir: library,ckChangeLog/src/main Prepare: "[ -f project.properties ] || echo 'source.dir=java' > ant.properties && echo -e 'android.library=true\\\\ntarget=android-19' > project.properties" ''')) - srclib = fdroidserver.metadata.parse_yml_srclib('Changelog-cketti.yml') + srclib = fdroidserver.metadata.parse_yaml_srclib('Changelog-cketti.yml') self.assertDictEqual(srclib, {'Repo': 'https://github.com/cketti/ckChangeLog', 'RepoType': 'git', From 975538a7a7757b09a08c8a8b377a4055258ff32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 24 Apr 2020 15:12:41 +0200 Subject: [PATCH 0291/2775] make yamllint optional --- fdroidserver/common.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 23942b49..c6ca2fb8 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -42,8 +42,6 @@ import urllib.request import zipfile import tempfile import json -import yamllint.config -import yamllint.linter # TODO change to only import defusedxml once its installed everywhere try: @@ -3745,6 +3743,13 @@ YAML_LINT_CONFIG = {'extends': 'default', def run_yamllint(path, indent=0): + + try: + import yamllint.config + import yamllint.linter + except ImportError: + return '' + result = [] with open(path, 'r', encoding='utf-8') as f: problems = yamllint.linter.run(f, yamllint.config.YamlLintConfig(json.dumps(YAML_LINT_CONFIG))) From d24484a9501a51f37187fe363e55f8902f8e98a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 24 Apr 2020 15:22:42 +0200 Subject: [PATCH 0292/2775] simple testcase for common.run_yamllint --- tests/common.TestCase | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/common.TestCase b/tests/common.TestCase index 2ee7852f..d5354284 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1298,6 +1298,32 @@ class CommonTest(unittest.TestCase): dfm.assert_called_once_with('srclib/ACRA') self.assertEqual(ret, ('ACRA', None, 'srclib/ACRA')) + def test_run_yamllint_wellformed(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('wellformed.yml', 'w') as f: + f.write(textwrap.dedent('''\ + yaml: + file: + - for + - test + purposeses: true + ''')) + result = fdroidserver.common.run_yamllint('wellformed.yml') + self.assertEqual(result, '') + + def test_run_yamllint_malformed(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('malformed.yml', 'w') as f: + f.write(textwrap.dedent('''\ + yaml: + - that + fails + - test + ''')) + result = fdroidserver.common.run_yamllint('malformed.yml') + self.assertIsNotNone(result) + self.assertNotEqual(result, '') + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 270c55560bebafb4f0ca76a213ee8b208f279ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 24 Apr 2020 15:31:59 +0200 Subject: [PATCH 0293/2775] add yamllint to dependency lists --- buildserver/provision-apt-get-install | 1 + setup.py | 1 + 2 files changed, 2 insertions(+) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index 2ec3d2f9..28dc05ad 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -119,6 +119,7 @@ packages=" unzip xsltproc yasm + yamllint zip zlib1g:i386 " diff --git a/setup.py b/setup.py index 40abdb19..bade76bb 100755 --- a/setup.py +++ b/setup.py @@ -86,6 +86,7 @@ setup(name='fdroidserver', 'qrcode', 'ruamel.yaml >= 0.15', 'requests >= 2.5.2, != 2.11.0, != 2.12.2, != 2.18.0', + 'yamllint', ], classifiers=[ 'Development Status :: 4 - Beta', From ed2c5f6f5bb21c6570c436c6f10c151bed1592e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sat, 25 Apr 2020 15:57:21 +0200 Subject: [PATCH 0294/2775] run yamllint on srclibs when running 'fdroid lint' --- fdroidserver/lint.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 4e097b2a..000d2092 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -600,13 +600,29 @@ def main(): if app.Disabled: continue + # only run yamllint when linting individual apps. if len(options.appid) > 0: + + # run yamllint on app metadata ymlpath = os.path.join('metadata', appid + '.yml') if os.path.isfile(ymlpath): yamllintresult = common.run_yamllint(ymlpath) if yamllintresult != '': print(yamllintresult) + # run yamllint on srclib metadata + srclibs = set() + for build in app.builds: + for srclib in build.srclibs: + srclibs.add(srclib) + for srclib in srclibs: + name, numer, libdir = common.getsrclib(srclib, 'srclibs', prepare=False, refresh=False) + srclibpath = os.path.join('srclibs', name + '.yml') + if os.path.isfile(srclibpath): + yamllintresult = common.run_yamllint(srclibpath) + if yamllintresult != '': + print(yamllintresult) + app_check_funcs = [ check_app_field_types, check_regexes, From 8285f3d759fecbc59dd4555e04bb391c035361ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sat, 25 Apr 2020 15:59:51 +0200 Subject: [PATCH 0295/2775] add changelog entry for yamllint feature --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32ff73dc..de4c33a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ([!669](https://gitlab.com/fdroid/fdroidserver/merge_requests/669)) * support for srclibs metadata in YAML format ([!700](https://gitlab.com/fdroid/fdroidserver/merge_requests/700)) +* check srclibs and app-metadata files with yamllint + ([!721](https://gitlab.com/fdroid/fdroidserver/merge_requests/721)) ### Fixed * fix build-logs dissapearing when deploying From b076e8cba7644eed41a0eec1c69e7816112ae046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sat, 25 Apr 2020 17:22:48 +0200 Subject: [PATCH 0296/2775] add srclib spec parser --- fdroidserver/common.py | 32 +++++++++++++++++++++++++++++++- fdroidserver/lint.py | 2 +- tests/common.TestCase | 18 +++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index c6ca2fb8..d7a45d2e 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -63,7 +63,7 @@ import fdroidserver.metadata import fdroidserver.lint from fdroidserver import _ from fdroidserver.exception import FDroidException, VCSException, NoSubmodulesException,\ - BuildException, VerificationException + BuildException, VerificationException, MetaDataException from .asynchronousfilereader import AsynchronousFileReader # The path to this fdroidserver distribution @@ -1808,6 +1808,36 @@ def get_app_from_url(url): return app +def parse_srclib_spec(spec): + + if type(spec) != str: + raise MetaDataException(_("can not parse scrlib spec " + "(not a string): '{}'") + .format(spec)) + + tokens = spec.split('@') + if len(tokens) > 2: + raise MetaDataException(_("could not parse srclib spec " + "(too many '@' signs): '{}'") + .format(spec)) + elif len(tokens) < 2: + raise MetaDataException(_("could not parse srclib spec " + "(no ref specified): '{}'") + .format(spec)) + + name = tokens[0] + ref = tokens[1] + number = None + subdir = None + + if ':' in name: + number, name = name.split(':', 1) + if '/' in name: + name, subdir = name.split('/', 1) + + return (name, ref, number, subdir) + + def getsrclib(spec, srclib_dir, subdir=None, basepath=False, raw=False, prepare=True, preponly=False, refresh=True, build=None): diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 000d2092..586eefbc 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -616,7 +616,7 @@ def main(): for srclib in build.srclibs: srclibs.add(srclib) for srclib in srclibs: - name, numer, libdir = common.getsrclib(srclib, 'srclibs', prepare=False, refresh=False) + name, ref, number, subdir = common.parse_srclib_spec(srclib) srclibpath = os.path.join('srclibs', name + '.yml') if os.path.isfile(srclibpath): yamllintresult = common.run_yamllint(srclibpath) diff --git a/tests/common.TestCase b/tests/common.TestCase index d5354284..93fbedd3 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -34,7 +34,7 @@ import fdroidserver.signindex import fdroidserver.common import fdroidserver.metadata from testcommon import TmpCwd -from fdroidserver.exception import FDroidException, VCSException +from fdroidserver.exception import FDroidException, VCSException, MetaDataException class CommonTest(unittest.TestCase): @@ -1014,6 +1014,22 @@ class CommonTest(unittest.TestCase): subdir = fdroidserver.common.get_gradle_subdir(build_dir, paths) self.assertEqual(subdirs[f], subdir) + def test_parse_srclib_spec_good(self): + self.assertEqual(fdroidserver.common.parse_srclib_spec('osmand-external-skia@android/oreo'), + ('osmand-external-skia', 'android/oreo', None, None)) + self.assertEqual(fdroidserver.common.parse_srclib_spec('1:appcompat@v7'), + ('appcompat', 'v7', '1', None)) + self.assertEqual(fdroidserver.common.parse_srclib_spec('1:Support/v7/appcompat@android-4.4_r1.1'), + ('Support', 'android-4.4_r1.1', '1', 'v7/appcompat')) + + def test_parse_srclib_spec_bad(self): + with self.assertRaises(MetaDataException): + self.assertEqual(fdroidserver.common.parse_srclib_spec(None)) + with self.assertRaises(MetaDataException): + self.assertEqual(fdroidserver.common.parse_srclib_spec('no-ref')) + with self.assertRaises(MetaDataException): + self.assertEqual(fdroidserver.common.parse_srclib_spec('@multi@at-signs@')) + def test_bad_urls(self): for url in ('asdf', 'file://thing.git', From 810a6587df14f46b109a3b04b110249890491dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Sat, 25 Apr 2020 17:39:23 +0200 Subject: [PATCH 0297/2775] add --force-yamllint option to lint --- fdroidserver/lint.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 586eefbc..36e47621 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -574,6 +574,9 @@ def main(): common.setup_global_opts(parser) parser.add_argument("-f", "--format", action="store_true", default=False, help=_("Also warn about formatting issues, like rewritemeta -l")) + parser.add_argument('--force-yamllint', action="store_true", default=False, + help=_("When linting the entire repository yamllint is disabled by default. " + "This option forces yamllint regardless.")) parser.add_argument("appid", nargs='*', help=_("applicationId in the form APPID")) metadata.add_metadata_arguments(parser) options = parser.parse_args() @@ -601,7 +604,7 @@ def main(): continue # only run yamllint when linting individual apps. - if len(options.appid) > 0: + if len(options.appid) > 0 or options.force_yamllint: # run yamllint on app metadata ymlpath = os.path.join('metadata', appid + '.yml') From 99ef3a8626accdf16d73e17eab7d9481f38c8c88 Mon Sep 17 00:00:00 2001 From: relan Date: Fri, 8 May 2020 10:30:28 +0300 Subject: [PATCH 0298/2775] Add Gradle 6.4 --- gradlew-fdroid | 3 ++- makebuildserver | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index eacfc759..aaf5814c 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -135,6 +135,7 @@ get_sha() { '6.2.1') echo 'a68ca7ba57f3404c3f6fc1f70a02d3a7d78652e6b46bbfaff83fc9a17168c279' ;; '6.2.2') echo '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17' ;; '6.3') echo '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768' ;; + '6.4') echo 'b888659f637887e759749f6226ddfcb1cb04f828c58c41279de73c463fdbacc9' ;; *) exit 1 esac } @@ -155,7 +156,7 @@ d_plugin_k=(3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 d_plugin_v=(5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 64d53fbb..2029e467 100755 --- a/makebuildserver +++ b/makebuildserver @@ -370,6 +370,8 @@ CACHE_FILES = [ '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17'), ('https://services.gradle.org/distributions/gradle-6.3-bin.zip', '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768'), + ('https://services.gradle.org/distributions/gradle-6.4-bin.zip', + 'b888659f637887e759749f6226ddfcb1cb04f828c58c41279de73c463fdbacc9'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From db96753902a430142ee09b98db77103154cb4412 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 11 May 2020 10:23:26 -0300 Subject: [PATCH 0299/2775] Fix nightly --archive-older command line option --- fdroidserver/nightly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index ae3aa0e3..e1d599cc 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -102,7 +102,7 @@ def main(): help=_('The file to be included in the repo (path or glob)')) parser.add_argument("--no-checksum", action="store_true", default=False, help=_("Don't use rsync checksums")) - parser.add_argument("--archive-older", default=20, + parser.add_argument("--archive-older", type=int, default=20, help=_("Set maximum releases in repo before older ones are archived")) # TODO add --with-btlog options = parser.parse_args() From 052e22284be2c288b9afbe8cdcf70058f421237c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 8 May 2020 11:42:59 +0200 Subject: [PATCH 0300/2775] gitlab-ci: show clear error message when one step of job fails --- .gitlab-ci.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e3ce7be9..25d2e11c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -142,14 +142,15 @@ lint_format_safety_bandit_checks: - python3 -m ensurepip - $pip install Babel 'bandit<1.6.0' pycodestyle pyflakes 'pylint<2.0' safety - export EXITVALUE=0 - - ./hooks/pre-commit || export EXITVALUE=1 - - ./tests/test-gradlew-fdroid || export EXITVALUE=1 + - function set_error() { export EXITVALUE=1; printf "\x1b[31mERROR `history|tail -2|head -1|cut -b 6-500`\x1b[0m\n"; } + - ./hooks/pre-commit || set_error + - ./tests/test-gradlew-fdroid || set_error - bandit -ii -s B110,B322,B404,B408,B410,B603,B607 -r $CI_PROJECT_DIR fdroid - || export EXITVALUE=1 - - safety check --full-report || export EXITVALUE=1 + || set_error + - safety check --full-report || set_error - pylint --rcfile=.pylint-rcfile --output-format=colorized --reports=n fdroid makebuildserver @@ -157,9 +158,9 @@ lint_format_safety_bandit_checks: fdroidserver/*.py tests/*.py tests/*.TestCase - || export EXITVALUE=1 + || set_error - apk add --no-cache gettext make - - make -C locale compile || export EXITVALUE=1 + - make -C locale compile || set_error - rm -f locale/*/*/*.mo - pybabel compile --domain=fdroidserver --directory locale 2>&1 | (grep -F "error:" && exit 1) || true - exit $EXITVALUE From 3282687f9e2f3d775232753da84faf3ee5eb751f Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 11 May 2020 10:23:26 -0300 Subject: [PATCH 0301/2775] Fix nightly --archive-older command line option --- fdroidserver/nightly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 1b7fb76d..b67a4097 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -102,7 +102,7 @@ def main(): help=_('The file to be included in the repo (path or glob)')) parser.add_argument("--no-checksum", action="store_true", default=False, help=_("Don't use rsync checksums")) - parser.add_argument("--archive-older", default=20, + parser.add_argument("--archive-older", type=int, default=20, help=_("Set maximum releases in repo before older ones are archived")) # TODO add --with-btlog options = parser.parse_args() From 0700242416f07847c507dfb0b9498cdf515f68e8 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 8 May 2020 12:29:54 +0200 Subject: [PATCH 0302/2775] gitlab-ci: use latest pylint to avoid safety error about vuln --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 25d2e11c..3832c933 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -138,9 +138,9 @@ lint_format_safety_bandit_checks: variables: LANG: C.UTF-8 script: - - apk add --no-cache bash dash ca-certificates python3 + - apk add --no-cache bash build-base dash ca-certificates gcc python3 python3-dev - python3 -m ensurepip - - $pip install Babel 'bandit<1.6.0' pycodestyle pyflakes 'pylint<2.0' safety + - $pip install Babel 'bandit<1.6.0' pycodestyle pyflakes pylint safety - export EXITVALUE=0 - function set_error() { export EXITVALUE=1; printf "\x1b[31mERROR `history|tail -2|head -1|cut -b 6-500`\x1b[0m\n"; } - ./hooks/pre-commit || set_error From 13ac46af07f6e9ccf285da11e81e7990c3deacbc Mon Sep 17 00:00:00 2001 From: relan Date: Fri, 8 May 2020 10:41:17 +0300 Subject: [PATCH 0303/2775] makebuildserver: upgrade NDK r21 to r21b --- buildserver/config.buildserver.py | 2 +- buildserver/provision-android-ndk | 2 +- examples/config.py | 2 +- makebuildserver | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index f54f126e..66aaaf2b 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -11,7 +11,7 @@ ndk_paths = { 'r18b': "/home/vagrant/android-ndk/r18b", 'r19c': "/home/vagrant/android-ndk/r19c", 'r20b': "/home/vagrant/android-ndk/r20b", - 'r21': "/home/vagrant/android-ndk/r21", + 'r21b': "/home/vagrant/android-ndk/r21b", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index 44498dd7..32dd230b 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21b; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/examples/config.py b/examples/config.py index e46116db..e2fa05d7 100644 --- a/examples/config.py +++ b/examples/config.py @@ -22,7 +22,7 @@ # 'r18b': None, # 'r19c': None, # 'r20b': None, -# 'r21': None, +# 'r21b': None, # } # Directory to store downloaded tools in (i.e. gradle versions) diff --git a/makebuildserver b/makebuildserver index 2029e467..922120b5 100755 --- a/makebuildserver +++ b/makebuildserver @@ -394,8 +394,8 @@ CACHE_FILES = [ '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), ('https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip', '8381c440fe61fcbb01e209211ac01b519cd6adf51ab1c2281d5daad6ca4c8c8c'), - ('https://dl.google.com/android/repository/android-ndk-r21-linux-x86_64.zip', - 'b65ea2d5c5b68fb603626adcbcea6e4d12c68eb8a73e373bbb9d23c252fc647b'), + ('https://dl.google.com/android/repository/android-ndk-r21b-linux-x86_64.zip', + '0c7af5dd23c5d2564915194e71b1053578438ac992958904703161c7672cbed7'), ] From cfa88a53355574647694de3070278c110606d351 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 13 May 2020 14:59:37 +0200 Subject: [PATCH 0304/2775] gitlab-ci: fix binfmt support for focal to run apksigner This manually mounts the binfmt_misc dir if its not present. It seems the Ubuntu/focal release stopped auto-mounting binfmt_misc: https://bugs.launchpad.net/binfmt-support/+bug/1878413 --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3832c933..a7d00a05 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -92,8 +92,10 @@ ubuntu_lts_ppa: - echo "deb http://ppa.launchpad.net/fdroid/fdroidserver/ubuntu $RELEASE main" >> /etc/apt/sources.list - apt-get update - apt-get dist-upgrade + - mount | grep binfmt_misc || mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc - apt-get install --install-recommends binfmt-support fdroidserver git python3-defusedxml python3-setuptools - - grep binfmt /proc/modules || apt -qy purge apksigner + - ls -l /proc/sys/fs/binfmt_misc || true + - test -e /proc/sys/fs/binfmt_misc/jarwrapper || apt -qy purge apksigner - cd tests - ./run-tests From 77367f1bff3aadab8eae0e98d01aa3b9aa3d29ea Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 13 May 2020 22:21:46 +0200 Subject: [PATCH 0305/2775] server: disable extraneous HTTP errors in upload_apk_to_virustotal This should be in the lowest level so that both the low level call, upload_apk_to_virustotal(), and the next level up, upload_to_virustotal(), both inherit this. --- fdroidserver/server.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index e261222b..b7f4ce53 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -512,9 +512,6 @@ def upload_to_virustotal(repo_section, virustotal_apikey): import requests requests # stop unused import warning - logging.getLogger("urllib3").setLevel(logging.WARNING) - logging.getLogger("requests").setLevel(logging.WARNING) - if repo_section == 'repo': if not os.path.exists('virustotal'): os.mkdir('virustotal') @@ -534,6 +531,9 @@ def upload_apk_to_virustotal(virustotal_apikey, packageName, apkName, hash, versionCode, **kwargs): import requests + logging.getLogger("urllib3").setLevel(logging.WARNING) + logging.getLogger("requests").setLevel(logging.WARNING) + outputfilename = os.path.join('virustotal', packageName + '_' + str(versionCode) + '_' + hash + '.json') From ba854ab24aa7bc0db7c421bf240b9fb08c353abc Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 13 May 2020 15:00:15 +0200 Subject: [PATCH 0306/2775] support Cordova's gradle file https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html --- fdroidserver/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 59b58e34..f0699f58 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1364,6 +1364,7 @@ def manifest_paths(app_dir, flavours): os.path.join(app_dir, 'src', 'main', 'AndroidManifest.xml'), os.path.join(app_dir, 'src', 'AndroidManifest.xml'), os.path.join(app_dir, 'build.gradle'), + os.path.join(app_dir, 'build-extras.gradle'), os.path.join(app_dir, 'build.gradle.kts')] for flavour in flavours: From 30f2d62597d76bc2b012018aa94175c694539809 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 13 May 2020 15:00:38 +0200 Subject: [PATCH 0307/2775] import: fix --omit-disable flag, its a boolean --- fdroidserver/import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 40746b99..70567bb9 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -73,7 +73,7 @@ def main(): help=_("Comma separated list of categories.")) parser.add_argument("-l", "--license", default=None, help=_("Overall license of the project.")) - parser.add_argument("--omit-disable", default=False, + parser.add_argument("--omit-disable", action="store_true", default=False, help=_("Do not add 'disable:' to the generated build entries")) parser.add_argument("--rev", default=None, help=_("Allows a different revision (or git branch) to be specified for the initial import")) From 1106795583213aa22d270b1a8bff5a2202e18750 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 1 Apr 2020 14:51:19 +0200 Subject: [PATCH 0308/2775] deploy: stop uploading to androidobservatory if its already up there --- fdroidserver/server.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index b7f4ce53..313ea424 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -492,12 +492,11 @@ def upload_apk_to_android_observatory(path): href = m.group() page = 'https://androidobservatory.org' - message = '' if href: message = (_('Found {apkfilename} at {url}') .format(apkfilename=apkfilename, url=(page + href))) - if message: logging.debug(message) + return # upload the file with a post request logging.info(_('Uploading {apkfilename} to androidobservatory.org') From df563d339acc2c35b896823625f96fd867494326 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 14 May 2020 11:54:32 +0200 Subject: [PATCH 0309/2775] fix pep8 E741 ambiguous variable name 'l' --- fdroidserver/install.py | 4 ++-- fdroidserver/lint.py | 22 +++++++++++----------- fdroidserver/scanner.py | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/fdroidserver/install.py b/fdroidserver/install.py index 968bb28f..c526f1ec 100644 --- a/fdroidserver/install.py +++ b/fdroidserver/install.py @@ -36,11 +36,11 @@ def devices(): p = SdkToolsPopen(['adb', "devices"]) if p.returncode != 0: raise FDroidException("An error occured when finding devices: %s" % p.output) - lines = [l for l in p.output.splitlines() if not l.startswith('* ')] + lines = [line for line in p.output.splitlines() if not line.startswith('* ')] if len(lines) < 3: return [] lines = lines[1:-1] - return [l.split()[0] for l in lines] + return [line.split()[0] for line in lines] def main(): diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 276bf555..ab7d422c 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -189,9 +189,9 @@ def check_regexes(app): v = app.get(f) t = metadata.fieldtype(f) if t == metadata.TYPE_MULTILINE: - for l in v.splitlines(): - if m.match(l): - yield "%s at line '%s': %s" % (f, l, r) + for line in v.splitlines(): + if m.match(line): + yield "%s at line '%s': %s" % (f, line, r) else: if v is None: continue @@ -345,12 +345,12 @@ def check_duplicates(app): yield _("Description '%s' is just the app's summary") % app.Summary seenlines = set() - for l in app.Description.splitlines(): - if len(l) < 1: + for line in app.Description.splitlines(): + if len(line) < 1: continue - if l in seenlines: + if line in seenlines: yield _("Description has a duplicate line") - seenlines.add(l) + seenlines.add(line) desc_url = re.compile(r'(^|[^[])\[([^ ]+)( |\]|$)') @@ -369,18 +369,18 @@ def check_bulleted_lists(app): validchars = ['*', '#'] lchar = '' lcount = 0 - for l in app.Description.splitlines(): - if len(l) < 1: + for line in app.Description.splitlines(): + if len(line) < 1: lcount = 0 continue - if l[0] == lchar and l[1] == ' ': + if line[0] == lchar and line[1] == ' ': lcount += 1 if lcount > 2 and lchar not in validchars: yield _("Description has a list (%s) but it isn't bulleted (*) nor numbered (#)") % lchar break else: - lchar = l[0] + lchar = line[0] lcount = 1 diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index db990f97..3d5b700f 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -250,7 +250,7 @@ def scan_source(build_dir, build=metadata.Build()): if is_used_by_gradle(line): for name in suspects_found(line): count += handleproblem('usual suspect \'%s\' at line %d' % (name, i + 1), path_in_build_dir, filepath) - noncomment_lines = [l for l in lines if not common.gradle_comment.match(l)] + noncomment_lines = [line for line in lines if not common.gradle_comment.match(line)] joined = re.sub(r'[\n\r\s]+', ' ', ' '.join(noncomment_lines)) for m in gradle_mavenrepo.finditer(joined): url = m.group(2) From 0945eadd4fae618a0cbc6c8ebbeff6cbfccca726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 14 May 2020 11:11:01 +0000 Subject: [PATCH 0310/2775] Apply suggestion to buildserver/provision-apt-get-install --- buildserver/provision-apt-get-install | 1 - 1 file changed, 1 deletion(-) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index 28dc05ad..2ec3d2f9 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -119,7 +119,6 @@ packages=" unzip xsltproc yasm - yamllint zip zlib1g:i386 " From a0e3b01e94e156a79d5eac4c1f9fa5adfeb8f221 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 14 May 2020 15:02:19 +0200 Subject: [PATCH 0311/2775] metadata: parsed srclibs must always return a dict as the container --- fdroidserver/metadata.py | 3 +++ tests/metadata.TestCase | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 99764ac4..5531d369 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -763,6 +763,9 @@ def parse_yaml_srclib(metadatapath): with open(metadatapath, "r", encoding="utf-8") as f: try: data = yaml.load(f, Loader=SafeLoader) + if type(data) is not dict: + raise yaml.error.YAMLError(_('{file} is blank or corrupt!') + .format(file=metadatapath)) except yaml.error.YAMLError as e: warn_or_exception(_("Invalid srclib metadata: could not " "parse '{file}'") diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index d52cd991..c2c9aa57 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -227,6 +227,19 @@ class MetadataTest(unittest.TestCase): with self.assertRaises(MetaDataException): fdroidserver.metadata.parse_yaml_metadata(mf, {}) + def test_parse_yaml_srclib_corrupt_file(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + srclibfile = os.path.join(testdir, 'srclib', 'mock.yml') + os.mkdir(os.path.dirname(srclibfile)) + with open(srclibfile, 'w') as fp: + fp.write(textwrap.dedent(""" + - RepoType: git + - Repo: https://github.com/realm/realm-js.git + """)) + with mock.patch('fdroidserver.metadata.warnings_action', 'error'): + with self.assertRaises(MetaDataException): + fdroidserver.metadata.parse_yaml_srclib(srclibfile) + def test_write_yaml_with_placeholder_values(self): mf = io.StringIO() From 7b6f0892203e92e7c97f3ba0cedfcaa5cccf0547 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 15 Apr 2020 21:43:41 +0200 Subject: [PATCH 0312/2775] index: xml.dom.minidom no longer sorts attribs It seems now that xml.dom.minidom preserves the order of attributes, rather than sorting them. We assume alpha-sort, so this manually This diff in the test suite running on Debian/testing pointed it out: https://gitlab.com/fdroid/fdroidserver/-/jobs/486970383 ```diff --- /builds/fdroid/fdroidserver/tests/repo/index.xml 2020-04-11 13:36:57.000000000 +0000 +++ repo/index.xml 2020-04-11 13:41:44.000000000 +0000 @@ -1,6 +1,6 @@ - + This is a repository of apps to be used with F-Droid. Applications in this repository are either official binaries built by the original application developers, or are binaries built from source by the admin of f-droid.org using the tools on https://gitlab.com/u/fdroid. http://foobarfoobarfoobar.onion/fdroid/repo https://foo.bar/fdroid/repo @@ -94,9 +94,9 @@ 2017-12-22 056c9f1554c40ba59a2103009c82b420 ACCESS_NETWORK_STATE,ACCESS_WIFI_STATE,CHANGE_WIFI_MULTICAST_STATE,INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE - - - + + +
@@ -182,9 +182,9 @@ 2013-12-31 eb41d4d6082bb3e81c3d58dbf7fc7332 ACCESS_NETWORK_STATE,ACCESS_WIFI_STATE,BLUETOOTH,BLUETOOTH_ADMIN,CHANGE_NETWORK_STATE,CHANGE_WIFI_MULTICAST_STATE,CHANGE_WIFI_STATE,INTERNET,NFC,RECEIVE_BOOT_COMPLETED - - - + + +
``` --- fdroidserver/index.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 7fbbea44..fd659407 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -317,13 +317,17 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing parent.appendChild(el) def addElementCheckLocalized(name, app, key, doc, parent, default=''): - '''Fill in field from metadata or localized block + """Fill in field from metadata or localized block For name/summary/description, they can come only from the app source, or from a dir in fdroiddata. They can be entirely missing from the metadata file if there is localized versions. This will fetch those from the localized version if its not available in the metadata file. - ''' + + Attributes should be alpha-sorted, so they must be added in + alpha- sort order. + + """ el = doc.createElement(name) value = app.get(key) @@ -349,21 +353,20 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing doc.appendChild(root) repoel = doc.createElement("repo") - - repoel.setAttribute("name", repodict['name']) + repoel.setAttribute("icon", os.path.basename(repodict['icon'])) if 'maxage' in repodict: repoel.setAttribute("maxage", str(repodict['maxage'])) - repoel.setAttribute("icon", os.path.basename(repodict['icon'])) + repoel.setAttribute("name", repodict['name']) + pubkey, repo_pubkey_fingerprint = extract_pubkey() + repoel.setAttribute("pubkey", pubkey.decode('utf-8')) + repoel.setAttribute("timestamp", '%d' % repodict['timestamp'].timestamp()) repoel.setAttribute("url", repodict['address']) + repoel.setAttribute("version", str(repodict['version'])) + addElement('description', repodict['description'], doc, repoel) for mirror in repodict.get('mirrors', []): addElement('mirror', mirror, doc, repoel) - repoel.setAttribute("version", str(repodict['version'])) - repoel.setAttribute("timestamp", '%d' % repodict['timestamp'].timestamp()) - - pubkey, repo_pubkey_fingerprint = extract_pubkey() - repoel.setAttribute("pubkey", pubkey.decode('utf-8')) root.appendChild(repoel) for command in ('install', 'uninstall'): @@ -541,16 +544,16 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing for permission in sorted_permissions: permel = doc.createElement('uses-permission') - permel.setAttribute('name', permission[0]) if permission[1] is not None: permel.setAttribute('maxSdkVersion', '%d' % permission[1]) apkel.appendChild(permel) + permel.setAttribute('name', permission[0]) for permission_sdk_23 in sorted(apk['uses-permission-sdk-23']): permel = doc.createElement('uses-permission-sdk-23') - permel.setAttribute('name', permission_sdk_23[0]) if permission_sdk_23[1] is not None: permel.setAttribute('maxSdkVersion', '%d' % permission_sdk_23[1]) apkel.appendChild(permel) + permel.setAttribute('name', permission_sdk_23[0]) if 'nativecode' in apk: addElement('nativecode', ','.join(sorted(apk['nativecode'])), doc, apkel) addElementNonEmpty('features', ','.join(sorted(apk['features'])), doc, apkel) From f5f61155ae023d28b3c74380141202f43fe622d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 10 May 2019 12:02:13 +0200 Subject: [PATCH 0313/2775] improve litecoin validation + tests --- fdroidserver/metadata.py | 2 +- tests/metadata.TestCase | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index d8ed98b9..e8bde005 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -457,7 +457,7 @@ valuetypes = { ["Bitcoin"]), FieldValidator("Litecoin address", - r'^L[a-zA-Z0-9]{33}$', + r'^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$', ["Litecoin"]), FieldValidator("Repo Type", diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index dc786095..d7b72f71 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -39,7 +39,7 @@ class MetadataTest(unittest.TestCase): os.makedirs(self.tmpdir) os.chdir(self.basedir) - def test_FieldValidator(self): + def test_FieldValidator_BitcoinAddress(self): validator = None for vali in fdroidserver.metadata.valuetypes: if vali.name == 'Bitcoin address': @@ -54,9 +54,9 @@ class MetadataTest(unittest.TestCase): self.assertIsNone(validator.check('3JrrrrWrEZr3rNrrvrecrnyirrnqRhWNLy', 'fake.app.id')) self.assertIsNone(validator.check('bc1qar0srrr7xrkvr5lr43lrdnwrre5rgtrzrf5rrq', 'fake.app.id')) - # some invalid addresses (various special use/testnet addresses) + # some invalid addresses self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, - '21BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + '21BvMrSYsrWrtrrlL5A10mlGFr7rrarrN2', 'fake.app.id') self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, '5Hrgr3ur5rGLrfKrrrrrrHSrqJrroGrrzrQrrrrrrLNrsrDrrrA', 'fake.app.id') self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, @@ -68,6 +68,35 @@ class MetadataTest(unittest.TestCase): self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, 'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id') + def test_FieldValidator_LitecoinAddress(self): + validator = None + for vali in fdroidserver.metadata.valuetypes: + if vali.name == 'Litecoin address': + validator = vali + break + self.assertIsNotNone(validator, "could not find 'Litecoin address' validator") + + fdroidserver.metadata.warnings_action = 'error' + + # some valid addresses (L, M, 3) + self.assertIsNone(validator.check('LgeGrrrrJAxyXprrPrrBrrX5Qrrrrrrrrd', 'fake.app.id')) + self.assertIsNone(validator.check('MrrrrrrrJAxyXpanPtrrRAX5QHxvUJo8id', 'fake.app.id')) + self.assertIsNone(validator.check('3rereVr9rAryrranrrrrrAXrrHx', 'fake.app.id')) + + # some invalid addresses (various special use/testnet addresses, invalid chars) + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '21BvMrSYsrWrtrrrn5Au4l4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '5Hrgr3ur5rGLrfKrrrrrr1SrqJrroGrrzrQrrrrrrLNrsrDrrrA', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + '92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'L0000rSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id') + self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, + 'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id') + def test_read_metadata(self): def _build_yaml_representer(dumper, data): From cdaf62e5d9ec2448e2aedf8989c1390d11f66370 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 14 May 2020 16:08:56 +0200 Subject: [PATCH 0314/2775] scanner: add --json option for outputting machine readable results * makes per-build entries in per-app entries * `fdroid scanner --json --verbose` will output logging messages to stderr * removed " at line N" from one message to make them uniform keys * this will be used in issuebot --- fdroidserver/scanner.py | 50 ++++++++++++++++++++++++++++++++++------- tests/scanner.TestCase | 2 ++ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 3d5b700f..6c163698 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -16,8 +16,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import json import os import re +import sys import traceback from argparse import ArgumentParser import logging @@ -31,6 +33,8 @@ from .exception import BuildException, VCSException config = None options = None +json_per_build = None + def get_gradle_compile_commands(build): compileCommands = ['compile', @@ -141,10 +145,12 @@ def scan_source(build_dir, build=metadata.Build()): def ignoreproblem(what, path_in_build_dir): logging.info('Ignoring %s at %s' % (what, path_in_build_dir)) + json_per_build['infos'].append([what, path_in_build_dir]) return 0 def removeproblem(what, path_in_build_dir, filepath): logging.info('Removing %s at %s' % (what, path_in_build_dir)) + json_per_build['infos'].append([what, path_in_build_dir]) os.remove(filepath) return 0 @@ -152,13 +158,17 @@ def scan_source(build_dir, build=metadata.Build()): if toignore(path_in_build_dir): return logging.warn('Found %s at %s' % (what, path_in_build_dir)) + json_per_build['warnings'].append([what, path_in_build_dir]) def handleproblem(what, path_in_build_dir, filepath): if toignore(path_in_build_dir): return ignoreproblem(what, path_in_build_dir) if todelete(path_in_build_dir): return removeproblem(what, path_in_build_dir, filepath) - logging.error('Found %s at %s' % (what, path_in_build_dir)) + if options.json: + json_per_build['errors'].append([what, path_in_build_dir]) + if not options.json or options.verbose: + logging.error('Found %s at %s' % (what, path_in_build_dir)) return 1 def is_executable(path): @@ -249,7 +259,8 @@ def scan_source(build_dir, build=metadata.Build()): for i, line in enumerate(lines): if is_used_by_gradle(line): for name in suspects_found(line): - count += handleproblem('usual suspect \'%s\' at line %d' % (name, i + 1), path_in_build_dir, filepath) + count += handleproblem("usual suspect \'%s\'" % (name), + path_in_build_dir, filepath) noncomment_lines = [line for line in lines if not common.gradle_comment.match(line)] joined = re.sub(r'[\n\r\s]+', ' ', ' '.join(noncomment_lines)) for m in gradle_mavenrepo.finditer(joined): @@ -280,7 +291,7 @@ def scan_source(build_dir, build=metadata.Build()): def main(): - global config, options + global config, options, json_per_build # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") @@ -288,10 +299,19 @@ def main(): parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) parser.add_argument("-f", "--force", action="store_true", default=False, help=_("Force scan of disabled apps and builds.")) + parser.add_argument("--json", action="store_true", default=False, + help=_("Output JSON to stdout.")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W + json_output = dict() + if options.json: + if options.verbose: + logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) + else: + logging.getLogger().setLevel(logging.ERROR) + config = common.read_config(options) # Read all app and srclib metadata @@ -309,8 +329,11 @@ def main(): for appid, app in apps.items(): + json_per_appid = dict() + if app.Disabled and not options.force: logging.info(_("Skipping {appid}: disabled").format(appid=appid)) + json_per_appid = json_per_appid['infos'].append('Skipping: disabled') continue try: @@ -321,20 +344,23 @@ def main(): if app.builds: logging.info(_("Processing {appid}").format(appid=appid)) + # Set up vcs interface and make sure we have the latest code... + vcs = common.getvcs(app.RepoType, app.Repo, build_dir) else: logging.info(_("{appid}: no builds specified, running on current source state") .format(appid=appid)) + json_per_build = {'errors': [], 'warnings': [], 'infos': []} + json_per_appid['current-source-state'] = json_per_build count = scan_source(build_dir) if count > 0: logging.warn(_('Scanner found {count} problems in {appid}:') .format(count=count, appid=appid)) probcount += count - continue - - # Set up vcs interface and make sure we have the latest code... - vcs = common.getvcs(app.RepoType, app.Repo, build_dir) + app.builds = [] for build in app.builds: + json_per_build = {'errors': [], 'warnings': [], 'infos': []} + json_per_appid[build.versionCode] = json_per_build if build.disable and not options.force: logging.info("...skipping version %s - %s" % ( @@ -365,8 +391,16 @@ def main(): appid, traceback.format_exc())) probcount += 1 + for k, v in json_per_appid.items(): + if len(v['errors']) or len(v['warnings']) or len(v['infos']): + json_output[appid] = json_per_appid + break + logging.info(_("Finished")) - print(_("%d problems found") % probcount) + if options.json: + print(json.dumps(json_output)) + else: + print(_("%d problems found") % probcount) if __name__ == "__main__": diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index cbaa9de2..72710dd5 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -26,6 +26,8 @@ class ScannerTest(unittest.TestCase): self.basedir = os.path.join(localmodule, 'tests') def test_scan_source_files(self): + fdroidserver.scanner.options = type('', (), {})() + fdroidserver.scanner.options.json = False source_files = os.path.join(self.basedir, 'source-files') projects = { 'cn.wildfirechat.chat': 4, From 80a467134f7506b73ee32f4bd575f4572dcd4b34 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 14 May 2020 17:49:59 +0200 Subject: [PATCH 0315/2775] gitlab-ci: run Debian/buster job on all commits --- .gitlab-ci.yml | 10 ++++------ hooks/pre-commit | 3 ++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9828dbc4..07be4899 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,16 +37,14 @@ metadata_v0: metadata/dump_*/*.yaml - diff -uw metadata/dump_* -debian_testing: - image: debian:testing - only: - - master@fdroid/fdroidserver +debian_buster: + image: debian:buster script: - apt-get -qy update - apt-get -qy dist-upgrade - apt-get -qy install --no-install-recommends fdroidserver git gnupg python3-defusedxml python3-setuptools - - sed -i -e 's,testing,sid,g' -e 's,testing,sid,g' /etc/apt/sources.list + - echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list - apt-get -qy update - apt-get install -y --no-install-recommends aapt androguard android-platform-tools-base zipalign - python3 -c 'import fdroidserver' @@ -135,7 +133,7 @@ lint_format_safety_bandit_checks: -x fdroidserver/dscanner.py,docker/install_agent.py,docker/drozer.py -r $CI_PROJECT_DIR fdroid || export EXITVALUE=1 - - safety check --full-report || export EXITVALUE=1 + - safety check --full-report --ignore=38224 || export EXITVALUE=1 - pylint --rcfile=.pylint-rcfile --output-format=colorized --reports=n fdroid makebuildserver diff --git a/hooks/pre-commit b/hooks/pre-commit index 94c55888..369b3620 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -53,10 +53,11 @@ fi # * E501: line too long (82 > 79 characters) # - Recommended for readability but not enforced # - Some lines are awkward to wrap around a char limit +# * E741: ambiguous variable name 'l' # * W503: line break before binary operator # - Quite pedantic -PEP8_IGNORE="E123,E501,W503" +PEP8_IGNORE="E123,E501,E741,W503" err() { echo >&2 ERROR: "$@" From 722a23f571f91a656a76ff36d140b482ce668445 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 15 May 2020 09:22:10 +0200 Subject: [PATCH 0316/2775] bump to versiob v1.1.7 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index efc46573..2ffcc1fd 100755 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ with open("README.md", "r") as fh: setup(name='fdroidserver', - version='1.1.6', + version='1.1.7', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From e25b8a19333aef21b0e3331e23c761866a3a6482 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Sun, 17 May 2020 02:58:30 +0200 Subject: [PATCH 0317/2775] add gradle 6.4.1 --- gradlew-fdroid | 3 ++- makebuildserver | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index aaf5814c..7664b1aa 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -136,6 +136,7 @@ get_sha() { '6.2.2') echo '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17' ;; '6.3') echo '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768' ;; '6.4') echo 'b888659f637887e759749f6226ddfcb1cb04f828c58c41279de73c463fdbacc9' ;; + '6.4.1') echo 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd' ;; *) exit 1 esac } @@ -156,7 +157,7 @@ d_plugin_k=(3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 d_plugin_v=(5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 922120b5..dc5a689d 100755 --- a/makebuildserver +++ b/makebuildserver @@ -370,8 +370,8 @@ CACHE_FILES = [ '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17'), ('https://services.gradle.org/distributions/gradle-6.3-bin.zip', '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768'), - ('https://services.gradle.org/distributions/gradle-6.4-bin.zip', - 'b888659f637887e759749f6226ddfcb1cb04f828c58c41279de73c463fdbacc9'), + ('https://services.gradle.org/distributions/gradle-6.4.1-bin.zip', + 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 68c072c72e2d9c75b5220ea1e95d1773e8ae2723 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Sun, 24 May 2020 10:24:40 +0200 Subject: [PATCH 0318/2775] Revert "scanner: add --json option for outputting machine readable results" This reverts commit cdaf62e5d9ec2448e2aedf8989c1390d11f66370. See: https://gitlab.com/fdroid/fdroidserver/-/merge_requests/748#note_347769371 --- fdroidserver/scanner.py | 50 +++++++---------------------------------- tests/scanner.TestCase | 2 -- 2 files changed, 8 insertions(+), 44 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 6c163698..3d5b700f 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -16,10 +16,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import json import os import re -import sys import traceback from argparse import ArgumentParser import logging @@ -33,8 +31,6 @@ from .exception import BuildException, VCSException config = None options = None -json_per_build = None - def get_gradle_compile_commands(build): compileCommands = ['compile', @@ -145,12 +141,10 @@ def scan_source(build_dir, build=metadata.Build()): def ignoreproblem(what, path_in_build_dir): logging.info('Ignoring %s at %s' % (what, path_in_build_dir)) - json_per_build['infos'].append([what, path_in_build_dir]) return 0 def removeproblem(what, path_in_build_dir, filepath): logging.info('Removing %s at %s' % (what, path_in_build_dir)) - json_per_build['infos'].append([what, path_in_build_dir]) os.remove(filepath) return 0 @@ -158,17 +152,13 @@ def scan_source(build_dir, build=metadata.Build()): if toignore(path_in_build_dir): return logging.warn('Found %s at %s' % (what, path_in_build_dir)) - json_per_build['warnings'].append([what, path_in_build_dir]) def handleproblem(what, path_in_build_dir, filepath): if toignore(path_in_build_dir): return ignoreproblem(what, path_in_build_dir) if todelete(path_in_build_dir): return removeproblem(what, path_in_build_dir, filepath) - if options.json: - json_per_build['errors'].append([what, path_in_build_dir]) - if not options.json or options.verbose: - logging.error('Found %s at %s' % (what, path_in_build_dir)) + logging.error('Found %s at %s' % (what, path_in_build_dir)) return 1 def is_executable(path): @@ -259,8 +249,7 @@ def scan_source(build_dir, build=metadata.Build()): for i, line in enumerate(lines): if is_used_by_gradle(line): for name in suspects_found(line): - count += handleproblem("usual suspect \'%s\'" % (name), - path_in_build_dir, filepath) + count += handleproblem('usual suspect \'%s\' at line %d' % (name, i + 1), path_in_build_dir, filepath) noncomment_lines = [line for line in lines if not common.gradle_comment.match(line)] joined = re.sub(r'[\n\r\s]+', ' ', ' '.join(noncomment_lines)) for m in gradle_mavenrepo.finditer(joined): @@ -291,7 +280,7 @@ def scan_source(build_dir, build=metadata.Build()): def main(): - global config, options, json_per_build + global config, options # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") @@ -299,19 +288,10 @@ def main(): parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) parser.add_argument("-f", "--force", action="store_true", default=False, help=_("Force scan of disabled apps and builds.")) - parser.add_argument("--json", action="store_true", default=False, - help=_("Output JSON to stdout.")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W - json_output = dict() - if options.json: - if options.verbose: - logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) - else: - logging.getLogger().setLevel(logging.ERROR) - config = common.read_config(options) # Read all app and srclib metadata @@ -329,11 +309,8 @@ def main(): for appid, app in apps.items(): - json_per_appid = dict() - if app.Disabled and not options.force: logging.info(_("Skipping {appid}: disabled").format(appid=appid)) - json_per_appid = json_per_appid['infos'].append('Skipping: disabled') continue try: @@ -344,23 +321,20 @@ def main(): if app.builds: logging.info(_("Processing {appid}").format(appid=appid)) - # Set up vcs interface and make sure we have the latest code... - vcs = common.getvcs(app.RepoType, app.Repo, build_dir) else: logging.info(_("{appid}: no builds specified, running on current source state") .format(appid=appid)) - json_per_build = {'errors': [], 'warnings': [], 'infos': []} - json_per_appid['current-source-state'] = json_per_build count = scan_source(build_dir) if count > 0: logging.warn(_('Scanner found {count} problems in {appid}:') .format(count=count, appid=appid)) probcount += count - app.builds = [] + continue + + # Set up vcs interface and make sure we have the latest code... + vcs = common.getvcs(app.RepoType, app.Repo, build_dir) for build in app.builds: - json_per_build = {'errors': [], 'warnings': [], 'infos': []} - json_per_appid[build.versionCode] = json_per_build if build.disable and not options.force: logging.info("...skipping version %s - %s" % ( @@ -391,16 +365,8 @@ def main(): appid, traceback.format_exc())) probcount += 1 - for k, v in json_per_appid.items(): - if len(v['errors']) or len(v['warnings']) or len(v['infos']): - json_output[appid] = json_per_appid - break - logging.info(_("Finished")) - if options.json: - print(json.dumps(json_output)) - else: - print(_("%d problems found") % probcount) + print(_("%d problems found") % probcount) if __name__ == "__main__": diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 72710dd5..cbaa9de2 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -26,8 +26,6 @@ class ScannerTest(unittest.TestCase): self.basedir = os.path.join(localmodule, 'tests') def test_scan_source_files(self): - fdroidserver.scanner.options = type('', (), {})() - fdroidserver.scanner.options.json = False source_files = os.path.join(self.basedir, 'source-files') projects = { 'cn.wildfirechat.chat': 4, From ddfbd1cc47f58deed4a5b4844f9850e2df5f4d26 Mon Sep 17 00:00:00 2001 From: relan Date: Thu, 21 May 2020 08:50:08 +0300 Subject: [PATCH 0319/2775] build: fix directories removal The 'dirs' array contains a single-level listing of a directory, e. g. ['app', 'build', 'build.gradle', 'gradle', '.gradle']. Multi-component paths like 'build/tmp' could never be found in this array and thus were never removed. Call shutil.rmtree() without checking that the argument is in 'dirs'. If it exists and is a directory, it'll be removed. Otherwise shutil.rmtree() will do nothing. --- fdroidserver/build.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 41467533..df74cdba 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -475,8 +475,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext def del_dirs(dl): for d in dl: - if d in dirs: - shutil.rmtree(os.path.join(root, d)) + shutil.rmtree(os.path.join(root, d), ignore_errors=True) def del_files(fl): for f in fl: From 9ff77cfd1a83d7e253e3bd7cb7517d548b8993c8 Mon Sep 17 00:00:00 2001 From: relan Date: Thu, 21 May 2020 08:50:35 +0300 Subject: [PATCH 0320/2775] build: clean buildSrc/build The buildSrc directory contains custom build logic written in Kotlin. Before this change we had to 'scandelete' buildSrc/build in the build recipes becase 'gradle clean' leaves binary artifacts there. --- fdroidserver/build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index df74cdba..6d8e0241 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -493,6 +493,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext os.path.join('build', 'outputs'), os.path.join('build', 'reports'), os.path.join('build', 'tmp'), + os.path.join('buildSrc', 'build'), '.gradle']) del_files(['gradlew', 'gradlew.bat']) From 5b9944fcde698d4be78f767368f3f87ab7340558 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 26 May 2020 09:48:55 +0200 Subject: [PATCH 0321/2775] add test for things `fdroid build` cleans This needs a lot of mocking because build.build_local() is a gianormous single function. --- tests/build.TestCase | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/tests/build.TestCase b/tests/build.TestCase index 6b872ebb..547c0b6e 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -10,7 +10,9 @@ import re import shutil import sys import tempfile +import textwrap import unittest +from unittest import mock localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) @@ -121,6 +123,79 @@ class BuildTest(unittest.TestCase): self.assertEqual(versionCode, vc) self.assertEqual(versionName, vn) + def test_build_local_clean(self): + """Test if `fdroid build` cleans ant and gradle build products""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.build.options = mock.Mock() + fdroidserver.build.options.json = False + fdroidserver.build.options.notarball = True + fdroidserver.build.options.skipscan = False + + app = fdroidserver.metadata.App() + app.id = 'mocked.app.id' + build = fdroidserver.metadata.Build() + build.commit = '1.0' + build.output = app.id + '.apk' + build.scanignore = ['baz.so'] + build.versionCode = '1' + build.versionName = '1.0' + vcs = mock.Mock() + + os.mkdir('reports') + os.mkdir('target') + + for f in ('baz.so', 'foo.aar', 'gradle-wrapper.jar'): + with open(f, 'w') as fp: + fp.write('placeholder') + self.assertTrue(os.path.exists(f)) + + os.mkdir('build') + os.mkdir('build/reports') + with open('build.gradle', 'w') as fp: + fp.write('// placeholder') + + os.mkdir('bin') + os.mkdir('gen') + with open('build.xml', 'w') as fp: + fp.write(textwrap.dedent( + """ + + + + """)) + + def make_fake_apk(output, build): + with open(build.output, 'w') as fp: + fp.write('APK PLACEHOLDER') + return output + + with mock.patch('fdroidserver.common.replace_build_vars', wraps=make_fake_apk): + with mock.patch('fdroidserver.common.get_native_code', return_value='x86'): + with mock.patch('fdroidserver.common.get_apk_id', + return_value=(app.id, build.versionCode, build.versionName)): + with mock.patch('fdroidserver.common.is_apk_and_debuggable', return_value=False): + fdroidserver.build.build_local( + app, build, vcs, + build_dir=testdir, output_dir=testdir, + log_dir=None, srclib_dir=None, extlib_dir=None, tmp_dir=None, + force=False, onserver=False, refresh=False + ) + + self.assertTrue(os.path.exists('baz.so')) + self.assertTrue(os.path.exists('foo.aar')) + self.assertTrue(os.path.isdir('build')) + self.assertTrue(os.path.isdir('reports')) + self.assertTrue(os.path.isdir('target')) + self.assertFalse(os.path.exists('bin')) + self.assertFalse(os.path.exists('build/reports')) + self.assertFalse(os.path.exists('gen')) + self.assertFalse(os.path.exists('gradle-wrapper.jar')) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 6030445be041a03b86a8bcb697fb328e2e25cb03 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 25 May 2020 17:36:58 +0200 Subject: [PATCH 0322/2775] logging.warn() was deprecated in Python 3.3, use logging.warning() sed -i 's,logging\.warn(,logging.warning(,g' fdroid */*.* https://docs.python.org/3.3/library/logging.html#logging.Logger.warning --- fdroidserver/__main__.py | 6 +++--- fdroidserver/build.py | 2 +- fdroidserver/import.py | 4 ++-- fdroidserver/init.py | 6 +++--- fdroidserver/install.py | 4 ++-- fdroidserver/scanner.py | 16 ++++++++-------- fdroidserver/server.py | 9 +++++---- fdroidserver/signatures.py | 4 +++- fdroidserver/update.py | 8 ++++---- fdroidserver/vmtools.py | 6 +++--- 10 files changed, 34 insertions(+), 31 deletions(-) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index a75236b9..7ffc6b7e 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -137,9 +137,9 @@ def main(): system_langcode, system_encoding = locale.getdefaultlocale() if system_encoding is None or system_encoding.lower() not in ('utf-8', 'utf8'): - logging.warn(_("Encoding is set to '{enc}' fdroid might run " - "into encoding issues. Please set it to 'UTF-8' " - "for best results.".format(enc=system_encoding))) + logging.warning(_("Encoding is set to '{enc}' fdroid might run " + "into encoding issues. Please set it to 'UTF-8' " + "for best results.".format(enc=system_encoding))) try: mod.main() diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 6d8e0241..13317701 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -278,7 +278,7 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): ftp.get(toolsversion_log, os.path.join(log_dir, toolsversion_log)) logging.debug('retrieved %s', toolsversion_log) except Exception as e: - logging.warn('could not get %s from builder vm: %s' % (toolsversion_log, e)) + logging.warning('could not get %s from builder vm: %s' % (toolsversion_log, e)) # Retrieve the built files... logging.info("Retrieving build output...") diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 70567bb9..5a313bf8 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -131,9 +131,9 @@ def main(): if not package: raise FDroidException(_("Couldn't find package ID")) if not versionName: - logging.warn(_("Couldn't find latest version name")) + logging.warning(_('Could not find latest version name')) if not versionCode: - logging.warn(_("Couldn't find latest version code")) + logging.warning(_('Could not find latest version code')) else: raise FDroidException(_("No gradle project could be found. Specify --subdir?")) diff --git a/fdroidserver/init.py b/fdroidserver/init.py index 7eb8bbe2..280a503a 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -130,7 +130,7 @@ def main(): if 'sdk_path' in test_config: common.write_to_config(test_config, 'sdk_path', options.android_home) else: - logging.warn('Looks like this is already an F-Droid repo, cowardly refusing to overwrite it...') + logging.warning('Looks like this is already an F-Droid repo, cowardly refusing to overwrite it...') logging.info('Try running `fdroid init` in an empty directory.') raise FDroidException('Repository already exists.') @@ -209,8 +209,8 @@ def main(): opensc_so = files[0] else: opensc_so = '/usr/lib/opensc-pkcs11.so' - logging.warn('No OpenSC PKCS#11 module found, ' - + 'install OpenSC then edit "opensc-fdroid.cfg"!') + logging.warning('No OpenSC PKCS#11 module found, ' + + 'install OpenSC then edit "opensc-fdroid.cfg"!') with open(os.path.join(examplesdir, 'opensc-fdroid.cfg'), 'r') as f: opensc_fdroid = f.read() opensc_fdroid = re.sub('^library.*', 'library = ' + opensc_so, opensc_fdroid, diff --git a/fdroidserver/install.py b/fdroidserver/install.py index c526f1ec..c4e4b7dd 100644 --- a/fdroidserver/install.py +++ b/fdroidserver/install.py @@ -109,8 +109,8 @@ def main(): continue if fail == "INSTALL_FAILED_ALREADY_EXISTS": - logging.warn(_("'{apkfilename}' is already installed on {dev}.") - .format(apkfilename=apk, dev=dev)) + logging.warning(_('"{apkfilename}" is already installed on {dev}.') + .format(apkfilename=apk, dev=dev)) else: raise FDroidException(_("Failed to install '{apkfilename}' on {dev}: {error}") .format(apkfilename=apk, dev=dev, error=fail)) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 30084695..6560c4da 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -159,7 +159,7 @@ def scan_source(build_dir, build=metadata.Build()): def warnproblem(what, path_in_build_dir): if toignore(path_in_build_dir): return - logging.warn('Found %s at %s' % (what, path_in_build_dir)) + logging.warning('Found %s at %s' % (what, path_in_build_dir)) if json_per_build is not None: json_per_build['warnings'].append([what, path_in_build_dir]) @@ -356,8 +356,8 @@ def main(): json_per_appid['current-source-state'] = json_per_build count = scan_source(build_dir) if count > 0: - logging.warn(_('Scanner found {count} problems in {appid}:') - .format(count=count, appid=appid)) + logging.warning(_('Scanner found {count} problems in {appid}:') + .format(count=count, appid=appid)) probcount += count app.builds = [] @@ -378,19 +378,19 @@ def main(): count = scan_source(build_dir, build) if count > 0: - logging.warn(_('Scanner found {count} problems in {appid}:{versionCode}:') - .format(count=count, appid=appid, versionCode=build.versionCode)) + logging.warning(_('Scanner found {count} problems in {appid}:{versionCode}:') + .format(count=count, appid=appid, versionCode=build.versionCode)) probcount += count except BuildException as be: - logging.warn("Could not scan app %s due to BuildException: %s" % ( + logging.warning('Could not scan app %s due to BuildException: %s' % ( appid, be)) probcount += 1 except VCSException as vcse: - logging.warn("VCS error while scanning app %s: %s" % (appid, vcse)) + logging.warning('VCS error while scanning app %s: %s' % (appid, vcse)) probcount += 1 except Exception: - logging.warn("Could not scan app %s due to unknown error: %s" % ( + logging.warning('Could not scan app %s due to unknown error: %s' % ( appid, traceback.format_exc())) probcount += 1 diff --git a/fdroidserver/server.py b/fdroidserver/server.py index 313ea424..cc930eb6 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -207,7 +207,7 @@ def update_awsbucket_libcloud(repo_section): s3url = 's3://' + awsbucket + '/' + obj.name logging.info(' deleting ' + s3url) if not driver.delete_object(obj): - logging.warn('Could not delete ' + s3url) + logging.warning('Could not delete ' + s3url) upload = True if upload: @@ -229,7 +229,7 @@ def update_awsbucket_libcloud(repo_section): object_name, obj = objs.popitem() s3url = 's3://' + awsbucket + '/' + object_name if object_name.startswith(upload_dir): - logging.warn(' deleting ' + s3url) + logging.warning(' deleting ' + s3url) driver.delete_object(obj) else: logging.info(' skipping ' + s3url) @@ -773,8 +773,9 @@ def main(): and not config.get('binary_transparency_remote') \ and not config.get('virustotal_apikey') \ and local_copy_dir is None: - logging.warn(_('No option set! Edit your config.py to set at least one of these:') - + '\nserverwebroot, servergitmirrors, local_copy_dir, awsbucket, virustotal_apikey, androidobservatory, or binary_transparency_remote') + logging.warning(_('No option set! Edit your config.py to set at least one of these:') + + '\nserverwebroot, servergitmirrors, local_copy_dir, awsbucket, ' + + 'virustotal_apikey, androidobservatory, or binary_transparency_remote') sys.exit(1) repo_sections = ['repo'] diff --git a/fdroidserver/signatures.py b/fdroidserver/signatures.py index 03b2d6f2..79bea6a1 100644 --- a/fdroidserver/signatures.py +++ b/fdroidserver/signatures.py @@ -76,7 +76,9 @@ def extract(options): if tmp_apk and os.path.exists(tmp_apk): os.remove(tmp_apk) else: - logging.warn(_('refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}').format(apkfilename=apk)) + logging.warning(_('refuse downloading via insecure HTTP connection ' + '(use HTTPS or specify --no-https-check): {apkfilename}') + .format(apkfilename=apk)) except FDroidException as e: logging.warning(_("Failed fetching signatures for '{apkfilename}': {error}") .format(apkfilename=apk, error=e)) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 13947570..4748a7f6 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -366,7 +366,7 @@ def update_wiki(apps, sortedids, apks): else: logging.debug("Page " + page.name + " is unchanged") else: - logging.warn("Deleting page " + page.name) + logging.warning('Deleting page ' + page.name) page.delete('No longer published') for pagename, text in genp.items(): logging.debug("Checking " + pagename) @@ -2162,15 +2162,15 @@ def main(): msg = _("{apkfilename} ({appid}) has no metadata!") \ .format(apkfilename=apk['apkName'], appid=apk['packageName']) if options.delete_unknown: - logging.warn(msg + '\n\t' + _("deleting: repo/{apkfilename}") - .format(apkfilename=apk['apkName'])) + logging.warning(msg + '\n\t' + _("deleting: repo/{apkfilename}") + .format(apkfilename=apk['apkName'])) rmf = os.path.join(repodirs[0], apk['apkName']) if not os.path.exists(rmf): logging.error(_("Could not find {path} to remove it").format(path=rmf)) else: os.remove(rmf) else: - logging.warn(msg + '\n\t' + _("Use `fdroid update -c` to create it.")) + logging.warning(msg + '\n\t' + _('Use `fdroid update -c` to create it.')) copy_triple_t_store_metadata(apps) insert_obbs(repodirs[0], apps, apks) diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index 829d22ca..bd8aae60 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -117,7 +117,7 @@ def get_build_vm(srvdir, provider=None): logging.debug('build vm provider \'virtualbox\' selected') return VirtualboxBuildVm(abssrvdir) else: - logging.warn('build vm provider not supported: \'%s\'', provider) + logging.warning('build vm provider not supported: \'%s\'', provider) # try guessing provider from installed software kvm_installed = shutil.which('kvm') is not None @@ -451,8 +451,8 @@ class LibvirtBuildVm(FDroidBuildVm): os.remove('box.img') else: - logging.warn("could not connect to storage-pool 'default', " - "skip packaging buildserver box") + logging.warning("could not connect to storage-pool 'default', " + "skip packaging buildserver box") def box_add(self, boxname, boxfile, force=True): boximg = '%s_vagrant_box_image_0.img' % (boxname) From 67332d83a5bca2bbeeff1466148857cb69089a4d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 14 May 2020 16:08:56 +0200 Subject: [PATCH 0323/2775] scanner: add --json option for outputting machine readable results * makes per-build entries in per-app entries * `fdroid scanner --json --verbose` will output logging messages to stderr * removed " at line N" from one message to make them uniform keys * this will be used in issuebot This is a second attempt with tests for how `fdroid build` calls the scanner functions. closes #771. It was previously merged in !748 then reverted in 68c072c72e2d9c75b5220ea1e95d1773e8ae2723 --- fdroidserver/scanner.py | 53 +++++++++++++++++++++++++++----- tests/scanner.TestCase | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 8 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 3d5b700f..30084695 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -16,8 +16,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import json import os import re +import sys import traceback from argparse import ArgumentParser import logging @@ -31,6 +33,8 @@ from .exception import BuildException, VCSException config = None options = None +json_per_build = None + def get_gradle_compile_commands(build): compileCommands = ['compile', @@ -141,10 +145,14 @@ def scan_source(build_dir, build=metadata.Build()): def ignoreproblem(what, path_in_build_dir): logging.info('Ignoring %s at %s' % (what, path_in_build_dir)) + if json_per_build is not None: + json_per_build['infos'].append([what, path_in_build_dir]) return 0 def removeproblem(what, path_in_build_dir, filepath): logging.info('Removing %s at %s' % (what, path_in_build_dir)) + if json_per_build is not None: + json_per_build['infos'].append([what, path_in_build_dir]) os.remove(filepath) return 0 @@ -152,13 +160,18 @@ def scan_source(build_dir, build=metadata.Build()): if toignore(path_in_build_dir): return logging.warn('Found %s at %s' % (what, path_in_build_dir)) + if json_per_build is not None: + json_per_build['warnings'].append([what, path_in_build_dir]) def handleproblem(what, path_in_build_dir, filepath): if toignore(path_in_build_dir): return ignoreproblem(what, path_in_build_dir) if todelete(path_in_build_dir): return removeproblem(what, path_in_build_dir, filepath) - logging.error('Found %s at %s' % (what, path_in_build_dir)) + if options.json: + json_per_build['errors'].append([what, path_in_build_dir]) + if not options.json or options.verbose: + logging.error('Found %s at %s' % (what, path_in_build_dir)) return 1 def is_executable(path): @@ -249,7 +262,8 @@ def scan_source(build_dir, build=metadata.Build()): for i, line in enumerate(lines): if is_used_by_gradle(line): for name in suspects_found(line): - count += handleproblem('usual suspect \'%s\' at line %d' % (name, i + 1), path_in_build_dir, filepath) + count += handleproblem("usual suspect \'%s\'" % (name), + path_in_build_dir, filepath) noncomment_lines = [line for line in lines if not common.gradle_comment.match(line)] joined = re.sub(r'[\n\r\s]+', ' ', ' '.join(noncomment_lines)) for m in gradle_mavenrepo.finditer(joined): @@ -280,7 +294,7 @@ def scan_source(build_dir, build=metadata.Build()): def main(): - global config, options + global config, options, json_per_build # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") @@ -288,10 +302,19 @@ def main(): parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) parser.add_argument("-f", "--force", action="store_true", default=False, help=_("Force scan of disabled apps and builds.")) + parser.add_argument("--json", action="store_true", default=False, + help=_("Output JSON to stdout.")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W + json_output = dict() + if options.json: + if options.verbose: + logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) + else: + logging.getLogger().setLevel(logging.ERROR) + config = common.read_config(options) # Read all app and srclib metadata @@ -309,8 +332,11 @@ def main(): for appid, app in apps.items(): + json_per_appid = dict() + if app.Disabled and not options.force: logging.info(_("Skipping {appid}: disabled").format(appid=appid)) + json_per_appid = json_per_appid['infos'].append('Skipping: disabled') continue try: @@ -321,20 +347,23 @@ def main(): if app.builds: logging.info(_("Processing {appid}").format(appid=appid)) + # Set up vcs interface and make sure we have the latest code... + vcs = common.getvcs(app.RepoType, app.Repo, build_dir) else: logging.info(_("{appid}: no builds specified, running on current source state") .format(appid=appid)) + json_per_build = {'errors': [], 'warnings': [], 'infos': []} + json_per_appid['current-source-state'] = json_per_build count = scan_source(build_dir) if count > 0: logging.warn(_('Scanner found {count} problems in {appid}:') .format(count=count, appid=appid)) probcount += count - continue - - # Set up vcs interface and make sure we have the latest code... - vcs = common.getvcs(app.RepoType, app.Repo, build_dir) + app.builds = [] for build in app.builds: + json_per_build = {'errors': [], 'warnings': [], 'infos': []} + json_per_appid[build.versionCode] = json_per_build if build.disable and not options.force: logging.info("...skipping version %s - %s" % ( @@ -365,8 +394,16 @@ def main(): appid, traceback.format_exc())) probcount += 1 + for k, v in json_per_appid.items(): + if len(v['errors']) or len(v['warnings']) or len(v['infos']): + json_output[appid] = json_per_appid + break + logging.info(_("Finished")) - print(_("%d problems found") % probcount) + if options.json: + print(json.dumps(json_output)) + else: + print(_("%d problems found") % probcount) if __name__ == "__main__": diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index cbaa9de2..c6c1232c 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -6,7 +6,10 @@ import logging import optparse import os import sys +import tempfile +import textwrap import unittest +from unittest import mock localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) @@ -14,6 +17,7 @@ print('localmodule: ' + localmodule) if localmodule not in sys.path: sys.path.insert(0, localmodule) +import fdroidserver.build import fdroidserver.common import fdroidserver.metadata import fdroidserver.scanner @@ -24,8 +28,14 @@ class ScannerTest(unittest.TestCase): def setUp(self): logging.basicConfig(level=logging.INFO) self.basedir = os.path.join(localmodule, 'tests') + self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) + if not os.path.exists(self.tmpdir): + os.makedirs(self.tmpdir) + os.chdir(self.basedir) def test_scan_source_files(self): + fdroidserver.scanner.options = type('', (), {})() + fdroidserver.scanner.options.json = False source_files = os.path.join(self.basedir, 'source-files') projects = { 'cn.wildfirechat.chat': 4, @@ -43,6 +53,63 @@ class ScannerTest(unittest.TestCase): self.assertEqual(should, fatal_problems, "%s should have %d errors!" % (d, should)) + def test_build_local_scanner(self): + """`fdroid build` calls scanner functions, test them here""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.build.options = mock.Mock() + fdroidserver.build.options.json = False + fdroidserver.build.options.notarball = True + fdroidserver.build.options.skipscan = False + fdroidserver.scanner.options = fdroidserver.build.options + + app = fdroidserver.metadata.App() + app.id = 'mocked.app.id' + build = fdroidserver.metadata.Build() + build.commit = '1.0' + build.output = app.id + '.apk' + build.scanignore = ['baz.so'] + build.versionCode = '1' + build.versionName = '1.0' + vcs = mock.Mock() + + for f in ('baz.so', 'foo.aar', 'gradle-wrapper.jar'): + with open(f, 'w') as fp: + fp.write('placeholder') + self.assertTrue(os.path.exists(f)) + + with open('build.xml', 'w') as fp: + fp.write(textwrap.dedent( + """ + + + + """)) + + def make_fake_apk(output, build): + with open(build.output, 'w') as fp: + fp.write('APK PLACEHOLDER') + return output + + with mock.patch('fdroidserver.common.replace_build_vars', wraps=make_fake_apk): + with mock.patch('fdroidserver.common.get_native_code', return_value='x86'): + with mock.patch('fdroidserver.common.get_apk_id', + return_value=(app.id, build.versionCode, build.versionName)): + with mock.patch('fdroidserver.common.is_apk_and_debuggable', return_value=False): + fdroidserver.build.build_local( + app, build, vcs, + build_dir=testdir, output_dir=testdir, + log_dir=None, srclib_dir=None, extlib_dir=None, tmp_dir=None, + force=False, onserver=False, refresh=False + ) + self.assertTrue(os.path.exists('baz.so')) + self.assertTrue(os.path.exists('foo.aar')) + self.assertFalse(os.path.exists('gradle-wrapper.jar')) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 95c3ab2454ffea2afdc944b9e82e184922aebdc5 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 26 May 2020 11:13:54 +0200 Subject: [PATCH 0324/2775] skip yamllint test if yamllint is not installed !721 --- tests/common.TestCase | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/common.TestCase b/tests/common.TestCase index 93fbedd3..4dc51e5c 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1315,6 +1315,11 @@ class CommonTest(unittest.TestCase): self.assertEqual(ret, ('ACRA', None, 'srclib/ACRA')) def test_run_yamllint_wellformed(self): + try: + import yamllint.config + yamllint.config # make pyflakes ignore this + except ImportError: + self.skipTest('yamllint not installed') with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('wellformed.yml', 'w') as f: f.write(textwrap.dedent('''\ @@ -1328,6 +1333,11 @@ class CommonTest(unittest.TestCase): self.assertEqual(result, '') def test_run_yamllint_malformed(self): + try: + import yamllint.config + yamllint.config # make pyflakes ignore this + except ImportError: + self.skipTest('yamllint not installed') with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('malformed.yml', 'w') as f: f.write(textwrap.dedent('''\ From cc5aed3c1fb4b42276059e0b1d258ec8cd8fce4d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 25 May 2020 21:44:19 +0200 Subject: [PATCH 0325/2775] fix version codes in bash completion for `fdroid build` I'm not sure the old code ever worked, but this works now, and supports .yml. closes #719 --- completion/bash-completion | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index d679fbd9..f5a8fdb2 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -60,20 +60,14 @@ __apk_vercode() { } __vercode() { - local p v - echo $cur | IFS=':' read p v - - COMPREPLY=( $( compgen -P "${p}:" -W "$( while read line; do - if [[ "$line" == "Build Version:"* ]] - then - line="${line#*,}" - printf "${line%%,*} " - elif [[ "$line" == "Build:"* ]] - then - line="${line#*,}" - printf "${line%%,*} " - fi - done < "metadata/${p}.yml" )" -- $cur ) ) + if [ $prev = ":" ]; then + appid="${COMP_WORDS[COMP_CWORD-2]}" + elif [ $cur = ":" ]; then + appid=$prev + cur="" + fi + versionCodes=`sed -En 's,^ +versionCode: +([0-9]+) *$,\1,p' metadata/${appid}.yml` + COMPREPLY=( $( compgen -W "$versionCodes" -- $cur ) ) } __complete_options() { @@ -91,11 +85,16 @@ __complete_build() { opts="-v -q -l -s -t -f -a -w" lopts="--verbose --quiet --latest --stop --test --server --reset-server --skip-scan --no-tarball --force --all --wiki --no-refresh" + case "${prev}" in + :) + __vercode + return 0;; + esac case "${cur}" in -*) __complete_options return 0;; - *:*) + :) __vercode return 0;; *) From 1ed4ed61c76ed1482df7559bc2c436011a65e6e3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 27 May 2020 17:40:23 +0200 Subject: [PATCH 0326/2775] buildserver: explicitly include sudo as a dependency The basebox currently provides sudo, but that may not always be the case. This makes the sudo dependency explicit, so that this provisioning script can also be used in other settings, like GitLab CI. --- buildserver/provision-apt-get-install | 1 + 1 file changed, 1 insertion(+) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index 2ec3d2f9..7123b8a6 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -115,6 +115,7 @@ packages=" scons sqlite3 subversion + sudo swig unzip xsltproc From fc885c9b5ce962b09a4a0ef804c8f884d3c95cbc Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 27 May 2020 22:03:23 +0200 Subject: [PATCH 0327/2775] scanner: test for get_gradle_compile_commands() --- tests/scanner.TestCase | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index c6c1232c..4392664e 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -53,6 +53,33 @@ class ScannerTest(unittest.TestCase): self.assertEqual(should, fatal_problems, "%s should have %d errors!" % (d, should)) + def test_get_gradle_compile_commands(self): + test_files = [ + ('source-files/fdroid/fdroidclient/build.gradle', 'yes', 17), + ('source-files/com.nextcloud.client/build.gradle', 'generic', 24), + ('source-files/com.kunzisoft.testcase/build.gradle', 'libre', 4), + ('source-files/cn.wildfirechat.chat/chat/build.gradle', 'yes', 33), + ('source-files/org.tasks/app/build.gradle.kts', 'generic', 39), + ('source-files/at.bitfire.davdroid/build.gradle', 'standard', 16), + ('source-files/se.manyver/android/app/build.gradle', 'indie', 29), + ('source-files/osmandapp/osmand/build.gradle', 'free', 5), + ('source-files/eu.siacs.conversations/build.gradle', 'free', 23), + ('source-files/org.mozilla.rocket/app/build.gradle', 'focus', 42), + ] + + for f, flavor, count in test_files: + i = 0 + build = fdroidserver.metadata.Build() + build.gradle = [flavor] + regexs = fdroidserver.scanner.get_gradle_compile_commands(build) + with open(f) as fp: + for line in fp.readlines(): + for regex in regexs: + m = regex.match(line) + if m: + i += 1 + self.assertEqual(count, i) + def test_build_local_scanner(self): """`fdroid build` calls scanner functions, test them here""" testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) From 7a84679b0d7afaffd244ff71191443a9b56446c8 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 29 May 2020 21:55:10 +0200 Subject: [PATCH 0328/2775] gradlew-fdroid: fix parsing when files have Windows linefeeds The new test file should have Windows linefeeds, if I got the git config correct. --- gradlew-fdroid | 3 +++ .../AlarmClock/gradle/wrapper/gradle-wrapper.properties | 6 ++++++ tests/test-gradlew-fdroid | 5 +++++ 3 files changed, 14 insertions(+) create mode 100644 tests/source-files/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper.properties diff --git a/gradlew-fdroid b/gradlew-fdroid index 7664b1aa..97cd5394 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -168,6 +168,7 @@ for f in {.,..}/gradle/wrapper/gradle-wrapper.properties; do if [[ $line == 'distributionUrl='* ]]; then wrapper_ver=${line#*/gradle-} wrapper_ver=${wrapper_ver%-*.zip} + wrapper_ver=$(printf $wrapper_ver | tr -d '\r') # strip Windows linefeeds break 2 fi done < $f @@ -186,9 +187,11 @@ for f in {.,..}/build.gradle{,.kts}; do if [[ -z "$plugin_pver" && $line == *'com.android.tools.build:gradle:'* ]]; then plugin_pver=${line#*[\'\"]com.android.tools.build:gradle:} plugin_pver=${plugin_pver%[\'\"]*} + plugin_pver=$(printf $plugin_pver | tr -d '\r') # strip Windows linefeeds elif [[ -z "$wrapper_ver" && $line == *'gradleVersion = '* ]]; then wrapper_ver=${line#*gradleVersion*=*[\'\"]} wrapper_ver=${wrapper_ver%[\'\"]*} + wrapper_ver=$(printf $wrapper_ver | tr -d '\r') # strip Windows linefeeds fi done < $f done diff --git a/tests/source-files/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper.properties b/tests/source-files/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..a7a1a8ca --- /dev/null +++ b/tests/source-files/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Jan 30 10:59:12 CET 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip diff --git a/tests/test-gradlew-fdroid b/tests/test-gradlew-fdroid index d7f9884b..2a34f971 100755 --- a/tests/test-gradlew-fdroid +++ b/tests/test-gradlew-fdroid @@ -19,8 +19,13 @@ exit_value=0 basedir=$(cd $(dirname $0)/..; pwd) export https_proxy=127.7.7.7:7 # fake proxy to block downloading +# force test file to have Windows linefeeds +sed -i -e $'s/\r$//' -e $'s/$/\r/' \ + $basedir/tests/source-files/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper.properties + run_test osmandapp/osmand 2.2.1 run_test com.integreight.onesheeld 3.3 run_test se.manyver/android 5.5 +run_test yuriykulikov/AlarmClock 5.1.1 exit $exit_value From edd41b3c5824611d36e530ff2ebf65050fc208b2 Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Fri, 29 May 2020 16:23:20 -0400 Subject: [PATCH 0329/2775] Upgrade NDK r21b to r21c --- buildserver/config.buildserver.py | 2 +- buildserver/provision-android-ndk | 2 +- examples/config.py | 2 +- makebuildserver | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index 66aaaf2b..ce848482 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -11,7 +11,7 @@ ndk_paths = { 'r18b': "/home/vagrant/android-ndk/r18b", 'r19c': "/home/vagrant/android-ndk/r19c", 'r20b': "/home/vagrant/android-ndk/r20b", - 'r21b': "/home/vagrant/android-ndk/r21b", + 'r21c': "/home/vagrant/android-ndk/r21c", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index 32dd230b..69bfd7d5 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21b; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21c; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/examples/config.py b/examples/config.py index e2fa05d7..77edf2b6 100644 --- a/examples/config.py +++ b/examples/config.py @@ -22,7 +22,7 @@ # 'r18b': None, # 'r19c': None, # 'r20b': None, -# 'r21b': None, +# 'r21c': None, # } # Directory to store downloaded tools in (i.e. gradle versions) diff --git a/makebuildserver b/makebuildserver index dc5a689d..7c5d3ce4 100755 --- a/makebuildserver +++ b/makebuildserver @@ -394,8 +394,8 @@ CACHE_FILES = [ '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), ('https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip', '8381c440fe61fcbb01e209211ac01b519cd6adf51ab1c2281d5daad6ca4c8c8c'), - ('https://dl.google.com/android/repository/android-ndk-r21b-linux-x86_64.zip', - '0c7af5dd23c5d2564915194e71b1053578438ac992958904703161c7672cbed7'), + ('https://dl.google.com/android/repository/android-ndk-r21c-linux-x86_64.zip', + '214ebfcfa5108ba78f5b2cc8db4d575068f9c973ac7f27d2fa1987dfdb76c9e7'), ] From cfff954782050a242a3fe610553f11fe42768719 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 2 Jun 2020 13:34:15 +0200 Subject: [PATCH 0330/2775] add AGP 4.0 --- gradlew-fdroid | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 7664b1aa..6ca320d4 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -153,8 +153,8 @@ contains() { # (key) should accept. plugin versions are actually prefixes and catch sub- # versions as well. Pairs are taken from: # https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle -d_plugin_k=(3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2) -d_plugin_v=(5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) +d_plugin_k=(4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2) +d_plugin_v=(6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about plugin_v=(6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) From 83e069323100cc21591801de2e41c35d152429dc Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 2 Jun 2020 21:52:58 +0200 Subject: [PATCH 0331/2775] update lint bash-completion: -f --format --force-yamllint --- completion/bash-completion | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index f5a8fdb2..b79b143f 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -200,8 +200,8 @@ __complete_rewritemeta() { } __complete_lint() { - opts="-v -q" - lopts="--verbose --quiet" + opts="-v -q -f" + lopts="--verbose --quiet --force-yamllint --format" case "${cur}" in -*) __complete_options From 6c5887e9060e7d0c2a478d1051c7fe8c337940d4 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 2 Jun 2020 21:53:24 +0200 Subject: [PATCH 0332/2775] lint: make --force-yamllint error if yamllint is not installed https://gitlab.com/fdroid/fdroidserver/-/merge_requests/753#note_353829401 --- fdroidserver/lint.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index b39dd873..23f664fc 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -603,6 +603,9 @@ def main(): if app.Disabled: continue + if options.force_yamllint: + import yamllint # throw error if it is not installed + # only run yamllint when linting individual apps. if len(options.appid) > 0 or options.force_yamllint: From b2daf96284539c8d2d2659e0386664672f78107a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 2 Jun 2020 22:05:18 +0200 Subject: [PATCH 0333/2775] lint: fix pyflakes --- fdroidserver/lint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 23f664fc..4b7a8507 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -605,6 +605,7 @@ def main(): if options.force_yamllint: import yamllint # throw error if it is not installed + yamllint # make pyflakes ignore this # only run yamllint when linting individual apps. if len(options.appid) > 0 or options.force_yamllint: From 13d9a122bff528fa338810443c8ad5619217b15b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 3 Jan 2020 14:17:03 +0100 Subject: [PATCH 0334/2775] metadata: validate STRING and INT build field types This converts float/int to string for things like commit: or versionName:. For versionCode, which must be an integer, it throws an exception if the data is any other type. --- fdroidserver/metadata.py | 11 +++++++++- tests/metadata.TestCase | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 5531d369..b1be88f8 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -1159,10 +1159,19 @@ def post_parse_yaml_metadata(yamldata): for flag in build.keys(): _flagtype = flagtype(flag) - # concatenate script flags into a single string if they are stored as list if _flagtype is TYPE_SCRIPT: + # concatenate script flags into a single string if they are stored as list if isinstance(build[flag], list): build[flag] = ' && '.join(build[flag]) + elif _flagtype is TYPE_STRING: + # things like versionNames are strings, but without quotes can be numbers + if isinstance(build[flag], float) or isinstance(build[flag], int): + build[flag] = str(build[flag]) + elif _flagtype is TYPE_INT: + # versionCode must be int + if not isinstance(build[flag], int): + warn_or_exception(_('{build_flag} must be an integer, found: {value}') + .format(build_flag=flag, value=build[flag])) def write_yaml(mf, app): diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index c2c9aa57..ff0e11d7 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -15,6 +15,7 @@ import unittest import yaml import tempfile import textwrap +from collections import OrderedDict from unittest import mock localmodule = os.path.realpath( @@ -180,6 +181,50 @@ class MetadataTest(unittest.TestCase): self.maxDiff = None self.assertEqual(result.read(), orig.read()) + def test_post_parse_yaml_metadata(self): + fdroidserver.metadata.warnings_action = 'error' + yamldata = OrderedDict() + builds = [] + yamldata['Builds'] = builds + build = OrderedDict() + builds.append(build) + + build['versionCode'] = 1.1 + self.assertRaises(fdroidserver.exception.MetaDataException, + fdroidserver.metadata.post_parse_yaml_metadata, yamldata) + + build['versionCode'] = '1' + self.assertRaises(fdroidserver.exception.MetaDataException, + fdroidserver.metadata.post_parse_yaml_metadata, yamldata) + + build['versionCode'] = 1 + build['versionName'] = 1 + fdroidserver.metadata.post_parse_yaml_metadata(yamldata) + self.assertNotEqual(1, yamldata['Builds'][0]['versionName']) + self.assertEqual('1', yamldata['Builds'][0]['versionName']) + self.assertEqual(1, yamldata['Builds'][0]['versionCode']) + + build['versionName'] = 1.0 + fdroidserver.metadata.post_parse_yaml_metadata(yamldata) + self.assertNotEqual(1.0, yamldata['Builds'][0]['versionName']) + self.assertEqual('1.0', yamldata['Builds'][0]['versionName']) + + build['commit'] = 1.0 + fdroidserver.metadata.post_parse_yaml_metadata(yamldata) + self.assertNotEqual(1.0, yamldata['Builds'][0]['commit']) + self.assertEqual('1.0', yamldata['Builds'][0]['commit']) + + teststr = '98234fab134b' + build['commit'] = teststr + fdroidserver.metadata.post_parse_yaml_metadata(yamldata) + self.assertEqual(teststr, yamldata['Builds'][0]['commit']) + + testcommitid = 1234567890 + build['commit'] = testcommitid + fdroidserver.metadata.post_parse_yaml_metadata(yamldata) + self.assertNotEqual(testcommitid, yamldata['Builds'][0]['commit']) + self.assertEqual('1234567890', yamldata['Builds'][0]['commit']) + def test_read_metadata_sort_by_time(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) metadatadir = os.path.join(testdir, 'metadata') From 4c6941138761b34d1e6b65ca9d5259861d173371 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 4 Jun 2020 00:30:15 +0200 Subject: [PATCH 0335/2775] add gradle 6.5 --- gradlew-fdroid | 3 ++- makebuildserver | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index e35da603..bd290a66 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -137,6 +137,7 @@ get_sha() { '6.3') echo '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768' ;; '6.4') echo 'b888659f637887e759749f6226ddfcb1cb04f828c58c41279de73c463fdbacc9' ;; '6.4.1') echo 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd' ;; + '6.5') echo '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f' ;; *) exit 1 esac } @@ -157,7 +158,7 @@ d_plugin_k=(4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 d_plugin_v=(6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 7c5d3ce4..a73fab7a 100755 --- a/makebuildserver +++ b/makebuildserver @@ -372,6 +372,8 @@ CACHE_FILES = [ '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768'), ('https://services.gradle.org/distributions/gradle-6.4.1-bin.zip', 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd'), + ('https://services.gradle.org/distributions/gradle-6.5-bin.zip', + '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 581e433832b0ec0d64116b774b446016dc2383e7 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 4 Jun 2020 12:30:40 +0200 Subject: [PATCH 0336/2775] strip_and_copy_image: abort on broken symlinks Also guard against other processes removing the files we are about to copy. closes fdroid/fdroidserver#783 --- fdroidserver/update.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 4748a7f6..3b7c5951 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -797,6 +797,13 @@ def _strip_and_copy_image(in_file, outpath): """ logging.debug('copying ' + in_file + ' ' + outpath) + if not os.path.exists(in_file): + if os.path.islink(in_file): + logging.warning(_("Broken symlink: {path}").format(path=in_file)) + else: + logging.warning(_("File disappeared while processing it: {path}").format(path=in_file)) + return + if os.path.isdir(outpath): out_file = os.path.join(outpath, os.path.basename(in_file)) else: From b63e9e68c52ceb6a6e54a0010598485fd958fd7c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 9 Jun 2020 22:01:31 +0200 Subject: [PATCH 0337/2775] move all test metadata files to .yml format for f in metadata/*.txt; do ../fdroid rewritemeta --to yml $(basename $f | sed 's,\.txt,,'); done --- MANIFEST.in | 26 +- tests/lint.TestCase | 4 +- tests/metadata.TestCase | 2 +- .../app.with.special.build.params.txt | 72 -- .../app.with.special.build.params.yml | 99 ++ tests/metadata/com.politedroid.txt | 40 - tests/metadata/com.politedroid.yml | 47 + tests/metadata/dump/com.politedroid.yaml | 2 +- tests/metadata/dump/org.adaway.yaml | 12 +- .../dump/org.smssecure.smssecure.yaml | 2 +- tests/metadata/fake.ota.update.txt | 42 - tests/metadata/fake.ota.update.yml | 44 + .../metadata/info.guardianproject.checkey.txt | 12 - .../metadata/info.guardianproject.checkey.yml | 15 + tests/metadata/obb.main.oldversion.txt | 12 - tests/metadata/obb.main.oldversion.yml | 14 + tests/metadata/obb.main.twoversions.txt | 12 - tests/metadata/obb.main.twoversions.yml | 14 + tests/metadata/obb.mainpatch.current.txt | 12 - tests/metadata/obb.mainpatch.current.yml | 14 + tests/metadata/org.adaway.json | 285 ------ tests/metadata/org.adaway.yml | 330 ++++++ tests/metadata/org.fdroid.ci.test.app.txt | 2 - tests/metadata/org.fdroid.ci.test.app.yml | 7 + tests/metadata/org.fdroid.fdroid.txt | 721 ------------- tests/metadata/org.fdroid.fdroid.yml | 951 ++++++++++++++++++ tests/metadata/org.smssecure.smssecure.txt | 126 --- tests/metadata/org.smssecure.smssecure.yml | 164 +++ tests/metadata/raw.template.txt | 9 - tests/metadata/raw.template.yml | 7 + tests/metadata/souch.smsbypass.txt | 52 - tests/metadata/souch.smsbypass.yml | 61 ++ tests/publish.TestCase | 6 +- tests/run-tests | 12 +- .../RandomPackageNames.java | 2 +- 35 files changed, 1799 insertions(+), 1433 deletions(-) delete mode 100644 tests/metadata/app.with.special.build.params.txt create mode 100644 tests/metadata/app.with.special.build.params.yml delete mode 100644 tests/metadata/com.politedroid.txt create mode 100644 tests/metadata/com.politedroid.yml delete mode 100644 tests/metadata/fake.ota.update.txt create mode 100644 tests/metadata/fake.ota.update.yml delete mode 100644 tests/metadata/info.guardianproject.checkey.txt create mode 100644 tests/metadata/info.guardianproject.checkey.yml delete mode 100644 tests/metadata/obb.main.oldversion.txt create mode 100644 tests/metadata/obb.main.oldversion.yml delete mode 100644 tests/metadata/obb.main.twoversions.txt create mode 100644 tests/metadata/obb.main.twoversions.yml delete mode 100644 tests/metadata/obb.mainpatch.current.txt create mode 100644 tests/metadata/obb.mainpatch.current.yml delete mode 100644 tests/metadata/org.adaway.json create mode 100644 tests/metadata/org.adaway.yml delete mode 100644 tests/metadata/org.fdroid.ci.test.app.txt create mode 100644 tests/metadata/org.fdroid.ci.test.app.yml delete mode 100644 tests/metadata/org.fdroid.fdroid.txt create mode 100644 tests/metadata/org.fdroid.fdroid.yml delete mode 100644 tests/metadata/org.smssecure.smssecure.txt create mode 100644 tests/metadata/org.smssecure.smssecure.yml delete mode 100644 tests/metadata/raw.template.txt create mode 100644 tests/metadata/raw.template.yml delete mode 100644 tests/metadata/souch.smsbypass.txt create mode 100644 tests/metadata/souch.smsbypass.yml diff --git a/MANIFEST.in b/MANIFEST.in index 04434d18..4aa37974 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -560,19 +560,19 @@ include tests/keystore.jks include tests/lint.TestCase include tests/metadata/apk/info.guardianproject.urzip.yaml include tests/metadata/apk/org.dyndns.fules.ck.yaml -include tests/metadata/app.with.special.build.params.txt -include tests/metadata/com.politedroid.txt +include tests/metadata/app.with.special.build.params.yml +include tests/metadata/com.politedroid.yml include tests/metadata/dump/com.politedroid.yaml include tests/metadata/dump/org.adaway.yaml include tests/metadata/dump/org.smssecure.smssecure.yaml include tests/metadata/dump/org.videolan.vlc.yaml include tests/metadata/duplicate.permisssions.yml -include tests/metadata/fake.ota.update.txt +include tests/metadata/fake.ota.update.yml include tests/metadata/info.guardianproject.checkey/en-US/description.txt include tests/metadata/info.guardianproject.checkey/en-US/phoneScreenshots/checkey-phone.png include tests/metadata/info.guardianproject.checkey/en-US/phoneScreenshots/checkey.png include tests/metadata/info.guardianproject.checkey/en-US/summary.txt -include tests/metadata/info.guardianproject.checkey.txt +include tests/metadata/info.guardianproject.checkey.yml include tests/metadata/info.guardianproject.urzip/en-US/changelogs/100.txt include tests/metadata/info.guardianproject.urzip/en-US/full_description.txt include tests/metadata/info.guardianproject.urzip/en-US/images/featureGraphic.png @@ -583,25 +583,25 @@ include tests/metadata/info.guardianproject.urzip/en-US/video.txt include tests/metadata/info.guardianproject.urzip.yml include tests/metadata/info.zwanenburg.caffeinetile.yml include tests/metadata/no.min.target.sdk.yml -include tests/metadata/obb.main.oldversion.txt -include tests/metadata/obb.mainpatch.current.txt -include tests/metadata/obb.main.twoversions.txt -include tests/metadata/org.adaway.json -include tests/metadata/org.fdroid.ci.test.app.txt -include tests/metadata/org.fdroid.fdroid.txt +include tests/metadata/obb.main.oldversion.yml +include tests/metadata/obb.mainpatch.current.yml +include tests/metadata/obb.main.twoversions.yml +include tests/metadata/org.adaway.yml +include tests/metadata/org.fdroid.ci.test.app.yml +include tests/metadata/org.fdroid.fdroid.yml include tests/metadata/org.smssecure.smssecure/signatures/134/28969C09.RSA include tests/metadata/org.smssecure.smssecure/signatures/134/28969C09.SF include tests/metadata/org.smssecure.smssecure/signatures/134/MANIFEST.MF include tests/metadata/org.smssecure.smssecure/signatures/135/28969C09.RSA include tests/metadata/org.smssecure.smssecure/signatures/135/28969C09.SF include tests/metadata/org.smssecure.smssecure/signatures/135/MANIFEST.MF -include tests/metadata/org.smssecure.smssecure.txt +include tests/metadata/org.smssecure.smssecure.yml include tests/metadata/org.videolan.vlc.yml -include tests/metadata/raw.template.txt +include tests/metadata/raw.template.yml include tests/metadata-rewrite-yml/app.with.special.build.params.yml include tests/metadata-rewrite-yml/fake.ota.update.yml include tests/metadata-rewrite-yml/org.fdroid.fdroid.yml -include tests/metadata/souch.smsbypass.txt +include tests/metadata/souch.smsbypass.yml include tests/metadata.TestCase include tests/openssl-version-check-test.py include tests/org.bitbucket.tickytacky.mirrormirror_1.apk diff --git a/tests/lint.TestCase b/tests/lint.TestCase index 54cfc365..783b6f1f 100755 --- a/tests/lint.TestCase +++ b/tests/lint.TestCase @@ -48,8 +48,8 @@ class LintTest(unittest.TestCase): os.path.join(tmptestsdir, 'metadata'), ignore=shutil.ignore_patterns('apk', 'dump', '*.json')) self.assertFalse(fdroidserver.lint.check_for_unsupported_metadata_files(tmptestsdir + '/')) - shutil.copy(os.path.join(localmodule, 'tests', 'metadata', 'org.adaway.json'), - os.path.join(tmptestsdir, 'metadata')) + with open(os.path.join(tmptestsdir, 'metadata', 'org.adaway.json'), 'w') as fp: + fp.write('placeholder') self.assertTrue(fdroidserver.lint.check_for_unsupported_metadata_files(tmptestsdir + '/')) def test_forbidden_html_tags(self): diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index ff0e11d7..ab636a35 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -232,7 +232,7 @@ class MetadataTest(unittest.TestCase): fdroidserver.common.config = {'accepted_formats': ['txt']} randomlist = [] - randomapps = glob.glob(os.path.join(self.basedir, 'metadata', '*.txt')) + randomapps = glob.glob(os.path.join(self.basedir, 'metadata', '*.yml')) random.shuffle(randomapps) i = 1 for f in randomapps: diff --git a/tests/metadata/app.with.special.build.params.txt b/tests/metadata/app.with.special.build.params.txt deleted file mode 100644 index 3592fbce..00000000 --- a/tests/metadata/app.with.special.build.params.txt +++ /dev/null @@ -1,72 +0,0 @@ -AntiFeatures:UpstreamNonFree -Categories:System -License:GPL-3.0-only -Web Site: -Source Code:https://github.com/loadrunner/Facebook-Contact-Sync -Issue Tracker:https://github.com/loadrunner/Facebook-Contact-Sync/issues - -Auto Name:UberSync for Facebook -Summary:Sync your Facebook Contacts -Description: -To configure, go to "Settings => Accounts & Sync => Add Account". Depending on -how many friends you have, the first import might take a while, so be patient. - -* Facebook does not allow to export phone numbers or emails: only names, pictures and statuses are synced. -* Facebook users have the option to block one or all apps: if they opt for that, they will be EXCLUDED from your friends list. - -Appbrain SDK was removed before building. -. - -Repo Type:git -Repo:https://github.com/loadrunner/Facebook-Contact-Sync.git - -Build:1.0.0,32 - commit=b3879c973e7cac3a3319 - -Build:1.0.1,33 - commit=252c8dd4c9 - -Build:1.2.0,39 - commit=v1.2.0 - patch=appbrain.patch - srclibs=FacebookSDK@sdk-version-3.0.1 - rm=libs/appbrain-sdk-android.jar - prebuild=sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties && \ - sed -i 's/Class\[\]/Class\\[\]/g' $$FacebookSDK$$/src/com/facebook/model/GraphObject.java - -Build:1.2.2,42 - commit=v1.2.2 - patch=appbrain.patch - srclibs=FacebookSDK@sdk-version-3.0.2 - rm=libs/appbrain-sdk-android.jar - extlibs=android/android-support-v4.jar - prebuild=mv libs/android-support-v4.jar $$FacebookSDK$$/libs/ && \ - sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties && \ - sed -i 's/Class\[\]/Class\\[\]/g' $$FacebookSDK$$/src/com/facebook/model/GraphObject.java - -Build:2.1.1,48 - commit=2.1.1 - patch=manifest-ads.patch,mobilecore.patch - maven=yes - srclibs=FacebookSDK@sdk-version-3.0.2 - -Build:2.1.1-b,49 - commit=2.1.1 - patch=manifest-ads.patch,mobilecore.patch - maven=yes@.. - srclibs=FacebookSDK@sdk-version-3.0.2 - -Build:2.1.1-c,50 - commit=2.1.1 - patch=manifest-ads.patch,mobilecore.patch - maven=2 - srclibs=FacebookSDK@sdk-version-3.0.2 - -Build:2.1.2,51 - disable=Labelled as pre-release, so skipped - -Archive Policy:0 versions -Auto Update Mode:None -Update Check Mode:None -Current Version:2.1.2 -Current Version Code:49 diff --git a/tests/metadata/app.with.special.build.params.yml b/tests/metadata/app.with.special.build.params.yml new file mode 100644 index 00000000..e7755881 --- /dev/null +++ b/tests/metadata/app.with.special.build.params.yml @@ -0,0 +1,99 @@ +AntiFeatures: + - UpstreamNonFree +Categories: + - System +License: GPL-3.0-only +SourceCode: https://github.com/loadrunner/Facebook-Contact-Sync +IssueTracker: https://github.com/loadrunner/Facebook-Contact-Sync/issues + +AutoName: UberSync for Facebook +Summary: Sync your Facebook Contacts +Description: |- + To configure, go to "Settings => Accounts & Sync => Add Account". Depending on + how many friends you have, the first import might take a while, so be patient. + + * Facebook does not allow to export phone numbers or emails: only names, pictures and statuses are synced. + * Facebook users have the option to block one or all apps: if they opt for that, they will be EXCLUDED from your friends list. + + Appbrain SDK was removed before building. + +RepoType: git +Repo: https://github.com/loadrunner/Facebook-Contact-Sync.git + +Builds: + - versionName: 1.0.0 + versionCode: 32 + commit: b3879c973e7cac3a3319 + + - versionName: 1.0.1 + versionCode: 33 + commit: 252c8dd4c9 + + - versionName: 1.2.0 + versionCode: 39 + commit: v1.2.0 + patch: + - appbrain.patch + srclibs: + - FacebookSDK@sdk-version-3.0.1 + rm: + - libs/appbrain-sdk-android.jar + prebuild: + - sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties + - sed -i 's/Class\[\]/Class\\[\]/g' $$FacebookSDK$$/src/com/facebook/model/GraphObject.java + + - versionName: 1.2.2 + versionCode: 42 + commit: v1.2.2 + patch: + - appbrain.patch + srclibs: + - FacebookSDK@sdk-version-3.0.2 + rm: + - libs/appbrain-sdk-android.jar + extlibs: + - android/android-support-v4.jar + prebuild: + - mv libs/android-support-v4.jar $$FacebookSDK$$/libs/ + - sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties + - sed -i 's/Class\[\]/Class\\[\]/g' $$FacebookSDK$$/src/com/facebook/model/GraphObject.java + + - versionName: 2.1.1 + versionCode: 48 + commit: 2.1.1 + patch: + - manifest-ads.patch + - mobilecore.patch + maven: 'yes' + srclibs: + - FacebookSDK@sdk-version-3.0.2 + + - versionName: 2.1.1-b + versionCode: 49 + commit: 2.1.1 + patch: + - manifest-ads.patch + - mobilecore.patch + maven: yes@.. + srclibs: + - FacebookSDK@sdk-version-3.0.2 + + - versionName: 2.1.1-c + versionCode: 50 + commit: 2.1.1 + patch: + - manifest-ads.patch + - mobilecore.patch + maven: '2' + srclibs: + - FacebookSDK@sdk-version-3.0.2 + + - versionName: 2.1.2 + versionCode: 51 + disable: Labelled as pre-release, so skipped + +ArchivePolicy: 0 versions +AutoUpdateMode: None +UpdateCheckMode: None +CurrentVersion: 2.1.2 +CurrentVersionCode: 49 diff --git a/tests/metadata/com.politedroid.txt b/tests/metadata/com.politedroid.txt deleted file mode 100644 index 135e5e8d..00000000 --- a/tests/metadata/com.politedroid.txt +++ /dev/null @@ -1,40 +0,0 @@ -Categories:Time -License:GPL-3.0-only -Web Site: -Source Code:https://github.com/miguelvps/PoliteDroid -Issue Tracker:https://github.com/miguelvps/PoliteDroid/issues - -Auto Name:Polite Droid -Summary:Calendar tool -Description: -Activates silent mode during calendar events. -. - -Repo Type:git -Repo:https://github.com/miguelvps/PoliteDroid.git - -Build:1.2,3 - commit=6a548e4b19 - target=android-10 - antifeatures=KnownVuln,UpstreamNonFree,NonFreeAssets - -Build:1.3,4 - commit=ad865b57bf3ac59580f38485608a9b1dda4fa7dc - target=android-15 - -Build:1.4,5 - commit=456bd615f3fbe6dff06433928cf7ea20073601fb - target=android-10 - -Build:1.5,6 - commit=v1.5 - sudo=echo 'this is just a test' - gradle=yes - -Archive Policy:4 versions -Auto Update Mode:Version v%v -Update Check Mode:Tags -Current Version:1.5 -Current Version Code:6 - -No Source Since:1.5 diff --git a/tests/metadata/com.politedroid.yml b/tests/metadata/com.politedroid.yml new file mode 100644 index 00000000..c138b6c8 --- /dev/null +++ b/tests/metadata/com.politedroid.yml @@ -0,0 +1,47 @@ +Categories: + - Time +License: GPL-3.0-only +SourceCode: https://github.com/miguelvps/PoliteDroid +IssueTracker: https://github.com/miguelvps/PoliteDroid/issues + +AutoName: Polite Droid +Summary: Calendar tool +Description: Activates silent mode during calendar events. + +RepoType: git +Repo: https://github.com/miguelvps/PoliteDroid.git + +Builds: + - versionName: '1.2' + versionCode: 3 + commit: 6a548e4b19 + target: android-10 + antifeatures: + - KnownVuln + - UpstreamNonFree + - NonFreeAssets + + - versionName: '1.3' + versionCode: 4 + commit: ad865b57bf3ac59580f38485608a9b1dda4fa7dc + target: android-15 + + - versionName: '1.4' + versionCode: 5 + commit: 456bd615f3fbe6dff06433928cf7ea20073601fb + target: android-10 + + - versionName: '1.5' + versionCode: 6 + commit: v1.5 + sudo: echo 'this is just a test' + gradle: + - yes + +ArchivePolicy: 4 versions +AutoUpdateMode: Version v%v +UpdateCheckMode: Tags +CurrentVersion: '1.5' +CurrentVersionCode: 6 + +NoSourceSince: '1.5' diff --git a/tests/metadata/dump/com.politedroid.yaml b/tests/metadata/dump/com.politedroid.yaml index 5d80e30e..48b4ac44 100644 --- a/tests/metadata/dump/com.politedroid.yaml +++ b/tests/metadata/dump/com.politedroid.yaml @@ -182,4 +182,4 @@ builds: comments: {} id: com.politedroid lastUpdated: null -metadatapath: metadata/com.politedroid.txt +metadatapath: metadata/com.politedroid.yml diff --git a/tests/metadata/dump/org.adaway.yaml b/tests/metadata/dump/org.adaway.yaml index 6412aaa3..00e59bd2 100644 --- a/tests/metadata/dump/org.adaway.yaml +++ b/tests/metadata/dump/org.adaway.yaml @@ -47,10 +47,10 @@ MaintainerNotes: '' Name: null NoSourceSince: '' OpenCollective: null -Provides: org.sufficientlysecure.adaway +Provides: null Repo: https://github.com/dschuermann/ad-away.git RepoType: git -RequiresRoot: true +RequiresRoot: false SourceCode: https://github.com/dschuermann/ad-away Summary: Block advertisements Translation: https://www.transifex.com/dominikschuermann/adaway @@ -1085,11 +1085,7 @@ builds: timeout: null versionCode: '52' versionName: '3.0' -comments: - build:40: - - '#RootCommands srclib needs changing on fdroidserver' - build:42: - - '#RootCommands srclib needs changing on fdroidserver' +comments: {} id: org.adaway lastUpdated: null -metadatapath: metadata/org.adaway.json +metadatapath: metadata/org.adaway.yml diff --git a/tests/metadata/dump/org.smssecure.smssecure.yaml b/tests/metadata/dump/org.smssecure.smssecure.yaml index 688e7d26..5fc47857 100644 --- a/tests/metadata/dump/org.smssecure.smssecure.yaml +++ b/tests/metadata/dump/org.smssecure.smssecure.yaml @@ -364,4 +364,4 @@ builds: comments: {} id: org.smssecure.smssecure lastUpdated: null -metadatapath: metadata/org.smssecure.smssecure.txt +metadatapath: metadata/org.smssecure.smssecure.yml diff --git a/tests/metadata/fake.ota.update.txt b/tests/metadata/fake.ota.update.txt deleted file mode 100644 index 165da014..00000000 --- a/tests/metadata/fake.ota.update.txt +++ /dev/null @@ -1,42 +0,0 @@ -Categories:System -License:Apache-2.0 -Web Site:https://f-droid.org -Source Code:https://gitlab.com/fdroid/privileged-extension -Issue Tracker:https://gitlab.com/fdroid/privileged-extension/issues -Donate:https://f-droid.org/about - -Auto Name:Fake OTA Update -Summary:Tests whether OTA ZIP files are being include -Description: -F-Droid can make use of system privileges or permissions to -install, update and remove applications on its own. The only way to obtain those -privileges is to become a system app. - -This is where the Privileged Extension comes in - being a separate app and much -smaller, it can be installed as a system app and communicate with the main app -via AIDL IPC. - -This has several advantages: - -* Reduced disk usage in the system partition -* System updates don't remove F-Droid -* The process of installing into system via root is safer - -This is packaged as an OTA (Over-The-Air) update ZIP file. It must be installed -using TWRP or other Android recovery that can flash updates to the system from -the /data/data/org.fdroid.fdroid folder on the /data partition. The standalone -APK is called F-Droid Privileged Extension. -. - -Repo Type:git -Repo:https://gitlab.com/fdroid/privileged-extension.git - -Build:0.2.1,2000 - commit=0.2.1 - output=app/build/distributions/FDroidPrivilegedExtensionFromBinaries-$$VERSION$$.zip - build=gradle assembleUpdateZipFromBinariesDebug - -Auto Update Mode:Version %v -Update Check Mode:Tags -Current Version:0.2.1 -Current Version Code:2000 diff --git a/tests/metadata/fake.ota.update.yml b/tests/metadata/fake.ota.update.yml new file mode 100644 index 00000000..dc8b6b9c --- /dev/null +++ b/tests/metadata/fake.ota.update.yml @@ -0,0 +1,44 @@ +Categories: + - System +License: Apache-2.0 +WebSite: https://f-droid.org +SourceCode: https://gitlab.com/fdroid/privileged-extension +IssueTracker: https://gitlab.com/fdroid/privileged-extension/issues +Donate: https://f-droid.org/about + +AutoName: Fake OTA Update +Summary: Tests whether OTA ZIP files are being include +Description: |- + F-Droid can make use of system privileges or permissions to + install, update and remove applications on its own. The only way to obtain those + privileges is to become a system app. + + This is where the Privileged Extension comes in - being a separate app and much + smaller, it can be installed as a system app and communicate with the main app + via AIDL IPC. + + This has several advantages: + + * Reduced disk usage in the system partition + * System updates don't remove F-Droid + * The process of installing into system via root is safer + + This is packaged as an OTA (Over-The-Air) update ZIP file. It must be installed + using TWRP or other Android recovery that can flash updates to the system from + the /data/data/org.fdroid.fdroid folder on the /data partition. The standalone + APK is called F-Droid Privileged Extension. + +RepoType: git +Repo: https://gitlab.com/fdroid/privileged-extension.git + +Builds: + - versionName: 0.2.1 + versionCode: 2000 + commit: 0.2.1 + output: app/build/distributions/FDroidPrivilegedExtensionFromBinaries-$$VERSION$$.zip + build: gradle assembleUpdateZipFromBinariesDebug + +AutoUpdateMode: Version %v +UpdateCheckMode: Tags +CurrentVersion: 0.2.1 +CurrentVersionCode: 2000 diff --git a/tests/metadata/info.guardianproject.checkey.txt b/tests/metadata/info.guardianproject.checkey.txt deleted file mode 100644 index c6d7557c..00000000 --- a/tests/metadata/info.guardianproject.checkey.txt +++ /dev/null @@ -1,12 +0,0 @@ -Categories:Development,GuardianProject -License:GPL-3.0-only -Web Site:https://dev.guardianproject.info/projects/checkey -Source Code:https://github.com/guardianproject/checkey -Issue Tracker:https://dev.guardianproject.info/projects/checkey/issues -Translation:https://www.transifex.com/otf/checkey -Bitcoin:1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk - -Auto Name:Checkey - - -Current Version Code:9999999 diff --git a/tests/metadata/info.guardianproject.checkey.yml b/tests/metadata/info.guardianproject.checkey.yml new file mode 100644 index 00000000..2a0119c4 --- /dev/null +++ b/tests/metadata/info.guardianproject.checkey.yml @@ -0,0 +1,15 @@ +Categories: + - Development + - GuardianProject +License: GPL-3.0-only +WebSite: https://dev.guardianproject.info/projects/checkey +SourceCode: https://github.com/guardianproject/checkey +IssueTracker: https://dev.guardianproject.info/projects/checkey/issues +Translation: https://www.transifex.com/otf/checkey +Bitcoin: 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk + +AutoName: Checkey + +AutoUpdateMode: None +UpdateCheckMode: None +CurrentVersionCode: 9999999 diff --git a/tests/metadata/obb.main.oldversion.txt b/tests/metadata/obb.main.oldversion.txt deleted file mode 100644 index 0a4e4956..00000000 --- a/tests/metadata/obb.main.oldversion.txt +++ /dev/null @@ -1,12 +0,0 @@ -Categories:Development -License:GPL-3.0-only -Source Code:https://github.com/eighthave/urzip -Bitcoin:1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk - -Auto Name:OBB Main Old Version - -Repo Type:git -Repo:https://github.com/eighthave/urzip.git - - -Current Version Code:99999999 diff --git a/tests/metadata/obb.main.oldversion.yml b/tests/metadata/obb.main.oldversion.yml new file mode 100644 index 00000000..1d18e69c --- /dev/null +++ b/tests/metadata/obb.main.oldversion.yml @@ -0,0 +1,14 @@ +Categories: + - Development +License: GPL-3.0-only +SourceCode: https://github.com/eighthave/urzip +Bitcoin: 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk + +AutoName: OBB Main Old Version + +RepoType: git +Repo: https://github.com/eighthave/urzip.git + +AutoUpdateMode: None +UpdateCheckMode: None +CurrentVersionCode: 99999999 diff --git a/tests/metadata/obb.main.twoversions.txt b/tests/metadata/obb.main.twoversions.txt deleted file mode 100644 index 69fb5909..00000000 --- a/tests/metadata/obb.main.twoversions.txt +++ /dev/null @@ -1,12 +0,0 @@ -Categories:Development -License:GPL-3.0-only -Source Code:https://github.com/eighthave/urzip -Bitcoin:1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk - -Auto Name:OBB Two Versions - -Repo Type:git -Repo:https://github.com/eighthave/urzip.git - - -Current Version Code:99999999 diff --git a/tests/metadata/obb.main.twoversions.yml b/tests/metadata/obb.main.twoversions.yml new file mode 100644 index 00000000..69ca50d1 --- /dev/null +++ b/tests/metadata/obb.main.twoversions.yml @@ -0,0 +1,14 @@ +Categories: + - Development +License: GPL-3.0-only +SourceCode: https://github.com/eighthave/urzip +Bitcoin: 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk + +AutoName: OBB Two Versions + +RepoType: git +Repo: https://github.com/eighthave/urzip.git + +AutoUpdateMode: None +UpdateCheckMode: None +CurrentVersionCode: 99999999 diff --git a/tests/metadata/obb.mainpatch.current.txt b/tests/metadata/obb.mainpatch.current.txt deleted file mode 100644 index 7cc4ae64..00000000 --- a/tests/metadata/obb.mainpatch.current.txt +++ /dev/null @@ -1,12 +0,0 @@ -Categories:Development -License:GPL-3.0-only -Source Code:https://github.com/eighthave/urzip -Bitcoin:1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk - -Auto Name:OBB Main+Patch Current Version - -Repo Type:git -Repo:https://github.com/eighthave/urzip.git - - -Current Version Code:99999999 diff --git a/tests/metadata/obb.mainpatch.current.yml b/tests/metadata/obb.mainpatch.current.yml new file mode 100644 index 00000000..865f34c6 --- /dev/null +++ b/tests/metadata/obb.mainpatch.current.yml @@ -0,0 +1,14 @@ +Categories: + - Development +License: GPL-3.0-only +SourceCode: https://github.com/eighthave/urzip +Bitcoin: 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk + +AutoName: OBB Main+Patch Current Version + +RepoType: git +Repo: https://github.com/eighthave/urzip.git + +AutoUpdateMode: None +UpdateCheckMode: None +CurrentVersionCode: 99999999 diff --git a/tests/metadata/org.adaway.json b/tests/metadata/org.adaway.json deleted file mode 100644 index df71f112..00000000 --- a/tests/metadata/org.adaway.json +++ /dev/null @@ -1,285 +0,0 @@ -{ - "AutoName": "AdAway", - "AutoUpdateMode": "Version v%v", - "Categories": ["System", "Security"], - "CurrentVersion": "3.0", - "CurrentVersionCode": 52, - "Description": [ - "An ad blocker that uses the hosts file. The hosts file", - "contains a list of mappings between hostnames and IP addresses. When", - "an app requests an ad, that request is directed to 127.0.0.1 which does", - "nothing. There are options to run a web server", - "to respond to blocked hostnames and to direct requests to the IP", - "address of your choosing. You can download hosts files from the", - "app but it is possible to use your own and to add certain sites", - "to the white- and black-lists.", - "", - "[https://github.com/dschuermann/ad-away/raw/HEAD/CHANGELOG Changelog]", - "", - "Requires root: Yes. The hosts files is located in /system which is normally", - "read-only." - ], - "Donate": "http://sufficientlysecure.org/index.php/adaway", - "FlattrID": "369138", - "IssueTracker": "https://github.com/dschuermann/ad-away/issues", - "License": "GPL-3.0-only", - "Provides": "org.sufficientlysecure.adaway", - "Repo": "https://github.com/dschuermann/ad-away.git", - "RepoType": "git", - "RequiresRoot": true, - "SourceCode": "https://github.com/dschuermann/ad-away", - "Summary": "Block advertisements", - "Translation": "https://www.transifex.com/dominikschuermann/adaway", - "UpdateCheckMode": "Tags", - "WebSite": "http://sufficientlysecure.org/index.php/adaway", - - "builds": [ - { - "buildjni": true, - "commit": "ea5378a94ee0dc1d99d2cec95fae7e6d81afb2b9", - "subdir": "org_adaway/", - "versionCode": 13, - "versionName": "1.12" - }, - { - "buildjni": true, - "commit": "4128e59da2eac5c2904c7c7568d298ca51e79540", - "patch": ["defprop.patch"], - "subdir": "org_adaway/", - "versionCode": 16, - "versionName": "1.15" - }, - { - "buildjni": true, - "commit": "0b9985398b9eef7baf6aadd0dbb12002bc199d2e", - "patch": ["defprop.patch"], - "subdir": "org_adaway/", - "versionCode": 19, - "versionName": "1.18" - }, - { - "buildjni": true, - "commit": "ab27f4dab5f3ea5e228cfb4a6b0e1fbf53695f22", - "patch": ["defprop.patch"], - "subdir": "org_adaway/", - "versionCode": 20, - "versionName": "1.19" - }, - { - "buildjni": true, - "commit": "695e3801e4081026c8f7213a2345fc451d5eb89c", - "patch": ["defprop.patch"], - "subdir": "org_adaway/", - "versionCode": 21, - "versionName": "1.20" - }, - { - "buildjni": true, - "commit": "65138c11cc8b6affd28b68e125fbc1dff0886a4e", - "patch": ["defprop.patch"], - "subdir": "org_adaway/", - "versionCode": 22, - "versionName": "1.21" - }, - { - "commit": "unknown - see disabled", - "disable": "no source in repo", - "versionCode": 24, - "versionName": "1.23" - }, - { - "buildjni": true, - "commit": "f811e53e1e1d2ee047b18715fd7d2072b90ae76b", - "prebuild": "android update project -p ../com_actionbarsherlock", - "subdir": "org_adaway/", - "versionCode": 25, - "versionName": "1.24" - }, - { - "buildjni": true, - "commit": "ff97932761cdee68638dc2550751a64b2cbe18e7", - "prebuild": "android update project -p ../com_actionbarsherlock", - "subdir": "org_adaway/", - "versionCode": 26, - "versionName": "1.25" - }, - { - "buildjni": true, - "commit": "33d4d80998f30bafc88c04c80cbae00b03916f99", - "prebuild": "android update project -p ../com_actionbarsherlock", - "subdir": "org_adaway/", - "versionCode": 27, - "versionName": "1.26" - }, - { - "buildjni": true, - "commit": "743d25a7e287505461f33f4b8e57e4cf988fffea", - "prebuild": "android update project -p ../com_actionbarsherlock", - "subdir": "org_adaway/", - "versionCode": 28, - "versionName": "1.27" - }, - { - "buildjni": true, - "commit": "eaa07f4", - "prebuild": "android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/*", - "subdir": "org_adaway/", - "versionCode": 30, - "versionName": "1.29" - }, - { - "buildjni": false, - "commit": "71ced3f", - "prebuild": "android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && rm libs/android-support-v4.jar", - "subdir": "org_adaway/", - "versionCode": 33, - "versionName": "1.32" - }, - { - "buildjni": false, - "commit": "9d63c18", - "prebuild": "android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/*", - "subdir": "org_adaway/", - "versionCode": 34, - "versionName": "1.33" - }, - { - "buildjni": false, - "commit": "f2568b1", - "prebuild": "android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && android update project -p ../org_donations", - "subdir": "org_adaway/", - "versionCode": 35, - "versionName": "1.34" - }, - { - "buildjni": false, - "commit": "7442d5d", - "prebuild": "android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && android update project -p ../org_donations", - "subdir": "org_adaway/", - "versionCode": 36, - "versionName": "1.35" - }, - { - "buildjni": false, - "commit": "83fc713", - "prebuild": "android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && android update project -p ../org_donations", - "subdir": "org_adaway/", - "versionCode": 37, - "versionName": "1.36" - }, - { - "buildjni": false, - "commit": "70da32b567122b701cdcb1609b780eb85732028f", - "prebuild": "android update project -p ../com_actionbarsherlock && rm -rf libs/armeabi/* && android update project -p ../org_donations", - "subdir": "org_adaway/", - "versionCode": 38, - "versionName": "1.37" - }, - { - "buildjni": true, - "commit": "v2.1", - "extlibs": ["htmlcleaner/htmlcleaner-2.2.jar"], - "init": "rm android-libs/Donations/custom_rules.xml && git clone https://github.com/dschuermann/HtmlSpanner android-libs/HtmlSpanner", - "prebuild": "rm -rf ../update_zip libs/root-commands-1.2.jar libs/htmlspanner-0.2-fork.jar && cp -f libs/htmlcleaner-2.2.jar android-libs/HtmlSpanner/htmlspanner/libs/ && echo \"android.library.reference.3=$$RootCommands$$\" >> project.properties && echo \"android.library.reference.4=android-libs/HtmlSpanner/htmlspanner\" >> project.properties && find . -type f -print0 | xargs -0 sed -i 's/org.rootcommands/org.sufficientlysecure.rootcommands/g' && cp android-libs/Donations/ant-templates/other/DonationsConfig.java android-libs/Donations/src/org/donations/", - "srclibs": ["RootCommands@c940b0e503"], - "subdir": "AdAway", - "androidupdate": [".", - "android-libs/Donations", - "android-libs/ActionBarSherlock", - "android-libs/HtmlSpanner/htmlspanner"], - "versionCode": 40, - "versionName": "2.1" - }, - { - "buildjni": true, - "commit": "v2.3", - "extlibs": ["htmlcleaner/htmlcleaner-2.2.jar"], - "init": "rm android-libs/Donations/custom_rules.xml && git clone https://github.com/dschuermann/HtmlSpanner android-libs/HtmlSpanner", - "prebuild": "rm -rf ../update_zip libs/root-commands-1.2.jar libs/htmlspanner-0.2-fork.jar && cp -f libs/htmlcleaner-2.2.jar android-libs/HtmlSpanner/htmlspanner/libs/ && echo \"android.library.reference.3=$$RootCommands$$\" >> project.properties && echo \"android.library.reference.4=android-libs/HtmlSpanner/htmlspanner\" >> project.properties && find . -type f -print0 | xargs -0 sed -i 's/org.rootcommands/org.sufficientlysecure.rootcommands/g' && cp android-libs/Donations/ant-templates/other/DonationsConfig.java android-libs/Donations/src/org/donations/", - "srclibs": ["RootCommands@c940b0e503"], - "subdir": "AdAway", - "androidupdate": [".", - "android-libs/Donations", - "android-libs/ActionBarSherlock", - "android-libs/HtmlSpanner/htmlspanner"], - "versionCode": 42, - "versionName": "2.3" - }, - { - "buildjni": true, - "commit": "v2.6", - "gradle": true, - "preassemble": ["renameExecutables"], - "subdir": "AdAway", - "versionCode": 45, - "versionName": "2.6" - }, - { - "buildjni": true, - "commit": "v2.7", - "gradle": true, - "preassemble": ["renameExecutables"], - "subdir": "AdAway", - "versionCode": 46, - "versionName": "2.7" - }, - { - "buildjni": true, - "commit": "v2.8", - "gradle": true, - "preassemble": ["renameExecutables"], - "subdir": "AdAway", - "versionCode": 47, - "versionName": "2.8" - }, - { - "buildjni": true, - "commit": "v2.8.1", - "gradle": true, - "preassemble": ["renameExecutables"], - "subdir": "AdAway", - "versionCode": 48, - "versionName": "2.8.1" - }, - { - "buildjni": true, - "commit": "v2.9", - "gradle": true, - "preassemble": ["renameExecutables"], - "subdir": "AdAway", - "versionCode": 49, - "versionName": "2.9" - }, - { - "buildjni": true, - "commit": "v2.9.1", - "gradle": true, - "preassemble": ["renameExecutables"], - "subdir": "AdAway", - "versionCode": 50, - "versionName": "2.9.1" - }, - { - "buildjni": true, - "commit": "v2.9.2", - "gradle": true, - "preassemble": ["renameExecutables"], - "subdir": "AdAway", - "versionCode": 51, - "versionName": "2.9.2" - }, - { - "buildjni": true, - "commit": "v3.0", - "gradle": true, - "preassemble": ["renameExecutables"], - "subdir": "AdAway", - "versionCode": 52, - "versionName": "3.0" - } - ], - "comments": { - "build:40": ["#RootCommands srclib needs changing on fdroidserver"], - "build:42": ["#RootCommands srclib needs changing on fdroidserver"] - } -} diff --git a/tests/metadata/org.adaway.yml b/tests/metadata/org.adaway.yml new file mode 100644 index 00000000..41bdb083 --- /dev/null +++ b/tests/metadata/org.adaway.yml @@ -0,0 +1,330 @@ +Categories: + - System + - Security +License: GPL-3.0-only +WebSite: http://sufficientlysecure.org/index.php/adaway +SourceCode: https://github.com/dschuermann/ad-away +IssueTracker: https://github.com/dschuermann/ad-away/issues +Translation: https://www.transifex.com/dominikschuermann/adaway +Donate: http://sufficientlysecure.org/index.php/adaway +FlattrID: '369138' + +AutoName: AdAway +Summary: Block advertisements +Description: |- + An ad blocker that uses the hosts file. The hosts file + contains a list of mappings between hostnames and IP addresses. When + an app requests an ad, that request is directed to 127.0.0.1 which does + nothing. There are options to run a web server + to respond to blocked hostnames and to direct requests to the IP + address of your choosing. You can download hosts files from the + app but it is possible to use your own and to add certain sites + to the white- and black-lists. + + [https://github.com/dschuermann/ad-away/raw/HEAD/CHANGELOG Changelog] + + Requires root: Yes. The hosts files is located in /system which is normally + read-only. + +RepoType: git +Repo: https://github.com/dschuermann/ad-away.git + +Builds: + - versionName: '1.12' + versionCode: 13 + commit: ea5378a94ee0dc1d99d2cec95fae7e6d81afb2b9 + subdir: org_adaway/ + buildjni: + - yes + + - versionName: '1.15' + versionCode: 16 + commit: 4128e59da2eac5c2904c7c7568d298ca51e79540 + subdir: org_adaway/ + patch: + - defprop.patch + buildjni: + - yes + + - versionName: '1.18' + versionCode: 19 + commit: 0b9985398b9eef7baf6aadd0dbb12002bc199d2e + subdir: org_adaway/ + patch: + - defprop.patch + buildjni: + - yes + + - versionName: '1.19' + versionCode: 20 + commit: ab27f4dab5f3ea5e228cfb4a6b0e1fbf53695f22 + subdir: org_adaway/ + patch: + - defprop.patch + buildjni: + - yes + + - versionName: '1.20' + versionCode: 21 + commit: 695e3801e4081026c8f7213a2345fc451d5eb89c + subdir: org_adaway/ + patch: + - defprop.patch + buildjni: + - yes + + - versionName: '1.21' + versionCode: 22 + commit: 65138c11cc8b6affd28b68e125fbc1dff0886a4e + subdir: org_adaway/ + patch: + - defprop.patch + buildjni: + - yes + + - versionName: '1.23' + versionCode: 24 + disable: no source in repo + commit: unknown - see disabled + + - versionName: '1.24' + versionCode: 25 + commit: f811e53e1e1d2ee047b18715fd7d2072b90ae76b + subdir: org_adaway/ + prebuild: android update project -p ../com_actionbarsherlock + buildjni: + - yes + + - versionName: '1.25' + versionCode: 26 + commit: ff97932761cdee68638dc2550751a64b2cbe18e7 + subdir: org_adaway/ + prebuild: android update project -p ../com_actionbarsherlock + buildjni: + - yes + + - versionName: '1.26' + versionCode: 27 + commit: 33d4d80998f30bafc88c04c80cbae00b03916f99 + subdir: org_adaway/ + prebuild: android update project -p ../com_actionbarsherlock + buildjni: + - yes + + - versionName: '1.27' + versionCode: 28 + commit: 743d25a7e287505461f33f4b8e57e4cf988fffea + subdir: org_adaway/ + prebuild: android update project -p ../com_actionbarsherlock + buildjni: + - yes + + - versionName: '1.29' + versionCode: 30 + commit: eaa07f4 + subdir: org_adaway/ + prebuild: + - android update project -p ../com_actionbarsherlock + - rm -rf libs/armeabi/* + buildjni: + - yes + + - versionName: '1.32' + versionCode: 33 + commit: 71ced3f + subdir: org_adaway/ + prebuild: + - android update project -p ../com_actionbarsherlock + - rm -rf libs/armeabi/* + - rm libs/android-support-v4.jar + + - versionName: '1.33' + versionCode: 34 + commit: 9d63c18 + subdir: org_adaway/ + prebuild: + - android update project -p ../com_actionbarsherlock + - rm -rf libs/armeabi/* + + - versionName: '1.34' + versionCode: 35 + commit: f2568b1 + subdir: org_adaway/ + prebuild: + - android update project -p ../com_actionbarsherlock + - rm -rf libs/armeabi/* + - android update project -p ../org_donations + + - versionName: '1.35' + versionCode: 36 + commit: 7442d5d + subdir: org_adaway/ + prebuild: + - android update project -p ../com_actionbarsherlock + - rm -rf libs/armeabi/* + - android update project -p ../org_donations + + - versionName: '1.36' + versionCode: 37 + commit: 83fc713 + subdir: org_adaway/ + prebuild: + - android update project -p ../com_actionbarsherlock + - rm -rf libs/armeabi/* + - android update project -p ../org_donations + + - versionName: '1.37' + versionCode: 38 + commit: 70da32b567122b701cdcb1609b780eb85732028f + subdir: org_adaway/ + prebuild: + - android update project -p ../com_actionbarsherlock + - rm -rf libs/armeabi/* + - android update project -p ../org_donations + + - versionName: '2.1' + versionCode: 40 + commit: v2.1 + subdir: AdAway + init: + - rm android-libs/Donations/custom_rules.xml + - git clone https://github.com/dschuermann/HtmlSpanner android-libs/HtmlSpanner + srclibs: + - RootCommands@c940b0e503 + extlibs: + - htmlcleaner/htmlcleaner-2.2.jar + prebuild: + - rm -rf ../update_zip libs/root-commands-1.2.jar libs/htmlspanner-0.2-fork.jar + - cp -f libs/htmlcleaner-2.2.jar android-libs/HtmlSpanner/htmlspanner/libs/ + - echo "android.library.reference.3=$$RootCommands$$" >> project.properties + - echo "android.library.reference.4=android-libs/HtmlSpanner/htmlspanner" >> + project.properties + - find . -type f -print0 | xargs -0 sed -i 's/org.rootcommands/org.sufficientlysecure.rootcommands/g' + - cp android-libs/Donations/ant-templates/other/DonationsConfig.java android-libs/Donations/src/org/donations/ + androidupdate: + - . + - android-libs/Donations + - android-libs/ActionBarSherlock + - android-libs/HtmlSpanner/htmlspanner + buildjni: + - yes + + - versionName: '2.3' + versionCode: 42 + commit: v2.3 + subdir: AdAway + init: + - rm android-libs/Donations/custom_rules.xml + - git clone https://github.com/dschuermann/HtmlSpanner android-libs/HtmlSpanner + srclibs: + - RootCommands@c940b0e503 + extlibs: + - htmlcleaner/htmlcleaner-2.2.jar + prebuild: + - rm -rf ../update_zip libs/root-commands-1.2.jar libs/htmlspanner-0.2-fork.jar + - cp -f libs/htmlcleaner-2.2.jar android-libs/HtmlSpanner/htmlspanner/libs/ + - echo "android.library.reference.3=$$RootCommands$$" >> project.properties + - echo "android.library.reference.4=android-libs/HtmlSpanner/htmlspanner" >> + project.properties + - find . -type f -print0 | xargs -0 sed -i 's/org.rootcommands/org.sufficientlysecure.rootcommands/g' + - cp android-libs/Donations/ant-templates/other/DonationsConfig.java android-libs/Donations/src/org/donations/ + androidupdate: + - . + - android-libs/Donations + - android-libs/ActionBarSherlock + - android-libs/HtmlSpanner/htmlspanner + buildjni: + - yes + + - versionName: '2.6' + versionCode: 45 + commit: v2.6 + subdir: AdAway + gradle: + - yes + buildjni: + - yes + preassemble: + - renameExecutables + + - versionName: '2.7' + versionCode: 46 + commit: v2.7 + subdir: AdAway + gradle: + - yes + buildjni: + - yes + preassemble: + - renameExecutables + + - versionName: '2.8' + versionCode: 47 + commit: v2.8 + subdir: AdAway + gradle: + - yes + buildjni: + - yes + preassemble: + - renameExecutables + + - versionName: 2.8.1 + versionCode: 48 + commit: v2.8.1 + subdir: AdAway + gradle: + - yes + buildjni: + - yes + preassemble: + - renameExecutables + + - versionName: '2.9' + versionCode: 49 + commit: v2.9 + subdir: AdAway + gradle: + - yes + buildjni: + - yes + preassemble: + - renameExecutables + + - versionName: 2.9.1 + versionCode: 50 + commit: v2.9.1 + subdir: AdAway + gradle: + - yes + buildjni: + - yes + preassemble: + - renameExecutables + + - versionName: 2.9.2 + versionCode: 51 + commit: v2.9.2 + subdir: AdAway + gradle: + - yes + buildjni: + - yes + preassemble: + - renameExecutables + + - versionName: '3.0' + versionCode: 52 + commit: v3.0 + subdir: AdAway + gradle: + - yes + buildjni: + - yes + preassemble: + - renameExecutables + +AutoUpdateMode: Version v%v +UpdateCheckMode: Tags +CurrentVersion: '3.0' +CurrentVersionCode: 52 diff --git a/tests/metadata/org.fdroid.ci.test.app.txt b/tests/metadata/org.fdroid.ci.test.app.txt deleted file mode 100644 index 466b7af6..00000000 --- a/tests/metadata/org.fdroid.ci.test.app.txt +++ /dev/null @@ -1,2 +0,0 @@ -Repo Type:git -Repo:https://gitlab.com/eighthave/ci-test-app diff --git a/tests/metadata/org.fdroid.ci.test.app.yml b/tests/metadata/org.fdroid.ci.test.app.yml new file mode 100644 index 00000000..09c63ce0 --- /dev/null +++ b/tests/metadata/org.fdroid.ci.test.app.yml @@ -0,0 +1,7 @@ +License: Unknown + +RepoType: git +Repo: https://gitlab.com/eighthave/ci-test-app + +AutoUpdateMode: None +UpdateCheckMode: None diff --git a/tests/metadata/org.fdroid.fdroid.txt b/tests/metadata/org.fdroid.fdroid.txt deleted file mode 100644 index f5a5e199..00000000 --- a/tests/metadata/org.fdroid.fdroid.txt +++ /dev/null @@ -1,721 +0,0 @@ -Categories:System -License:GPL-3.0-or-later -Web Site:https://f-droid.org -Source Code:https://gitlab.com/fdroid/fdroidclient -Issue Tracker:https://gitlab.com/fdroid/fdroidclient/issues -Translation:https://hosted.weblate.org/projects/f-droid/f-droid -Changelog:https://gitlab.com/fdroid/fdroidclient/raw/HEAD/CHANGELOG.md -Donate:https://f-droid.org/about -FlattrID:343053 -Bitcoin:15u8aAPK4jJ5N8wpWJ5gutAyyeHtKX5i18 - -Auto Name:F-Droid -Summary:Application manager -Description: -Connects to F-Droid compatible repositories. The default repo is hosted at -f-droid.org, which contains only bona fide FOSS. - -Android is open in the sense that you are free to install apks from anywhere you -wish, but there are many good reasons for using a client/repository setup: - -* Be notified when updates are available -* Keep track of older and beta versions -* Filter apps that aren't compatible with the device -* Find apps via categories and searchable descriptions -* Access associated urls for donations, source code etc. -* Stay safe by checking repo index signatures and apk hashes -. - -Repo Type:srclib -Repo:fdroidclient - -Build:0.17,8 - commit=c626ce5f6d3e10ae15942f01ff028be310cc695a - init=rm -f build.xml - -Build:0.18,9 - commit=a6c9ed8d06b19315df9ba9041324f78139f7d238 - init=rm -f build.xml - -Build:0.19,10 - commit=540b7d0522f4d67a4896697f7342e4c75b4cbf59 - init=rm -f build.xml - -Build:0.20,11 - commit=ddacfb856ad66c1c367e20c9cbecbfb15fe00813 - init=rm -f build.xml - -Build:0.21,12 - commit=49fa56aa6626a190f2d711120b69e435e9e615b1 - init=rm -f build.xml - -Build:0.22,13 - commit=a6a33c942495cc4c74a7cb6e968efe0e00815e68 - init=rm -f build.xml - -Build:0.23,14 - commit=aa58a8aad1a1c3832eafb9f1bdd6db8292d2c172 - init=rm -f build.xml - -Build:0.24,15 - commit=9b5fe2976443255b95027abd412f1c1e7f3d27b2 - init=rm -f build.xml - -Build:0.25,16 - commit=43977cc493e47a4dc841c4192ae8a40fb14b639b - init=rm -f build.xml - -Build:0.28,19 - commit=f881aabe5bd0ac94771b03f1318a6e0972ab4128 - target=android-15 - -Build:0.29,20 - commit=87b229b95d0909bfd05c65c5670794e743626f6c - target=android-15 - -Build:0.30,21 - commit=497cb19840f79b31ae9590f5abd9e4df832b34ee - target=android-15 - -Build:0.31,22 - commit=f99f8a544c7cb4d4a48ad09da00ad281af05f2ac - target=android-15 - -Build:0.32,23 - commit=cc3970cc243e345416bfc62781ece6eeefd11495 - target=android-15 - -Build:0.33,24 - commit=58eb580159aa4d54767f0af1736cad233fec2475 - target=android-15 - -Build:0.34-test,25 - commit=335d27b725b0f92e9e8804ae09518cd47bc7b021 - target=android-15 - -Build:0.35-test,26 - commit=a06d18b029392669e98359f86c07e442a04e6a13 - target=android-15 - -Build:0.36-test,27 - commit=647e230c9e888c04bb0554078c5aa81da63548a0 - target=android-15 - -Build:0.37-test,28 - commit=3c02e3ccc147a34af42cedf7d85f18dc75c8efa8 - target=android-15 - -Build:0.38,38 - commit=99b52c988d203811f434d6ac40675a63d5ae41ab - target=android-15 - -Build:0.39-test,39 - commit=9a7d0b9f10710105d51d8206a7faa4408c60c20d - target=android-15 - -Build:0.40,40 - commit=51a67efdf1ee2819bee99d9263b2980dafaf761d - target=android-15 - -Build:0.42,42 - commit=36b815095ef51ca4f21887d973dbc0a50575cd65 - target=android-15 - -Build:0.43,43 - disable=sdk doesn't like tzm (at f2109e4e0bf1597c625221d8d2d10050f146ba5a) - commit=f2109e4e0bf1597c625221d8d2d10050f146ba5a - target=android-15 - -Build:0.44,44 - disable=nasty upgrade bug - commit=0.44 - target=android-15 - -Build:0.45,45 - commit=0.45 - target=android-15 - -Build:0.46,46 - commit=0.46 - target=android-15 - -Build:0.47-test,47 - commit=0.47-test - target=android-17 - -Build:0.48-test,48 - commit=0.48-test - target=android-17 - -Build:0.50,50 - commit=0.50 - -Build:0.51-test,51 - commit=0.51-test - -Build:0.52-test,52 - commit=0.52-test - submodules=yes - prebuild=rm -rf extern/Universal-Image-Loader/downloads - update=.,extern/Universal-Image-Loader/library - -Build:0.53-test,53 - commit=0.53-test - submodules=yes - scandelete=yes - -Build:0.54,540 - commit=0.54 - submodules=yes - scandelete=yes - -Build:0.55,550 - commit=0.55 - submodules=yes - -Build:0.56-test,560 - commit=0.56-test - submodules=yes - -Build:0.57-test,570 - commit=0.57-test - submodules=yes - -Build:0.58,580 - commit=0.58 - submodules=yes - -Build:0.59-test,590 - commit=0.59-test - submodules=yes - -Build:0.61-test,610 - commit=0.61-test - submodules=yes - -Build:0.62,620 - commit=0.62 - submodules=yes - -Build:0.63,630 - commit=0.63 - submodules=yes - -Build:0.64-test,640 - commit=0.64-test - submodules=yes - -Build:0.65,650 - commit=0.65 - submodules=yes - -Build:0.66,660 - commit=0.66 - submodules=yes - -Build:0.67-test,670 - commit=0.67-test - submodules=yes - -Build:0.68-test,680 - commit=0.68-test - submodules=yes - -Build:0.69-test,690 - commit=0.69-test - submodules=yes - -Build:0.70-test,700 - commit=0.70-test - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.71,710 - disable=Broken MTM/AndroidPinning - commit=0.71 - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.72,720 - disable=proguard issues - commit=0.72 - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.73,730 - disable=local repos broken - commit=0.73 - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.74,740 - disable=still some proguard issues - commit=0.74 - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.75,750 - disable=repo update progress crasher - commit=0.75 - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.76,760 - commit=0.76 - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.77-test,770 - commit=0.77-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.78,780 - commit=0.78 - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.79-test,790 - commit=0.79-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.80-test,800 - commit=0.80-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.81-test,810 - commit=0.81-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.82,820 - commit=0.82 - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.83,830 - commit=0.83 - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.84-test,840 - commit=0.84-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.85-test,850 - commit=0.85-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.86-test,860 - commit=0.86-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.87-test,870 - commit=0.87-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.88,880 - commit=0.88 - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.89-test,890 - commit=0.89-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.90-test,900 - commit=0.90-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.91,910 - commit=0.91 - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.92,920 - commit=0.92 - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.93-test,930 - commit=0.93-test - subdir=F-Droid - submodules=yes - prebuild=./ant-prepare.sh - update=. - -Build:0.94-test,940 - commit=0.94-test - subdir=F-Droid - submodules=yes - gradle=yes - -Build:0.95-alpha1,95001 - commit=0.95-alpha1 - subdir=F-Droid - submodules=yes - gradle=yes - -Build:0.95-alpha2,95002 - commit=v0.95-alpha2 - subdir=F-Droid - submodules=yes - gradle=yes - -Build:0.95,95050 - commit=v0.95 - subdir=F-Droid - submodules=yes - gradle=yes - -Build:0.95.1,95150 - commit=v0.95.1 - subdir=F-Droid - submodules=yes - gradle=yes - -Build:0.96-alpha1,96001 - commit=v0.96-alpha1 - subdir=F-Droid - gradle=yes - -Build:0.96-alpha2,96002 - commit=v0.96-alpha2 - subdir=F-Droid - gradle=yes - -Build:0.96-alpha3,96003 - commit=v0.96-alpha3 - subdir=F-Droid - gradle=yes - -Build:0.96-alpha4,96004 - commit=v0.96-alpha4 - subdir=F-Droid - gradle=yes - -Build:0.96-alpha5,96005 - commit=v0.96-alpha5 - subdir=F-Droid - gradle=yes - -Build:0.96-alpha6,96006 - commit=v0.96-alpha6 - subdir=F-Droid - gradle=yes - -Build:0.96,96050 - commit=v0.96 - subdir=F-Droid - gradle=yes - scanignore=extern/AndroidPinning/res/raw/cacerts - -Build:0.96.1,96150 - commit=v0.96.1 - subdir=F-Droid - gradle=yes - scanignore=extern/AndroidPinning/res/raw/cacerts - -Build:0.97-alpha1,97001 - commit=v0.97-alpha1 - subdir=F-Droid - gradle=yes - scanignore=extern/AndroidPinning/res/raw/cacerts - -Build:0.97-alpha2,97002 - commit=v0.97-alpha2 - subdir=F-Droid - gradle=yes - -Build:0.97-alpha3,97003 - commit=v0.97-alpha3 - subdir=F-Droid - gradle=yes - -Build:0.97-alpha4,97004 - commit=v0.97-alpha4 - subdir=F-Droid - gradle=yes - -Build:0.97-alpha5,97005 - commit=v0.97-alpha5 - subdir=F-Droid - gradle=yes - -Build:0.97-alpha6,97006 - commit=v0.97-alpha6 - subdir=F-Droid - gradle=yes - -Build:0.97-alpha7,97007 - commit=v0.97-alpha7 - subdir=F-Droid - gradle=yes - -Build:0.97-alpha8,97008 - commit=v0.97-alpha8 - subdir=F-Droid - gradle=yes - -Build:0.97,97050 - commit=v0.97 - subdir=F-Droid - gradle=yes - -Build:0.98-alpha1,98001 - commit=v0.98-alpha1 - subdir=F-Droid - gradle=yes - -Build:0.98-alpha2,98002 - commit=v0.98-alpha2 - subdir=F-Droid - gradle=yes - -Build:0.98-alpha3,98003 - commit=v0.98-alpha3 - subdir=F-Droid - gradle=yes - -Build:0.98-alpha4,98004 - commit=v0.98-alpha4 - subdir=F-Droid - gradle=yes - -Build:0.98-alpha5,98005 - commit=v0.98-alpha5 - subdir=F-Droid - gradle=yes - -Build:0.98-alpha6,98006 - commit=v0.98-alpha6 - subdir=F-Droid - gradle=yes - -Build:0.98-alpha7,98007 - commit=v0.98-alpha7 - subdir=F-Droid - gradle=yes - -Build:0.98,98050 - commit=v0.98 - subdir=F-Droid - gradle=yes - -Build:0.98.1,98150 - commit=v0.98.1 - subdir=F-Droid - gradle=yes - -Build:0.99-alpha1,99001 - commit=v0.99-alpha1 - subdir=F-Droid - gradle=yes - -Build:0.99-alpha2,99002 - commit=v0.99-alpha2 - subdir=F-Droid - gradle=yes - -Build:0.99,99050 - commit=v0.99 - subdir=F-Droid - gradle=yes - -Build:0.99.1,99150 - commit=v0.99.1 - subdir=F-Droid - gradle=yes - -Build:0.99.2,99250 - commit=v0.99.2 - subdir=F-Droid - gradle=yes - -Build:0.100-alpha1,100001 - commit=v0.100-alpha1 - subdir=F-Droid - gradle=yes - -Build:0.100-alpha2,100002 - commit=v0.100-alpha2 - subdir=F-Droid - gradle=yes - -Build:0.100-alpha3,100003 - commit=v0.100-alpha3 - subdir=app - gradle=yes - -Build:0.100-alpha4,100004 - commit=v0.100-alpha4 - subdir=app - gradle=yes - -Build:0.100-alpha5,100005 - commit=v0.100-alpha5 - subdir=app - gradle=yes - -Build:0.100-alpha6,100006 - commit=v0.100-alpha6 - subdir=app - gradle=yes - -Build:0.100-alpha7,100007 - commit=v0.100-alpha7 - subdir=app - gradle=yes - -Build:0.100-alpha8,100008 - commit=v0.100-alpha8 - subdir=app - gradle=yes - -Build:0.100,100050 - commit=v0.100 - subdir=app - gradle=yes - -Build:0.100.1,100150 - commit=v0.100.1 - subdir=app - gradle=yes - -Build:0.101-alpha1,101001 - commit=v0.101-alpha1 - subdir=app - gradle=yes - -Build:0.101-alpha2,101002 - commit=v0.101-alpha2 - subdir=app - gradle=yes - -Build:0.101-alpha3,101003 - commit=v0.101-alpha3 - subdir=app - gradle=yes - -Build:0.101-alpha4,101004 - commit=v0.101-alpha4 - subdir=app - gradle=yes - -Build:0.101-alpha5,101005 - commit=v0.101-alpha5 - subdir=app - gradle=yes - -Build:0.101-alpha6,101006 - commit=v0.101-alpha6 - subdir=app - gradle=yes - -Build:0.101,101050 - commit=v0.101 - subdir=app - gradle=yes - -Build:0.102-alpha1,102001 - commit=v0.102-alpha1 - subdir=app - gradle=yes - -Build:0.102-alpha2,102002 - commit=v0.102-alpha2 - subdir=app - gradle=yes - -Build:0.102-alpha3,102003 - commit=v0.102-alpha3 - subdir=app - gradle=yes - -Build:0.102,102050 - commit=v0.102 - subdir=app - gradle=yes - -Build:0.102.1,102150 - commit=v0.102.1 - subdir=app - gradle=yes - -Build:0.102.2,102250 - commit=v0.102.2 - subdir=app - gradle=yes - -Build:0.102.3,102350 - commit=v0.102.3 - subdir=app - gradle=yes - -Build:0.103-alpha1,103001 - commit=v0.103-alpha1 - subdir=app - gradle=yes - -Build:0.103-alpha2,103002 - commit=v0.103-alpha2 - subdir=app - gradle=yes - -Build:0.103-alpha3,103003 - commit=v0.103-alpha3 - subdir=app - gradle=yes - -Archive Policy:12 versions -Auto Update Mode:None -Update Check Mode:Static -Current Version:0.102.3 -Current Version Code:102350 diff --git a/tests/metadata/org.fdroid.fdroid.yml b/tests/metadata/org.fdroid.fdroid.yml new file mode 100644 index 00000000..9471f9a6 --- /dev/null +++ b/tests/metadata/org.fdroid.fdroid.yml @@ -0,0 +1,951 @@ +Categories: + - System +License: GPL-3.0-or-later +WebSite: https://f-droid.org +SourceCode: https://gitlab.com/fdroid/fdroidclient +IssueTracker: https://gitlab.com/fdroid/fdroidclient/issues +Translation: https://hosted.weblate.org/projects/f-droid/f-droid +Changelog: https://gitlab.com/fdroid/fdroidclient/raw/HEAD/CHANGELOG.md +Donate: https://f-droid.org/about +FlattrID: '343053' +Bitcoin: 15u8aAPK4jJ5N8wpWJ5gutAyyeHtKX5i18 + +AutoName: F-Droid +Summary: Application manager +Description: |- + Connects to F-Droid compatible repositories. The default repo is hosted at + f-droid.org, which contains only bona fide FOSS. + + Android is open in the sense that you are free to install apks from anywhere you + wish, but there are many good reasons for using a client/repository setup: + + * Be notified when updates are available + * Keep track of older and beta versions + * Filter apps that aren't compatible with the device + * Find apps via categories and searchable descriptions + * Access associated urls for donations, source code etc. + * Stay safe by checking repo index signatures and apk hashes + +RepoType: srclib +Repo: fdroidclient + +Builds: + - versionName: '0.17' + versionCode: 8 + commit: c626ce5f6d3e10ae15942f01ff028be310cc695a + init: rm -f build.xml + + - versionName: '0.18' + versionCode: 9 + commit: a6c9ed8d06b19315df9ba9041324f78139f7d238 + init: rm -f build.xml + + - versionName: '0.19' + versionCode: 10 + commit: 540b7d0522f4d67a4896697f7342e4c75b4cbf59 + init: rm -f build.xml + + - versionName: '0.20' + versionCode: 11 + commit: ddacfb856ad66c1c367e20c9cbecbfb15fe00813 + init: rm -f build.xml + + - versionName: '0.21' + versionCode: 12 + commit: 49fa56aa6626a190f2d711120b69e435e9e615b1 + init: rm -f build.xml + + - versionName: '0.22' + versionCode: 13 + commit: a6a33c942495cc4c74a7cb6e968efe0e00815e68 + init: rm -f build.xml + + - versionName: '0.23' + versionCode: 14 + commit: aa58a8aad1a1c3832eafb9f1bdd6db8292d2c172 + init: rm -f build.xml + + - versionName: '0.24' + versionCode: 15 + commit: 9b5fe2976443255b95027abd412f1c1e7f3d27b2 + init: rm -f build.xml + + - versionName: '0.25' + versionCode: 16 + commit: 43977cc493e47a4dc841c4192ae8a40fb14b639b + init: rm -f build.xml + + - versionName: '0.28' + versionCode: 19 + commit: f881aabe5bd0ac94771b03f1318a6e0972ab4128 + target: android-15 + + - versionName: '0.29' + versionCode: 20 + commit: 87b229b95d0909bfd05c65c5670794e743626f6c + target: android-15 + + - versionName: '0.30' + versionCode: 21 + commit: 497cb19840f79b31ae9590f5abd9e4df832b34ee + target: android-15 + + - versionName: '0.31' + versionCode: 22 + commit: f99f8a544c7cb4d4a48ad09da00ad281af05f2ac + target: android-15 + + - versionName: '0.32' + versionCode: 23 + commit: cc3970cc243e345416bfc62781ece6eeefd11495 + target: android-15 + + - versionName: '0.33' + versionCode: 24 + commit: 58eb580159aa4d54767f0af1736cad233fec2475 + target: android-15 + + - versionName: 0.34-test + versionCode: 25 + commit: 335d27b725b0f92e9e8804ae09518cd47bc7b021 + target: android-15 + + - versionName: 0.35-test + versionCode: 26 + commit: a06d18b029392669e98359f86c07e442a04e6a13 + target: android-15 + + - versionName: 0.36-test + versionCode: 27 + commit: 647e230c9e888c04bb0554078c5aa81da63548a0 + target: android-15 + + - versionName: 0.37-test + versionCode: 28 + commit: 3c02e3ccc147a34af42cedf7d85f18dc75c8efa8 + target: android-15 + + - versionName: '0.38' + versionCode: 38 + commit: 99b52c988d203811f434d6ac40675a63d5ae41ab + target: android-15 + + - versionName: 0.39-test + versionCode: 39 + commit: 9a7d0b9f10710105d51d8206a7faa4408c60c20d + target: android-15 + + - versionName: '0.40' + versionCode: 40 + commit: 51a67efdf1ee2819bee99d9263b2980dafaf761d + target: android-15 + + - versionName: '0.42' + versionCode: 42 + commit: 36b815095ef51ca4f21887d973dbc0a50575cd65 + target: android-15 + + - versionName: '0.43' + versionCode: 43 + disable: sdk doesn't like tzm (at f2109e4e0bf1597c625221d8d2d10050f146ba5a) + commit: f2109e4e0bf1597c625221d8d2d10050f146ba5a + target: android-15 + + - versionName: '0.44' + versionCode: 44 + disable: nasty upgrade bug + commit: '0.44' + target: android-15 + + - versionName: '0.45' + versionCode: 45 + commit: '0.45' + target: android-15 + + - versionName: '0.46' + versionCode: 46 + commit: '0.46' + target: android-15 + + - versionName: 0.47-test + versionCode: 47 + commit: 0.47-test + target: android-17 + + - versionName: 0.48-test + versionCode: 48 + commit: 0.48-test + target: android-17 + + - versionName: '0.50' + versionCode: 50 + commit: '0.50' + + - versionName: 0.51-test + versionCode: 51 + commit: 0.51-test + + - versionName: 0.52-test + versionCode: 52 + commit: 0.52-test + submodules: true + prebuild: rm -rf extern/Universal-Image-Loader/downloads + androidupdate: + - . + - extern/Universal-Image-Loader/library + + - versionName: 0.53-test + versionCode: 53 + commit: 0.53-test + submodules: true + scandelete: + - yes + + - versionName: '0.54' + versionCode: 540 + commit: '0.54' + submodules: true + scandelete: + - yes + + - versionName: '0.55' + versionCode: 550 + commit: '0.55' + submodules: true + + - versionName: 0.56-test + versionCode: 560 + commit: 0.56-test + submodules: true + + - versionName: 0.57-test + versionCode: 570 + commit: 0.57-test + submodules: true + + - versionName: '0.58' + versionCode: 580 + commit: '0.58' + submodules: true + + - versionName: 0.59-test + versionCode: 590 + commit: 0.59-test + submodules: true + + - versionName: 0.61-test + versionCode: 610 + commit: 0.61-test + submodules: true + + - versionName: '0.62' + versionCode: 620 + commit: '0.62' + submodules: true + + - versionName: '0.63' + versionCode: 630 + commit: '0.63' + submodules: true + + - versionName: 0.64-test + versionCode: 640 + commit: 0.64-test + submodules: true + + - versionName: '0.65' + versionCode: 650 + commit: '0.65' + submodules: true + + - versionName: '0.66' + versionCode: 660 + commit: '0.66' + submodules: true + + - versionName: 0.67-test + versionCode: 670 + commit: 0.67-test + submodules: true + + - versionName: 0.68-test + versionCode: 680 + commit: 0.68-test + submodules: true + + - versionName: 0.69-test + versionCode: 690 + commit: 0.69-test + submodules: true + + - versionName: 0.70-test + versionCode: 700 + commit: 0.70-test + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.71' + versionCode: 710 + disable: Broken MTM/AndroidPinning + commit: '0.71' + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.72' + versionCode: 720 + disable: proguard issues + commit: '0.72' + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.73' + versionCode: 730 + disable: local repos broken + commit: '0.73' + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.74' + versionCode: 740 + disable: still some proguard issues + commit: '0.74' + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.75' + versionCode: 750 + disable: repo update progress crasher + commit: '0.75' + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.76' + versionCode: 760 + commit: '0.76' + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.77-test + versionCode: 770 + commit: 0.77-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.78' + versionCode: 780 + commit: '0.78' + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.79-test + versionCode: 790 + commit: 0.79-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.80-test + versionCode: 800 + commit: 0.80-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.81-test + versionCode: 810 + commit: 0.81-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.82' + versionCode: 820 + commit: '0.82' + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.83' + versionCode: 830 + commit: '0.83' + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.84-test + versionCode: 840 + commit: 0.84-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.85-test + versionCode: 850 + commit: 0.85-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.86-test + versionCode: 860 + commit: 0.86-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.87-test + versionCode: 870 + commit: 0.87-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.88' + versionCode: 880 + commit: '0.88' + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.89-test + versionCode: 890 + commit: 0.89-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.90-test + versionCode: 900 + commit: 0.90-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.91' + versionCode: 910 + commit: '0.91' + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: '0.92' + versionCode: 920 + commit: '0.92' + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.93-test + versionCode: 930 + commit: 0.93-test + subdir: F-Droid + submodules: true + prebuild: ./ant-prepare.sh + androidupdate: + - . + + - versionName: 0.94-test + versionCode: 940 + commit: 0.94-test + subdir: F-Droid + submodules: true + gradle: + - yes + + - versionName: 0.95-alpha1 + versionCode: 95001 + commit: 0.95-alpha1 + subdir: F-Droid + submodules: true + gradle: + - yes + + - versionName: 0.95-alpha2 + versionCode: 95002 + commit: v0.95-alpha2 + subdir: F-Droid + submodules: true + gradle: + - yes + + - versionName: '0.95' + versionCode: 95050 + commit: v0.95 + subdir: F-Droid + submodules: true + gradle: + - yes + + - versionName: 0.95.1 + versionCode: 95150 + commit: v0.95.1 + subdir: F-Droid + submodules: true + gradle: + - yes + + - versionName: 0.96-alpha1 + versionCode: 96001 + commit: v0.96-alpha1 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.96-alpha2 + versionCode: 96002 + commit: v0.96-alpha2 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.96-alpha3 + versionCode: 96003 + commit: v0.96-alpha3 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.96-alpha4 + versionCode: 96004 + commit: v0.96-alpha4 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.96-alpha5 + versionCode: 96005 + commit: v0.96-alpha5 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.96-alpha6 + versionCode: 96006 + commit: v0.96-alpha6 + subdir: F-Droid + gradle: + - yes + + - versionName: '0.96' + versionCode: 96050 + commit: v0.96 + subdir: F-Droid + gradle: + - yes + scanignore: + - extern/AndroidPinning/res/raw/cacerts + + - versionName: 0.96.1 + versionCode: 96150 + commit: v0.96.1 + subdir: F-Droid + gradle: + - yes + scanignore: + - extern/AndroidPinning/res/raw/cacerts + + - versionName: 0.97-alpha1 + versionCode: 97001 + commit: v0.97-alpha1 + subdir: F-Droid + gradle: + - yes + scanignore: + - extern/AndroidPinning/res/raw/cacerts + + - versionName: 0.97-alpha2 + versionCode: 97002 + commit: v0.97-alpha2 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.97-alpha3 + versionCode: 97003 + commit: v0.97-alpha3 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.97-alpha4 + versionCode: 97004 + commit: v0.97-alpha4 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.97-alpha5 + versionCode: 97005 + commit: v0.97-alpha5 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.97-alpha6 + versionCode: 97006 + commit: v0.97-alpha6 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.97-alpha7 + versionCode: 97007 + commit: v0.97-alpha7 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.97-alpha8 + versionCode: 97008 + commit: v0.97-alpha8 + subdir: F-Droid + gradle: + - yes + + - versionName: '0.97' + versionCode: 97050 + commit: v0.97 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.98-alpha1 + versionCode: 98001 + commit: v0.98-alpha1 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.98-alpha2 + versionCode: 98002 + commit: v0.98-alpha2 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.98-alpha3 + versionCode: 98003 + commit: v0.98-alpha3 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.98-alpha4 + versionCode: 98004 + commit: v0.98-alpha4 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.98-alpha5 + versionCode: 98005 + commit: v0.98-alpha5 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.98-alpha6 + versionCode: 98006 + commit: v0.98-alpha6 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.98-alpha7 + versionCode: 98007 + commit: v0.98-alpha7 + subdir: F-Droid + gradle: + - yes + + - versionName: '0.98' + versionCode: 98050 + commit: v0.98 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.98.1 + versionCode: 98150 + commit: v0.98.1 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.99-alpha1 + versionCode: 99001 + commit: v0.99-alpha1 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.99-alpha2 + versionCode: 99002 + commit: v0.99-alpha2 + subdir: F-Droid + gradle: + - yes + + - versionName: '0.99' + versionCode: 99050 + commit: v0.99 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.99.1 + versionCode: 99150 + commit: v0.99.1 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.99.2 + versionCode: 99250 + commit: v0.99.2 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.100-alpha1 + versionCode: 100001 + commit: v0.100-alpha1 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.100-alpha2 + versionCode: 100002 + commit: v0.100-alpha2 + subdir: F-Droid + gradle: + - yes + + - versionName: 0.100-alpha3 + versionCode: 100003 + commit: v0.100-alpha3 + subdir: app + gradle: + - yes + + - versionName: 0.100-alpha4 + versionCode: 100004 + commit: v0.100-alpha4 + subdir: app + gradle: + - yes + + - versionName: 0.100-alpha5 + versionCode: 100005 + commit: v0.100-alpha5 + subdir: app + gradle: + - yes + + - versionName: 0.100-alpha6 + versionCode: 100006 + commit: v0.100-alpha6 + subdir: app + gradle: + - yes + + - versionName: 0.100-alpha7 + versionCode: 100007 + commit: v0.100-alpha7 + subdir: app + gradle: + - yes + + - versionName: 0.100-alpha8 + versionCode: 100008 + commit: v0.100-alpha8 + subdir: app + gradle: + - yes + + - versionName: '0.100' + versionCode: 100050 + commit: v0.100 + subdir: app + gradle: + - yes + + - versionName: 0.100.1 + versionCode: 100150 + commit: v0.100.1 + subdir: app + gradle: + - yes + + - versionName: 0.101-alpha1 + versionCode: 101001 + commit: v0.101-alpha1 + subdir: app + gradle: + - yes + + - versionName: 0.101-alpha2 + versionCode: 101002 + commit: v0.101-alpha2 + subdir: app + gradle: + - yes + + - versionName: 0.101-alpha3 + versionCode: 101003 + commit: v0.101-alpha3 + subdir: app + gradle: + - yes + + - versionName: 0.101-alpha4 + versionCode: 101004 + commit: v0.101-alpha4 + subdir: app + gradle: + - yes + + - versionName: 0.101-alpha5 + versionCode: 101005 + commit: v0.101-alpha5 + subdir: app + gradle: + - yes + + - versionName: 0.101-alpha6 + versionCode: 101006 + commit: v0.101-alpha6 + subdir: app + gradle: + - yes + + - versionName: '0.101' + versionCode: 101050 + commit: v0.101 + subdir: app + gradle: + - yes + + - versionName: 0.102-alpha1 + versionCode: 102001 + commit: v0.102-alpha1 + subdir: app + gradle: + - yes + + - versionName: 0.102-alpha2 + versionCode: 102002 + commit: v0.102-alpha2 + subdir: app + gradle: + - yes + + - versionName: 0.102-alpha3 + versionCode: 102003 + commit: v0.102-alpha3 + subdir: app + gradle: + - yes + + - versionName: '0.102' + versionCode: 102050 + commit: v0.102 + subdir: app + gradle: + - yes + + - versionName: 0.102.1 + versionCode: 102150 + commit: v0.102.1 + subdir: app + gradle: + - yes + + - versionName: 0.102.2 + versionCode: 102250 + commit: v0.102.2 + subdir: app + gradle: + - yes + + - versionName: 0.102.3 + versionCode: 102350 + commit: v0.102.3 + subdir: app + gradle: + - yes + + - versionName: 0.103-alpha1 + versionCode: 103001 + commit: v0.103-alpha1 + subdir: app + gradle: + - yes + + - versionName: 0.103-alpha2 + versionCode: 103002 + commit: v0.103-alpha2 + subdir: app + gradle: + - yes + + - versionName: 0.103-alpha3 + versionCode: 103003 + commit: v0.103-alpha3 + subdir: app + gradle: + - yes + +ArchivePolicy: 12 versions +AutoUpdateMode: None +UpdateCheckMode: Static +CurrentVersion: 0.102.3 +CurrentVersionCode: 102350 diff --git a/tests/metadata/org.smssecure.smssecure.txt b/tests/metadata/org.smssecure.smssecure.txt deleted file mode 100644 index bf41a061..00000000 --- a/tests/metadata/org.smssecure.smssecure.txt +++ /dev/null @@ -1,126 +0,0 @@ -Categories:Phone & SMS -License:GPL-3.0-only -Web Site:http://www.smssecure.org -Source Code:https://github.com/SMSSecure/SMSSecure -Issue Tracker:https://github.com/SMSSecure/SMSSecure/issues -Translation:https://www.transifex.com/silence/silence - -Auto Name:SMSSecure -Summary:Send encrypted text messages (SMS) -Description: -SMSSecure is an SMS/MMS application that allows you to protect your privacy while communicating with friends. -Using SMSSecure, you can send SMS messages and share media or attachments with complete privacy. - -* Easy. SMSSecure works like any other SMS application. There's nothing to sign up for and no new service your friends need to join. -* Reliable. SMSSecure communicates using encrypted SMS messages. No servers or internet connection required. -* Private. SMSSecure uses the TextSecure encryption protocol to provide privacy for every message, every time. -* Safe. All messages are encrypted locally, so if your phone is lost or stolen, your messages are protected. -* Open Source. SMSSecure is Free and Open Source, enabling anyone to verify its security by auditing the code. -. - -Repo Type:git -Repo:https://github.com/SMSSecure/SMSSecure - -Build:0.3.3,5 - disable=builds, merge changes into upstream - commit=66367479a4f57f347b5cbe8f6f8f632adaae7727 - gradle=yes - srclibs=GradleWitness@10f1269c0aafdc1d478efc005ed48f3a47d44278,PreferenceFragment@717a45433b927d2f0dfc5328f79e77c9682c37bc,ShortcutBadger@3815ce2ec0c66acd7d7c0b4f2479df8fa70fed87,AospMms@android-5.1.0_r3 - forcevercode=yes - rm=libs/* - prebuild=touch signing.properties && \ - pushd $$GradleWitness$$ && \ - gradle jar && \ - popd && \ - cp $$GradleWitness$$/build/libs/GradleWitness.jar libs/gradle-witness.jar && \ - sed -i -e '20,22d' build.gradle && \ - pushd $$PreferenceFragment$$ && \ - gradle uploadArchives && \ - popd && \ - sed -i -e '/5470f5872514a6226fa1fc6f4e000991f38805691c534cf0bd2778911fc773ad/d' build.gradle && \ - mkdir smil && \ - pushd smil && \ - wget -c http://www.w3.org/TR/smil-boston-dom/java-binding.zip && \ - unzip java-binding.zip && \ - popd && \ - cp -fR smil/java/org src/ && \ - rm -fR smil && \ - sed -i -e '/org.w3c.smil/d' build.gradle && \ - cp -fR $$AospMms$$/src/org src/ - -Build:0.3.3,6 - disable=builds, wait for upstream - commit=9675ce5eecb929dcaddb43b3d9486fdb88b9ae1a - submodules=yes - gradle=yes - srclibs=GradleWitness@10f1269c0aafdc1d478efc005ed48f3a47d44278 - rm=libs/*.jar - prebuild=touch signing.properties && \ - pushd $$GradleWitness$$ && \ - gradle jar && \ - popd && \ - cp $$GradleWitness$$/build/libs/GradleWitness.jar libs/gradle-witness.jar - -Build:0.4.2,9 - disable=builds locally, but not on BS - commit=v0.4.2 - submodules=yes - gradle=yes - rm=libs/*.jar - prebuild=touch signing.properties && \ - ./build-witness.sh && \ - rm -rf libs/gradle-witness/build && \ - echo "org.gradle.jvmargs=-Xms512m -Xmx512m -XX:MaxPermSize=512m" >> gradle.properties - -Build:0.5.1,11 - commit=v0.5.1 - submodules=yes - gradle=yes - rm=libs/*.jar - prebuild=touch signing.properties && \ - ./build-witness.sh && \ - rm -rf libs/gradle-witness/build && \ - echo "org.gradle.jvmargs=-Xms512m -Xmx512m -XX:MaxPermSize=512m" >> gradle.properties - -Build:0.5.2,12 - disable=broken in upstream - commit=v0.5.2 - submodules=yes - gradle=yes - rm=libs/*.jar - prebuild=touch signing.properties && \ - ./scripts/build-witness.sh && \ - rm -rf libs/gradle-witness/build - -Build:0.5.3,100 - commit=v0.5.3 - submodules=yes - gradle=yes - rm=libs/*.jar - prebuild=touch signing.properties && \ - ./scripts/build-witness.sh && \ - rm -rf libs/gradle-witness/build - -Build:0.5.4,101 - commit=v0.5.4 - submodules=yes - gradle=yes - rm=libs/*.jar - prebuild=touch signing.properties && \ - ./scripts/build-witness.sh && \ - rm -rf libs/gradle-witness/build - -Build:0.6.0,102 - commit=v0.6.0 - submodules=yes - gradle=yes - rm=libs/*.jar - prebuild=touch signing.properties && \ - ./scripts/build-witness.sh && \ - rm -rf libs/gradle-witness/build - -Auto Update Mode:Version v%v -Update Check Mode:Tags -Current Version:0.6.0 -Current Version Code:102 - diff --git a/tests/metadata/org.smssecure.smssecure.yml b/tests/metadata/org.smssecure.smssecure.yml new file mode 100644 index 00000000..992deefe --- /dev/null +++ b/tests/metadata/org.smssecure.smssecure.yml @@ -0,0 +1,164 @@ +Categories: + - Phone & SMS +License: GPL-3.0-only +WebSite: http://www.smssecure.org +SourceCode: https://github.com/SMSSecure/SMSSecure +IssueTracker: https://github.com/SMSSecure/SMSSecure/issues +Translation: https://www.transifex.com/silence/silence + +AutoName: SMSSecure +Summary: Send encrypted text messages (SMS) +Description: |- + SMSSecure is an SMS/MMS application that allows you to protect your privacy while communicating with friends. + Using SMSSecure, you can send SMS messages and share media or attachments with complete privacy. + + * Easy. SMSSecure works like any other SMS application. There's nothing to sign up for and no new service your friends need to join. + * Reliable. SMSSecure communicates using encrypted SMS messages. No servers or internet connection required. + * Private. SMSSecure uses the TextSecure encryption protocol to provide privacy for every message, every time. + * Safe. All messages are encrypted locally, so if your phone is lost or stolen, your messages are protected. + * Open Source. SMSSecure is Free and Open Source, enabling anyone to verify its security by auditing the code. + +RepoType: git +Repo: https://github.com/SMSSecure/SMSSecure + +Builds: + - versionName: 0.3.3 + versionCode: 5 + disable: builds, merge changes into upstream + commit: 66367479a4f57f347b5cbe8f6f8f632adaae7727 + gradle: + - yes + srclibs: + - GradleWitness@10f1269c0aafdc1d478efc005ed48f3a47d44278 + - PreferenceFragment@717a45433b927d2f0dfc5328f79e77c9682c37bc + - ShortcutBadger@3815ce2ec0c66acd7d7c0b4f2479df8fa70fed87 + - AospMms@android-5.1.0_r3 + forcevercode: true + rm: + - libs/* + prebuild: + - touch signing.properties + - pushd $$GradleWitness$$ + - gradle jar + - popd + - cp $$GradleWitness$$/build/libs/GradleWitness.jar libs/gradle-witness.jar + - sed -i -e '20,22d' build.gradle + - pushd $$PreferenceFragment$$ + - gradle uploadArchives + - popd + - sed -i -e '/5470f5872514a6226fa1fc6f4e000991f38805691c534cf0bd2778911fc773ad/d' + build.gradle + - mkdir smil + - pushd smil + - wget -c http://www.w3.org/TR/smil-boston-dom/java-binding.zip + - unzip java-binding.zip + - popd + - cp -fR smil/java/org src/ + - rm -fR smil + - sed -i -e '/org.w3c.smil/d' build.gradle + - cp -fR $$AospMms$$/src/org src/ + + - versionName: 0.3.3 + versionCode: 6 + disable: builds, wait for upstream + commit: 9675ce5eecb929dcaddb43b3d9486fdb88b9ae1a + submodules: true + gradle: + - yes + srclibs: + - GradleWitness@10f1269c0aafdc1d478efc005ed48f3a47d44278 + rm: + - libs/*.jar + prebuild: + - touch signing.properties + - pushd $$GradleWitness$$ + - gradle jar + - popd + - cp $$GradleWitness$$/build/libs/GradleWitness.jar libs/gradle-witness.jar + + - versionName: 0.4.2 + versionCode: 9 + disable: builds locally, but not on BS + commit: v0.4.2 + submodules: true + gradle: + - yes + rm: + - libs/*.jar + prebuild: + - touch signing.properties + - ./build-witness.sh + - rm -rf libs/gradle-witness/build + - echo "org.gradle.jvmargs=-Xms512m -Xmx512m -XX:MaxPermSize=512m" >> gradle.properties + + - versionName: 0.5.1 + versionCode: 11 + commit: v0.5.1 + submodules: true + gradle: + - yes + rm: + - libs/*.jar + prebuild: + - touch signing.properties + - ./build-witness.sh + - rm -rf libs/gradle-witness/build + - echo "org.gradle.jvmargs=-Xms512m -Xmx512m -XX:MaxPermSize=512m" >> gradle.properties + + - versionName: 0.5.2 + versionCode: 12 + disable: broken in upstream + commit: v0.5.2 + submodules: true + gradle: + - yes + rm: + - libs/*.jar + prebuild: + - touch signing.properties + - ./scripts/build-witness.sh + - rm -rf libs/gradle-witness/build + + - versionName: 0.5.3 + versionCode: 100 + commit: v0.5.3 + submodules: true + gradle: + - yes + rm: + - libs/*.jar + prebuild: + - touch signing.properties + - ./scripts/build-witness.sh + - rm -rf libs/gradle-witness/build + + - versionName: 0.5.4 + versionCode: 101 + commit: v0.5.4 + submodules: true + gradle: + - yes + rm: + - libs/*.jar + prebuild: + - touch signing.properties + - ./scripts/build-witness.sh + - rm -rf libs/gradle-witness/build + + - versionName: 0.6.0 + versionCode: 102 + commit: v0.6.0 + submodules: true + gradle: + - yes + rm: + - libs/*.jar + prebuild: + - touch signing.properties + - ./scripts/build-witness.sh + - rm -rf libs/gradle-witness/build + +AutoUpdateMode: Version v%v +UpdateCheckMode: Tags +CurrentVersion: 0.6.0 +CurrentVersionCode: 102 diff --git a/tests/metadata/raw.template.txt b/tests/metadata/raw.template.txt deleted file mode 100644 index ec2fe286..00000000 --- a/tests/metadata/raw.template.txt +++ /dev/null @@ -1,9 +0,0 @@ -License:Unknown -Web Site: -Source Code: -Issue Tracker: -Changelog: -Summary:Template -Description: -Template -. diff --git a/tests/metadata/raw.template.yml b/tests/metadata/raw.template.yml new file mode 100644 index 00000000..bd0ae1a5 --- /dev/null +++ b/tests/metadata/raw.template.yml @@ -0,0 +1,7 @@ +License: Unknown + +Summary: Template +Description: Template + +AutoUpdateMode: None +UpdateCheckMode: None diff --git a/tests/metadata/souch.smsbypass.txt b/tests/metadata/souch.smsbypass.txt deleted file mode 100644 index d73822f0..00000000 --- a/tests/metadata/souch.smsbypass.txt +++ /dev/null @@ -1,52 +0,0 @@ -Categories:Phone & SMS -License:GPL-3.0-only -Web Site:https://gitlab.com/souch/SMSbypass -Source Code:https://gitlab.com/souch/SMSbypass/tree/HEAD -Issue Tracker:https://gitlab.com/souch/SMSbypass/issues -Donate:http://rodolphe.souchaud.free.fr/donate -FlattrID:cad90e036b975ed129a3ce80a0750466 - -Auto Name:Battery level -Summary:Filter SMS and show them in a fake app -Description: -In order to keep away curious eyes, SMS-bypass filters incoming SMS messages -before they reach your inbox. Based on bughunter2.smsfilter. - -Features: - -* Discrete fake app "Battery level": Long tap on Battery percentage will show SMS. -* Filter incoming SMS specified address: redirect the SMS to SMS-bypass messages list; remove SMS arrival sound or vibration; show a discreet notification icon (battery level); vibrate if checked in settings -* Add contact from contact list -* Export messages to a text file -. - -Repo Type:git -Repo:https://gitlab.com/souch/SMSbypass.git - -Build:0.8,5 - commit=v0.8 - subdir=app - gradle=yes - prebuild=sed -i -e '/minSdkVersion/amaxSdkVersion 19\n' build.gradle - -Build:0.8b,6 - disable=don't build, just use as template for AUM, correct VC is 8 - commit=2bd6164ff6391906af2af2b484de69a4ff926a01 - subdir=app - gradle=yes - -Build:0.8.1,8 - disable=mistagged - commit=v0.8.1 - subdir=app - gradle=yes - -Build:0.9,9 - commit=v0.9 - subdir=app - gradle=yes - -Auto Update Mode:Version v%v -Update Check Mode:Tags -Current Version:0.9 -Current Version Code:9 diff --git a/tests/metadata/souch.smsbypass.yml b/tests/metadata/souch.smsbypass.yml new file mode 100644 index 00000000..5733673a --- /dev/null +++ b/tests/metadata/souch.smsbypass.yml @@ -0,0 +1,61 @@ +Categories: + - Phone & SMS +License: GPL-3.0-only +WebSite: https://gitlab.com/souch/SMSbypass +SourceCode: https://gitlab.com/souch/SMSbypass/tree/HEAD +IssueTracker: https://gitlab.com/souch/SMSbypass/issues +Donate: http://rodolphe.souchaud.free.fr/donate +FlattrID: cad90e036b975ed129a3ce80a0750466 + +AutoName: Battery level +Summary: Filter SMS and show them in a fake app +Description: |- + In order to keep away curious eyes, SMS-bypass filters incoming SMS messages + before they reach your inbox. Based on bughunter2.smsfilter. + + Features: + + * Discrete fake app "Battery level": Long tap on Battery percentage will show SMS. + * Filter incoming SMS specified address: redirect the SMS to SMS-bypass messages list; remove SMS arrival sound or vibration; show a discreet notification icon (battery level); vibrate if checked in settings + * Add contact from contact list + * Export messages to a text file + +RepoType: git +Repo: https://gitlab.com/souch/SMSbypass.git + +Builds: + - versionName: '0.8' + versionCode: 5 + commit: v0.8 + subdir: app + gradle: + - yes + prebuild: sed -i -e '/minSdkVersion/amaxSdkVersion 19\n' build.gradle + + - versionName: 0.8b + versionCode: 6 + disable: don't build, just use as template for AUM, correct VC is 8 + commit: 2bd6164ff6391906af2af2b484de69a4ff926a01 + subdir: app + gradle: + - yes + + - versionName: 0.8.1 + versionCode: 8 + disable: mistagged + commit: v0.8.1 + subdir: app + gradle: + - yes + + - versionName: '0.9' + versionCode: 9 + commit: v0.9 + subdir: app + gradle: + - yes + +AutoUpdateMode: Version v%v +UpdateCheckMode: Tags +CurrentVersion: '0.9' +CurrentVersionCode: 9 diff --git a/tests/publish.TestCase b/tests/publish.TestCase index ac00d6d9..88cdc48a 100755 --- a/tests/publish.TestCase +++ b/tests/publish.TestCase @@ -149,9 +149,9 @@ class PublishTest(unittest.TestCase): os.mkdir(os.path.join(testdir, 'repo')) metadata_dir = os.path.join(testdir, 'metadata') os.mkdir(metadata_dir) - shutil.copy(os.path.join('metadata', 'com.politedroid.txt'), metadata_dir) - with open(os.path.join(metadata_dir, 'com.politedroid.txt'), 'a') as fp: - fp.write('\nBinaries:https://placeholder/foo%v.apk\n') + shutil.copy(os.path.join('metadata', 'com.politedroid.yml'), metadata_dir) + with open(os.path.join(metadata_dir, 'com.politedroid.yml'), 'a') as fp: + fp.write('\nBinaries: https://placeholder/foo%v.apk\n') os.mkdir(os.path.join(testdir, 'unsigned')) shutil.copy('repo/com.politedroid_6.apk', os.path.join(testdir, 'unsigned')) os.mkdir(os.path.join(testdir, 'unsigned', 'binaries')) diff --git a/tests/run-tests b/tests/run-tests index d769686e..b6a43c0d 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -327,7 +327,7 @@ if ! which apksigner; then fdroid_init_with_prebuilt_keystore echo "accepted_formats = ['txt']" >> config.py test -d metadata || mkdir metadata - cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ + cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ test -d repo || mkdir repo cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py @@ -413,7 +413,7 @@ cd $REPOROOT fdroid_init_with_prebuilt_keystore echo "accepted_formats = ['txt']" >> config.py test -d metadata || mkdir metadata -cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ +cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ $sed -i.tmp '/Archive Policy:/d' metadata/com.politedroid.txt test -d repo || mkdir repo cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ @@ -496,7 +496,7 @@ echo "accepted_formats = ['txt']" >> config.py echo 'allow_disabled_algorithms = True' >> config.py $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py test -d metadata || mkdir metadata -cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ +cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ echo 'Summary:good test version of urzip' > metadata/info.guardianproject.urzip.txt echo 'Summary:good MD5 sig, disabled algorithm' > metadata/org.bitbucket.tickytacky.mirrormirror.txt $sed -i.tmp '/Archive Policy:/d' metadata/*.txt @@ -632,7 +632,7 @@ fi set -e mkdir $REPOROOT/metadata/ -cp $WORKSPACE/tests/metadata/org.smssecure.smssecure.txt $REPOROOT/metadata/ +cp $WORKSPACE/tests/metadata/org.smssecure.smssecure.yml $REPOROOT/metadata/ $fdroid readmeta # now make a fake duplicate @@ -872,7 +872,7 @@ REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore mkdir $REPOROOT/metadata -cp -a $WORKSPACE/tests/metadata/obb.mainpatch.current.txt $REPOROOT/metadata +cp -a $WORKSPACE/tests/metadata/obb.mainpatch.current.yml $REPOROOT/metadata echo "accepted_formats = ['txt']" >> config.py cp $WORKSPACE/tests/repo/obb.mainpatch.current_1619.apk $REPOROOT/repo/ cp $WORKSPACE/tests/repo/obb.mainpatch.current_1619_another-release-key.apk $REPOROOT/repo/ @@ -1218,7 +1218,7 @@ fdroid_init_with_prebuilt_keystore echo "accepted_formats = ['txt']" >> config.py echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py test -d metadata || mkdir metadata -cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata/ +cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ test -d repo || mkdir repo test -d unsigned || mkdir unsigned cp $WORKSPACE/tests/repo/com.politedroid_6.apk unsigned/ diff --git a/tests/valid-package-names/RandomPackageNames.java b/tests/valid-package-names/RandomPackageNames.java index 82d77bbe..80257fd8 100644 --- a/tests/valid-package-names/RandomPackageNames.java +++ b/tests/valid-package-names/RandomPackageNames.java @@ -115,7 +115,7 @@ public class RandomPackageNames { for (File f : new File("/home/hans/code/fdroid/fdroiddata/metadata").listFiles()) { String name = f.getName(); - if (name.endsWith(".yml") || name.endsWith(".txt")) { + if (name.endsWith(".yml")) { compare(name.substring(0, name.length() - 4)); } } From 1b90aec697b3a163bbab92a83ace7d948a0c4292 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 25 May 2020 21:47:49 +0200 Subject: [PATCH 0338/2775] purge .txt and .json from bash-completion YAML is the way! --- completion/bash-completion | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index b79b143f..7e2a15da 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -26,16 +26,15 @@ __fdroid_init() { (( $# >= 1 )) && __complete_${1} } -__by_ext() { - local ext="$1" - files=( metadata/*.$ext ) +__get_appid() { + files=( metadata/*.yml ) files=( ${files[@]#metadata/} ) - files=${files[@]%.$ext} + files=${files[@]%.yml} echo "$files" } __package() { - files="$(__by_ext txt) $(__by_ext yml) $(__by_ext json)" + files="$(__get_appid)" COMPREPLY=( $( compgen -W "$files" -- $cur ) ) } From 37f37ebd88e79ebe93239b72ed5503d5bde13f4b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 9 Jun 2020 22:19:06 +0200 Subject: [PATCH 0339/2775] use default accepted_formats since all the files are .yml anyway --- .gitlab-ci.yml | 7 +++---- tests/androguard_test.py | 1 - tests/config.py | 1 - tests/dump_internal_metadata_format.py | 7 ++++++- tests/lint.TestCase | 5 ----- tests/metadata.TestCase | 12 +++--------- tests/run-tests | 11 ----------- tests/update.TestCase | 13 ------------- 8 files changed, 12 insertions(+), 45 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a7d00a05..277c6162 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,7 @@ test: - cd tests - ./complete-ci-tests -# Test that the parsing of the .txt format didn't change from last +# Test that the parsing of the .yml metadata format didn't change from last # released version. This uses the commit ID of the release tags, # rather than the release tag itself so that contributor forks do not # need to include the tags in them for this test to work. @@ -22,19 +22,18 @@ metadata_v0: variables: RELEASE_COMMIT_ID: 4655e2e24ebd043be6faa4adf552db391caf2be9 # 1.1a~ script: - - git fetch https://gitlab.com/fdroid/fdroidserver $RELEASE_COMMIT_ID + - git fetch https://gitlab.com/fdroid/fdroidserver.git $RELEASE_COMMIT_ID - cd tests - export GITCOMMIT=`git describe` - git checkout $RELEASE_COMMIT_ID - cd .. - - git clone --depth 1 https://gitlab.com/fdroid/fdroiddata + - git clone --depth 1 https://gitlab.com/fdroid/fdroiddata.git - cd fdroiddata - ../tests/dump_internal_metadata_format.py - cd .. - git reset --hard - git checkout $GITCOMMIT - cd fdroiddata - - echo "accepted_formats = ('txt', 'yml')" >> config.py - ../tests/dump_internal_metadata_format.py - sed -i -e '/kivy:\sfalse/d' diff --git a/tests/androguard_test.py b/tests/androguard_test.py index c708b85f..162dffb3 100644 --- a/tests/androguard_test.py +++ b/tests/androguard_test.py @@ -41,7 +41,6 @@ class UpdateTest(unittest.TestCase): raise Exception('This test must be run in the "tests/" subdir') config['ndk_paths'] = dict() - config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config fdroidserver.update.config = config diff --git a/tests/config.py b/tests/config.py index 745fb9d6..ead06f91 100644 --- a/tests/config.py +++ b/tests/config.py @@ -31,7 +31,6 @@ mirrors = ( ) update_stats = True -accepted_formats = ('json', 'txt', 'yml') install_list = 'org.adaway' uninstall_list = ('com.android.vending', 'com.facebook.orca', ) diff --git a/tests/dump_internal_metadata_format.py b/tests/dump_internal_metadata_format.py index 6b657b06..50a4cd20 100755 --- a/tests/dump_internal_metadata_format.py +++ b/tests/dump_internal_metadata_format.py @@ -1,5 +1,10 @@ #!/usr/bin/env python3 # +# Test that the parsing of the .yml metadata format didn't change from last +# released version. This uses the commit ID of the release tags, +# rather than the release tag itself so that contributor forks do not +# need to include the tags in them for this test to work. +# # This is for running manual tests when changing the metadata format. # The idea is to test changes using all of the files in # fdroiddata.git. To run it, do: @@ -71,7 +76,7 @@ if not os.path.isdir('metadata'): config = dict() config['sdk_path'] = os.getenv('ANDROID_HOME') or '/opt/android-sdk' config['ndk_paths'] = dict() -config['accepted_formats'] = ['txt'] +config['accepted_formats'] = ['yml'] fdroidserver.common.config = config repo = git.Repo(localmodule) diff --git a/tests/lint.TestCase b/tests/lint.TestCase index 783b6f1f..09aca89f 100755 --- a/tests/lint.TestCase +++ b/tests/lint.TestCase @@ -34,11 +34,6 @@ class LintTest(unittest.TestCase): os.chdir(self.basedir) def test_check_for_unsupported_metadata_files(self): - config = dict() - fdroidserver.common.fill_config_defaults(config) - config['accepted_formats'] = ('txt', 'yml') - fdroidserver.common.config = config - fdroidserver.lint.config = config self.assertTrue(fdroidserver.lint.check_for_unsupported_metadata_files()) tmptestsdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index ab636a35..3799e48c 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -108,12 +108,8 @@ class MetadataTest(unittest.TestCase): self.maxDiff = None - # these need to be set to prevent code running on None, only - # 'accepted_formats' is actually used in metadata.py config = dict() - config['sdk_path'] = '/opt/android-sdk' - config['ndk_paths'] = dict() - config['accepted_formats'] = ['json', 'txt', 'yml'] + fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config fdroidserver.metadata.warnings_action = None @@ -134,7 +130,7 @@ class MetadataTest(unittest.TestCase): def test_rewrite_yaml_fakeotaupdate(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) - fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']} + fdroidserver.common.config = {'accepted_formats': ['yml']} fdroidserver.metadata.warnings_action = None # rewrite metadata @@ -151,7 +147,7 @@ class MetadataTest(unittest.TestCase): def test_rewrite_yaml_fdroidclient(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) - fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']} + fdroidserver.common.config = {'accepted_formats': ['yml']} # rewrite metadata allapps = fdroidserver.metadata.read_metadata(xref=True) @@ -167,7 +163,6 @@ class MetadataTest(unittest.TestCase): def test_rewrite_yaml_special_build_params(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) - fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']} # rewrite metadata allapps = fdroidserver.metadata.read_metadata(xref=True) @@ -229,7 +224,6 @@ class MetadataTest(unittest.TestCase): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) metadatadir = os.path.join(testdir, 'metadata') os.makedirs(metadatadir) - fdroidserver.common.config = {'accepted_formats': ['txt']} randomlist = [] randomapps = glob.glob(os.path.join(self.basedir, 'metadata', '*.yml')) diff --git a/tests/run-tests b/tests/run-tests index b6a43c0d..f3533bd3 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -167,7 +167,6 @@ if which zipalign || ls -1 $ANDROID_HOME/build-tools/*/zipalign; then $fdroid init --keystore keystore.jks --repo-keyalias=sova echo 'keystorepass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py echo 'keypass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py - echo "accepted_formats = ['txt', 'yml']" >> config.py echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py test -d archive || mkdir archive test -d metadata || mkdir metadata @@ -252,7 +251,6 @@ fdroid_init_with_prebuilt_keystore cp -a $WORKSPACE/tests/metadata $WORKSPACE/tests/repo $WORKSPACE/tests/stats $REPOROOT/ cp -a $WORKSPACE/tests/gnupghome $GNUPGHOME chmod 0700 $GNUPGHOME -echo "accepted_formats = ['json', 'txt', 'yml']" >> config.py echo "install_list = 'org.adaway'" >> config.py echo "uninstall_list = ('com.android.vending', 'com.facebook.orca',)" >> config.py echo "gpghome = '$GNUPGHOME'" >> config.py @@ -293,7 +291,6 @@ echo_header 'test moving lots of APKs to the archive' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo "accepted_formats = ['txt']" >> config.py $sed -i.tmp '/allow_disabled_algorithms/d' config.py test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/*.txt metadata/ @@ -325,7 +322,6 @@ if ! which apksigner; then REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore - echo "accepted_formats = ['txt']" >> config.py test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ test -d repo || mkdir repo @@ -411,7 +407,6 @@ echo_header 'test moving old APKs to and from the archive' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo "accepted_formats = ['txt']" >> config.py test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ $sed -i.tmp '/Archive Policy:/d' metadata/com.politedroid.txt @@ -492,7 +487,6 @@ echo_header 'test allowing disabled signatures in repo and archive' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo "accepted_formats = ['txt']" >> config.py echo 'allow_disabled_algorithms = True' >> config.py $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py test -d metadata || mkdir metadata @@ -586,7 +580,6 @@ echo_header 'rename apks with `fdroid update --rename-apks`, --nosign for speed' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo "accepted_formats = ['txt', 'yml']" >> config.py echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/info.guardianproject.urzip.yml metadata/ @@ -873,7 +866,6 @@ cd $REPOROOT fdroid_init_with_prebuilt_keystore mkdir $REPOROOT/metadata cp -a $WORKSPACE/tests/metadata/obb.mainpatch.current.yml $REPOROOT/metadata -echo "accepted_formats = ['txt']" >> config.py cp $WORKSPACE/tests/repo/obb.mainpatch.current_1619.apk $REPOROOT/repo/ cp $WORKSPACE/tests/repo/obb.mainpatch.current_1619_another-release-key.apk $REPOROOT/repo/ $fdroid update --pretty @@ -1029,7 +1021,6 @@ cd $REPOROOT fdroid_init_with_prebuilt_keystore cp -a $WORKSPACE/tests/metadata $WORKSPACE/tests/repo $WORKSPACE/tests/stats $REPOROOT/ echo "binary_transparency_remote = '$GIT_REMOTE'" >> config.py -echo "accepted_formats = ['json', 'txt', 'yml']" >> config.py $fdroid update --verbose if have_git_2_3; then $fdroid server update --verbose @@ -1182,7 +1173,6 @@ if have_git_2_3; then echo "mirrors = ['http://foo.bar/fdroid', 'http://asdflkdsfjafdsdfhkjh.onion/fdroid']" >> config.py echo "servergitmirrors = '$SERVER_GIT_MIRROR'" >> config.py echo "local_copy_dir = '$LOCAL_COPY_DIR'" >> config.py - echo "accepted_formats = ['json', 'txt', 'yml']" >> config.py $fdroid update --pretty grep -F '' repo/index.xml @@ -1215,7 +1205,6 @@ echo_header 'test extracting and publishing with developer signature' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo "accepted_formats = ['txt']" >> config.py echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ diff --git a/tests/update.TestCase b/tests/update.TestCase index e3d9ef53..1465ad57 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -47,7 +47,6 @@ class UpdateTest(unittest.TestCase): def testInsertStoreMetadata(self): config = dict() fdroidserver.common.fill_config_defaults(config) - config['accepted_formats'] = ('txt', 'yml') fdroidserver.update.config = config fdroidserver.update.options = fdroidserver.common.options os.chdir(os.path.join(localmodule, 'tests')) @@ -170,7 +169,6 @@ class UpdateTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) - config['accepted_formats'] = ('yml') fdroidserver.common.config = config fdroidserver.update.config = config fdroidserver.update.options = fdroidserver.common.options @@ -201,11 +199,6 @@ class UpdateTest(unittest.TestCase): shutil.copytree(os.path.join(self.basedir, 'triple-t-2'), tmptestsdir) os.chdir(tmptestsdir) - config = dict() - fdroidserver.common.fill_config_defaults(config) - config['accepted_formats'] = ('yml') - fdroidserver.common.config = config - fdroidserver.update.config = config fdroidserver.update.options = fdroidserver.common.options apps = fdroidserver.metadata.read_metadata(xref=True) @@ -344,7 +337,6 @@ class UpdateTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() - config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config fdroidserver.update.config = config @@ -402,7 +394,6 @@ class UpdateTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() - config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config fdroidserver.update.config = config @@ -592,7 +583,6 @@ class UpdateTest(unittest.TestCase): raise Exception('This test must be run in the "tests/" subdir') config['ndk_paths'] = dict() - config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config fdroidserver.update.config = config @@ -646,7 +636,6 @@ class UpdateTest(unittest.TestCase): fdroidserver.update.config = config config['ndk_paths'] = dict() - config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config fdroidserver.update.config = config @@ -765,7 +754,6 @@ class UpdateTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() - config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config fdroidserver.update.config = config @@ -801,7 +789,6 @@ class UpdateTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() - config['accepted_formats'] = ['json', 'txt', 'yml'] fdroidserver.common.config = config fdroidserver.update.config = config From f0fb3b64f801cdec7a398cec4abbbf38a2930af4 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 9 Jun 2020 22:22:43 +0200 Subject: [PATCH 0340/2775] remove obselete tests --- MANIFEST.in | 1 - tests/extra/convert_metadata_to_yaml_then_txt.sh | 14 -------------- tests/run-tests | 13 ------------- 3 files changed, 28 deletions(-) delete mode 100755 tests/extra/convert_metadata_to_yaml_then_txt.sh diff --git a/MANIFEST.in b/MANIFEST.in index 4aa37974..ce591656 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -541,7 +541,6 @@ include tests/description-parsing.py include tests/dummy-keystore.jks include tests/dump_internal_metadata_format.py include tests/exception.TestCase -include tests/extra/convert_metadata_to_yaml_then_txt.sh include tests/extra/manual-vmtools-test.py include tests/getsig/getsig.java include tests/getsig/make.sh diff --git a/tests/extra/convert_metadata_to_yaml_then_txt.sh b/tests/extra/convert_metadata_to_yaml_then_txt.sh deleted file mode 100755 index efc03350..00000000 --- a/tests/extra/convert_metadata_to_yaml_then_txt.sh +++ /dev/null @@ -1,14 +0,0 @@ -#! /bin/bash - -if [ ! -d metadata ]; then - echo 'no metadata directory present' - exit 1 -fi - -fdroid rewritemeta --to yml -fdroid rewritemeta --to txt - -echo '## stripping maven, kivy, disable buildflags if they are set to "no"' -sed -i '/^ maven=no$/d' metadata/*.txt -sed -i '/^ kivy=no$/d' metadata/*.txt -sed -i '/^ disable=no$/d' metadata/*.txt diff --git a/tests/run-tests b/tests/run-tests index f3533bd3..6ce7b299 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -628,19 +628,6 @@ mkdir $REPOROOT/metadata/ cp $WORKSPACE/tests/metadata/org.smssecure.smssecure.yml $REPOROOT/metadata/ $fdroid readmeta -# now make a fake duplicate -touch $REPOROOT/metadata/org.smssecure.smssecure.yml - -set +e -$fdroid readmeta -if [ $? -eq 0 ]; then - echo "This should have failed because there is a duplicate metadata file!" - exit 1 -else - echo "testing duplicate metadata checks passed" -fi -set -e - #------------------------------------------------------------------------------# echo_header "ensure commands that don't need the JDK work without a JDK configed" From 0d1fddb82e6d032217e52b8c99c02672b430dbc1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 9 Jun 2020 22:34:23 +0200 Subject: [PATCH 0341/2775] convert inline tests to .yml --- tests/run-tests | 60 +++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/tests/run-tests b/tests/run-tests index 6ce7b299..9c5d85d9 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -226,15 +226,18 @@ REPOROOT=`create_test_dir` cd $REPOROOT cp $WORKSPACE/examples/fdroid-icon.png $REPOROOT/ mkdir metadata -echo "Auto Name:Just A Test" > metadata/org.fdroid.ci.test.app.txt -echo "Web Site:" >> metadata/org.fdroid.ci.test.app.txt -echo "Build:0.3,300" >> metadata/org.fdroid.ci.test.app.txt -echo " commit=0.3" >> metadata/org.fdroid.ci.test.app.txt -echo " subdir=app" >> metadata/org.fdroid.ci.test.app.txt -echo " gradle=yes" >> metadata/org.fdroid.ci.test.app.txt -echo "" >> metadata/org.fdroid.ci.test.app.txt -echo "Repo:https://gitlab.com/fdroid/ci-test-app.git" >> metadata/org.fdroid.ci.test.app.txt -echo "Repo Type:git" >> metadata/org.fdroid.ci.test.app.txt +echo "AutoName: Just A Test" > metadata/org.fdroid.ci.test.app.yml +echo "WebSite: " >> metadata/org.fdroid.ci.test.app.yml +echo "Builds:" >> metadata/org.fdroid.ci.test.app.yml +echo " - versionName: 0.3" >> metadata/org.fdroid.ci.test.app.yml +echo " versionCode: 300" >> metadata/org.fdroid.ci.test.app.yml +echo " commit: 0.3" >> metadata/org.fdroid.ci.test.app.yml +echo " subdir: app" >> metadata/org.fdroid.ci.test.app.yml +echo " gradle:" >> metadata/org.fdroid.ci.test.app.yml +echo " - yes" >> metadata/org.fdroid.ci.test.app.yml +echo "" >> metadata/org.fdroid.ci.test.app.yml +echo "Repo: https://gitlab.com/fdroid/ci-test-app.git" >> metadata/org.fdroid.ci.test.app.yml +echo "RepoType: git" >> metadata/org.fdroid.ci.test.app.yml mkdir build cp -a $WORKSPACE/tests/tmp/importer build/org.fdroid.ci.test.app ls -l build/org.fdroid.ci.test.app @@ -293,10 +296,10 @@ cd $REPOROOT fdroid_init_with_prebuilt_keystore $sed -i.tmp '/allow_disabled_algorithms/d' config.py test -d metadata || mkdir metadata -cp $WORKSPACE/tests/metadata/*.txt metadata/ -echo 'Summary:good test version of urzip' > metadata/info.guardianproject.urzip.txt -echo 'Summary:good MD5 sig, which is disabled algorithm' > metadata/org.bitbucket.tickytacky.mirrormirror.txt -$sed -i.tmp '/Archive Policy:/d' metadata/*.txt +cp $WORKSPACE/tests/metadata/*.yml metadata/ +echo 'Summary: good test version of urzip' > metadata/info.guardianproject.urzip.yml +echo 'Summary: good MD5 sig, which is disabled algorithm' > metadata/org.bitbucket.tickytacky.mirrormirror.yml +$sed -i.tmp '/ArchivePolicy:/d' metadata/*.yml test -d repo || mkdir repo cp $WORKSPACE/tests/urzip.apk \ $WORKSPACE/tests/org.bitbucket.tickytacky.mirrormirror_[0-9].apk \ @@ -341,7 +344,7 @@ if ! which apksigner; then test -e repo/com.politedroid_6.apk echo "enable one app in the repo" - $sed -i.tmp 's,^Archive Policy:4,Archive Policy:1,' metadata/com.politedroid.txt + $sed -i.tmp 's,^ArchivePolicy: 4,ArchivePolicy: 1,' metadata/com.politedroid.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 3 test `grep '' repo/index.xml | wc -l` -eq 1 @@ -355,7 +358,7 @@ if ! which apksigner; then test -e repo/com.politedroid_6.apk echo "remove all apps from the repo" - $sed -i.tmp 's,^Archive Policy:1,Archive Policy:0,' metadata/com.politedroid.txt + $sed -i.tmp 's,^ArchivePolicy: 1,ArchivePolicy: 0,' metadata/com.politedroid.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 4 test `grep '' repo/index.xml | wc -l` -eq 0 @@ -370,7 +373,7 @@ if ! which apksigner; then ! test -e repo/com.politedroid_6.apk echo "move back one from archive to the repo" - $sed -i.tmp 's,^Archive Policy:0,Archive Policy:1,' metadata/com.politedroid.txt + $sed -i.tmp 's,^ArchivePolicy: 0,ArchivePolicy: 1,' metadata/com.politedroid.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 3 test `grep '' repo/index.xml | wc -l` -eq 1 @@ -385,7 +388,7 @@ if ! which apksigner; then test -e repo/com.politedroid_6.apk echo "set an earlier version as CVC and test that it's the only one not archived" - $sed -i.tmp 's,^Current Version Code:6,Current Version Code:5,' metadata/com.politedroid.txt + $sed -i.tmp 's,^CurrentVersionCode: 6,CurrentVersionCode: 5,' metadata/com.politedroid.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 3 test `grep '' repo/index.xml | wc -l` -eq 1 @@ -409,7 +412,7 @@ cd $REPOROOT fdroid_init_with_prebuilt_keystore test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ -$sed -i.tmp '/Archive Policy:/d' metadata/com.politedroid.txt +$sed -i.tmp '/ArchivePolicy:/d' metadata/com.politedroid.yml test -d repo || mkdir repo cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py @@ -440,7 +443,7 @@ test -e archive/com.politedroid_5.apk test -e repo/com.politedroid_6.apk # disabling deletes from the archive -$sed -i.tmp 's/Build:1.3,4/Build:1.3,4\n disable=testing deletion/' metadata/com.politedroid.txt +$sed -i.tmp 's/\(versionCode: 4\)/\1\n disable: testing deletion/' metadata/com.politedroid.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 2 test `grep '' repo/index.xml | wc -l` -eq 1 @@ -454,7 +457,7 @@ test -e archive/com.politedroid_5.apk test -e repo/com.politedroid_6.apk # disabling deletes from the repo, and promotes one from the archive -$sed -i.tmp 's/Build:1.5,6/Build:1.5,6\n disable=testing deletion/' metadata/com.politedroid.txt +$sed -i.tmp 's/\(versionCode: 6\)/\1\n disable: testing deletion/' metadata/com.politedroid.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 1 test `grep '' repo/index.xml | wc -l` -eq 1 @@ -491,9 +494,9 @@ echo 'allow_disabled_algorithms = True' >> config.py $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ -echo 'Summary:good test version of urzip' > metadata/info.guardianproject.urzip.txt -echo 'Summary:good MD5 sig, disabled algorithm' > metadata/org.bitbucket.tickytacky.mirrormirror.txt -$sed -i.tmp '/Archive Policy:/d' metadata/*.txt +echo 'Summary: good test version of urzip' > metadata/info.guardianproject.urzip.yml +echo 'Summary: good MD5 sig, disabled algorithm' > metadata/org.bitbucket.tickytacky.mirrormirror.yml +$sed -i.tmp '/ArchivePolicy:/d' metadata/*.yml test -d repo || mkdir repo cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk \ $WORKSPACE/tests/org.bitbucket.tickytacky.mirrormirror_[0-9].apk \ @@ -636,12 +639,11 @@ REPOROOT=`create_test_dir` cd $REPOROOT mkdir repo mkdir metadata -echo "License:GPL-2.0-only" >> metadata/fake.txt -echo "Summary:Yup still fake" >> metadata/fake.txt -echo "Categories:Internet" >> metadata/fake.txt -echo "Description:" >> metadata/fake.txt -echo "this is fake" >> metadata/fake.txt -echo "." >> metadata/fake.txt +echo "License: GPL-2.0-only" >> metadata/fake.yml +echo "Summary: Yup still fake" >> metadata/fake.yml +echo "Categories: [Internet]" >> metadata/fake.yml +echo "Description: |" >> metadata/fake.yml +echo " this is fake" >> metadata/fake.yml # fake that no JDKs are available echo 'java_paths = {}' > config.py From bde65aa54d4eb52eab1f0a8d082435f2f1b301bb Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 10 Jun 2020 10:24:15 +0200 Subject: [PATCH 0342/2775] gitlab-ci: switch metadata_v0 test to commit that supports only .yml 37f37ebd88e79ebe93239b72ed5503d5bde13f4b --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 277c6162..0b5d96cd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,7 +20,7 @@ test: metadata_v0: image: registry.gitlab.com/fdroid/ci-images-server:latest variables: - RELEASE_COMMIT_ID: 4655e2e24ebd043be6faa4adf552db391caf2be9 # 1.1a~ + RELEASE_COMMIT_ID: 37f37ebd88e79ebe93239b72ed5503d5bde13f4b # 2.0a~ script: - git fetch https://gitlab.com/fdroid/fdroidserver.git $RELEASE_COMMIT_ID - cd tests From bf815251ec04a74f24424d2f8b28f9089305668b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 23 Jan 2020 04:13:14 +0100 Subject: [PATCH 0343/2775] rough plugin system implementation --- fdroidserver/__main__.py | 42 ++++++++++++++++++++++++++++++++++------ tests/main.TestCase | 36 ++++++++++++++++++++++++++++++---- tests/testcommon.py | 16 +++++++++++++++ 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index 7ffc6b7e..70b35993 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # # fdroidserver/__main__.py - part of the FDroid server tools +# Copyright (C) 2020 Michael Pöhn # Copyright (C) 2010-2015, Ciaran Gultnieks, ciaran@ciarang.com # Copyright (C) 2013-2014 Daniel Marti # @@ -20,7 +21,9 @@ import sys import os import locale +import pkgutil import logging +import importlib import fdroidserver.common import fdroidserver.metadata @@ -54,25 +57,49 @@ commands = OrderedDict([ ]) -def print_help(): +def print_help(fdroid_modules=None): print(_("usage: ") + _("fdroid [] [-h|--help|--version|]")) print("") print(_("Valid commands are:")) for cmd, summary in commands.items(): print(" " + cmd + ' ' * (15 - len(cmd)) + summary) + if fdroid_modules: + print(_('commands from plugin modules:')) + for command in sorted(fdroid_modules.keys()): + print(' {:15}{}'.format(command, fdroid_modules[command]['summary'])) print("") +def find_plugins(): + fdroid_modules = [x[1] for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] + commands = {} + for module_name in fdroid_modules: + try: + command_name = module_name[7:] + module = importlib.import_module(module_name) + if hasattr(module, 'fdroid_summary') and hasattr(module, 'main'): + commands[command_name] = {'summary': module.fdroid_summary, + 'module': module} + except IOError: + # We need to keep module lookup fault tolerant because buggy + # modules must not prevent fdroidserver from functioning + # TODO: think about warning users or debug logs for notifying devs + pass + return commands + + def main(): + sys.path.append(os.getcwd()) + fdroid_modules = find_plugins() if len(sys.argv) <= 1: - print_help() + print_help(fdroid_modules=fdroid_modules) sys.exit(0) command = sys.argv[1] - if command not in commands: + if command not in commands and command not in fdroid_modules.keys(): if command in ('-h', '--help'): - print_help() + print_help(fdroid_modules=fdroid_modules) sys.exit(0) elif command == '--version': output = _('no version info found!') @@ -103,7 +130,7 @@ def main(): sys.exit(0) else: print(_("Command '%s' not recognised.\n" % command)) - print_help() + print_help(fdroid_modules=fdroid_modules) sys.exit(1) verbose = any(s in sys.argv for s in ['-v', '--verbose']) @@ -133,7 +160,10 @@ def main(): sys.argv[0] += ' ' + command del sys.argv[1] - mod = __import__('fdroidserver.' + command, None, None, [command]) + if command in commands.keys(): + mod = __import__('fdroidserver.' + command, None, None, [command]) + else: + mod = fdroid_modules[command]['module'] system_langcode, system_encoding = locale.getdefaultlocale() if system_encoding is None or system_encoding.lower() not in ('utf-8', 'utf8'): diff --git a/tests/main.TestCase b/tests/main.TestCase index 8621cfcc..c303f181 100755 --- a/tests/main.TestCase +++ b/tests/main.TestCase @@ -4,8 +4,11 @@ import inspect import optparse import os import sys +import textwrap import unittest +import tempfile from unittest import mock +from testcommon import TmpCwd, TmpPyPath localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) @@ -17,7 +20,7 @@ from fdroidserver import common import fdroidserver.__main__ -class FdroidTest(unittest.TestCase): +class MainTest(unittest.TestCase): '''this tests fdroid.py''' def test_commands(self): @@ -49,18 +52,43 @@ class FdroidTest(unittest.TestCase): co = mock.Mock() with mock.patch('sys.argv', ['', 'init', '-h']): with mock.patch('fdroidserver.init.main', co): - with mock.patch('sys.exit', lambda x: None): + with mock.patch('sys.exit') as exit_mock: fdroidserver.__main__.main() + exit_mock.assert_called_once_with(0) co.assert_called_once_with() def test_call_deploy(self): co = mock.Mock() with mock.patch('sys.argv', ['', 'deploy', '-h']): with mock.patch('fdroidserver.server.main', co): - with mock.patch('sys.exit', lambda x: None): + with mock.patch('sys.exit') as exit_mock: fdroidserver.__main__.main() + exit_mock.assert_called_once_with(0) co.assert_called_once_with() + def test_find_plugins(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('fdroid_testy.py', 'w') as f: + f.write(textwrap.dedent("""\ + fdroid_summary = "ttt" + main = lambda: 'all good'""")) + with TmpPyPath(tmpdir): + plugins = fdroidserver.__main__.find_plugins() + self.assertIn('testy', plugins.keys()) + self.assertEqual(plugins['testy']['summary'], 'ttt') + self.assertEqual(plugins['testy']['module'].main(), 'all good') + + def test_main_plugin(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('fdroid_testy.py', 'w') as f: + f.write(textwrap.dedent("""\ + fdroid_summary = "ttt" + main = lambda: pritn('all good')""")) + with mock.patch('sys.argv', ['', 'testy']): + with mock.patch('sys.exit') as exit_mock: + fdroidserver.__main__.main() + exit_mock.assert_called_once_with(0) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) @@ -71,5 +99,5 @@ if __name__ == "__main__": (common.options, args) = parser.parse_args(['--verbose']) newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(FdroidTest)) + newSuite.addTest(unittest.makeSuite(MainTest)) unittest.main(failfast=False) diff --git a/tests/testcommon.py b/tests/testcommon.py index a637012e..2557bd61 100644 --- a/tests/testcommon.py +++ b/tests/testcommon.py @@ -16,6 +16,7 @@ # along with this program. If not, see . import os +import sys class TmpCwd(): @@ -32,3 +33,18 @@ class TmpCwd(): def __exit__(self, a, b, c): os.chdir(self.orig_cwd) + + +class TmpPyPath(): + """Context-manager for temporarily changing the current working + directory. + """ + + def __init__(self, additional_path): + self.additional_path = additional_path + + def __enter__(self): + sys.path.append(self.additional_path) + + def __exit__(self, a, b, c): + sys.path.remove(self.additional_path) From 3a3803ea2deba72257f29ec654917bb271f720f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 29 Jan 2020 12:39:21 +0100 Subject: [PATCH 0344/2775] raise excepten when starting broken plugin --- fdroidserver/__main__.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index 70b35993..fa7eb02a 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -74,17 +74,19 @@ def find_plugins(): fdroid_modules = [x[1] for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] commands = {} for module_name in fdroid_modules: + command_name = module_name[7:] try: - command_name = module_name[7:] module = importlib.import_module(module_name) if hasattr(module, 'fdroid_summary') and hasattr(module, 'main'): commands[command_name] = {'summary': module.fdroid_summary, 'module': module} - except IOError: + except Exception as e: # We need to keep module lookup fault tolerant because buggy # modules must not prevent fdroidserver from functioning - # TODO: think about warning users or debug logs for notifying devs - pass + if len(sys.argv) > 1 and sys.argv[1] == command_name: + # only raise exeption when a user specifies the broken + # plugin in explicitly in command line + raise e return commands From b257a3411a9dec1a22e53b46eef0827a3c202a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 29 Jan 2020 13:08:43 +0100 Subject: [PATCH 0345/2775] stick to default python sys.path --- fdroidserver/__main__.py | 1 - tests/main.TestCase | 11 +++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index fa7eb02a..46cf87df 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -91,7 +91,6 @@ def find_plugins(): def main(): - sys.path.append(os.getcwd()) fdroid_modules = find_plugins() if len(sys.argv) <= 1: diff --git a/tests/main.TestCase b/tests/main.TestCase index c303f181..e33c6758 100755 --- a/tests/main.TestCase +++ b/tests/main.TestCase @@ -84,10 +84,13 @@ class MainTest(unittest.TestCase): f.write(textwrap.dedent("""\ fdroid_summary = "ttt" main = lambda: pritn('all good')""")) - with mock.patch('sys.argv', ['', 'testy']): - with mock.patch('sys.exit') as exit_mock: - fdroidserver.__main__.main() - exit_mock.assert_called_once_with(0) + test_path = sys.path.copy() + test_path.append(tmpdir) + with mock.patch('sys.path', test_path): + with mock.patch('sys.argv', ['', 'testy']): + with mock.patch('sys.exit') as exit_mock: + fdroidserver.__main__.main() + exit_mock.assert_called_once_with(0) if __name__ == "__main__": From 77167e098ece2a8b93d8f9bcb8c52737ff1750d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 10 Jun 2020 18:43:11 +0200 Subject: [PATCH 0346/2775] plugin system: regex instead of import bases plugin parsing --- fdroidserver/__main__.py | 53 ++++++++++++++++++++----- tests/main.TestCase | 85 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 122 insertions(+), 16 deletions(-) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index 46cf87df..785179de 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -18,12 +18,12 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import re import sys import os import locale import pkgutil import logging -import importlib import fdroidserver.common import fdroidserver.metadata @@ -70,16 +70,51 @@ def print_help(fdroid_modules=None): print("") +def preparse_plugin(module_name, module_dir): + """simple regex based parsing for plugin scripts, + so we don't have to import them when we just need the summary, + but not plan on executing this particular plugin.""" + if '.' in module_name: + raise ValueError("No '.' allowed in fdroid plugin modules: '{}'" + .format(module_name)) + path = os.path.join(module_dir, module_name + '.py') + if not os.path.isfile(path): + path = os.path.join(module_dir, module_name, '__main__.py') + if not os.path.isfile(path): + raise ValueError("unable to find main plugin script " + "for module '{n}' ('{d}')" + .format(n=module_name, + d=module_dir)) + summary = None + main = None + with open(path, 'r', encoding='utf-8') as f: + re_main = re.compile(r'^(\s*def\s+main\s*\(.*\)\s*:' + r'|\s*main\s*=\s*lambda\s*:.+)$') + re_summary = re.compile(r'^\s*fdroid_summary\s*=\s["\'](?P.+)["\']$') + for line in f: + m_summary = re_summary.match(line) + if m_summary: + summary = m_summary.group('text') + if re_main.match(line): + main = True + + if summary is None: + raise NameError("could not find 'fdroid_summary' in: '{}' plugin" + .format(module_name)) + if main is None: + raise NameError("could not find 'main' function in: '{}' plugin" + .format(module_name)) + return {'name': module_name, 'summary': summary} + + def find_plugins(): - fdroid_modules = [x[1] for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] + found_plugins = [{'name': x[1], 'dir': x[0].path} for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] commands = {} - for module_name in fdroid_modules: - command_name = module_name[7:] + for plugin_def in found_plugins: + command_name = plugin_def['name'][7:] try: - module = importlib.import_module(module_name) - if hasattr(module, 'fdroid_summary') and hasattr(module, 'main'): - commands[command_name] = {'summary': module.fdroid_summary, - 'module': module} + commands[command_name] = preparse_plugin(plugin_def['name'], + plugin_def['dir']) except Exception as e: # We need to keep module lookup fault tolerant because buggy # modules must not prevent fdroidserver from functioning @@ -164,7 +199,7 @@ def main(): if command in commands.keys(): mod = __import__('fdroidserver.' + command, None, None, [command]) else: - mod = fdroid_modules[command]['module'] + mod = __import__(fdroid_modules[command]['name'], None, None, [command]) system_langcode, system_encoding = locale.getdefaultlocale() if system_encoding is None or system_encoding.lower() not in ('utf-8', 'utf8'): diff --git a/tests/main.TestCase b/tests/main.TestCase index e33c6758..35b80bc2 100755 --- a/tests/main.TestCase +++ b/tests/main.TestCase @@ -4,6 +4,7 @@ import inspect import optparse import os import sys +import pkgutil import textwrap import unittest import tempfile @@ -74,24 +75,94 @@ class MainTest(unittest.TestCase): main = lambda: 'all good'""")) with TmpPyPath(tmpdir): plugins = fdroidserver.__main__.find_plugins() - self.assertIn('testy', plugins.keys()) - self.assertEqual(plugins['testy']['summary'], 'ttt') - self.assertEqual(plugins['testy']['module'].main(), 'all good') + self.assertIn('testy', plugins.keys()) + self.assertEqual(plugins['testy']['summary'], 'ttt') + self.assertEqual(__import__(plugins['testy']['name'], + None, + None, + ['testy']) + .main(), + 'all good') - def test_main_plugin(self): + def test_main_plugin_lambda(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('fdroid_testy.py', 'w') as f: f.write(textwrap.dedent("""\ fdroid_summary = "ttt" main = lambda: pritn('all good')""")) - test_path = sys.path.copy() - test_path.append(tmpdir) - with mock.patch('sys.path', test_path): + with TmpPyPath(tmpdir): with mock.patch('sys.argv', ['', 'testy']): with mock.patch('sys.exit') as exit_mock: fdroidserver.__main__.main() exit_mock.assert_called_once_with(0) + def test_main_plugin_def(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('fdroid_testy.py', 'w') as f: + f.write(textwrap.dedent("""\ + fdroid_summary = "ttt" + def main(): + pritn('all good')""")) + with TmpPyPath(tmpdir): + with mock.patch('sys.argv', ['', 'testy']): + with mock.patch('sys.exit') as exit_mock: + fdroidserver.__main__.main() + exit_mock.assert_called_once_with(0) + + def test_preparse_plugin_lookup_bad_name(self): + self.assertRaises(ValueError, + fdroidserver.__main__.preparse_plugin, + "some.package", "/non/existent/module/path") + + def test_preparse_plugin_lookup_bad_path(self): + self.assertRaises(ValueError, + fdroidserver.__main__.preparse_plugin, + "fake_module_name", "/non/existent/module/path") + + def test_preparse_plugin_lookup_summary_missing(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('fdroid_testy.py', 'w') as f: + f.write(textwrap.dedent("""\ + main = lambda: print('all good')""")) + with TmpPyPath(tmpdir): + p = [x for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] + module_dir = p[0][0].path + module_name = p[0][1] + self.assertRaises(NameError, + fdroidserver.__main__.preparse_plugin, + module_name, module_dir) + + def test_preparse_plugin_lookup_module_file(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('fdroid_testy.py', 'w') as f: + f.write(textwrap.dedent("""\ + fdroid_summary = "ttt" + main = lambda: pritn('all good')""")) + with TmpPyPath(tmpdir): + p = [x for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] + module_path = p[0][0].path + module_name = p[0][1] + d = fdroidserver.__main__.preparse_plugin(module_name, module_path) + self.assertDictEqual(d, {'name': 'fdroid_testy', + 'summary': 'ttt'}) + + def test_preparse_plugin_lookup_module_dir(self): + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + os.mkdir(os.path.join(tmpdir, 'fdroid_testy')) + with open('fdroid_testy/__main__.py', 'w') as f: + f.write(textwrap.dedent("""\ + fdroid_summary = "ttt" + main = lambda: print('all good')""")) + with open('fdroid_testy/__init__.py', 'w') as f: + pass + with TmpPyPath(tmpdir): + p = [x for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] + module_path = p[0][0].path + module_name = p[0][1] + d = fdroidserver.__main__.preparse_plugin(module_name, module_path) + self.assertDictEqual(d, {'name': 'fdroid_testy', + 'summary': 'ttt'}) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From a97b3ca4dd30999091c8afc4e9ddd4d354ae09ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 10 Jun 2020 18:15:38 +0200 Subject: [PATCH 0347/2775] implement plugin system review suggestsions --- fdroidserver/__main__.py | 36 ++++++++-------- tests/main.TestCase | 93 +++++++++++++++++++++++++++++++--------- 2 files changed, 91 insertions(+), 38 deletions(-) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index 785179de..770d8c13 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -32,7 +32,7 @@ from argparse import ArgumentError from collections import OrderedDict -commands = OrderedDict([ +COMMANDS = OrderedDict([ ("build", _("Build a package from source")), ("init", _("Quickly start a new repository")), ("publish", _("Sign and place packages in the repo")), @@ -57,16 +57,16 @@ commands = OrderedDict([ ]) -def print_help(fdroid_modules=None): +def print_help(available_plugins=None): print(_("usage: ") + _("fdroid [] [-h|--help|--version|]")) print("") print(_("Valid commands are:")) - for cmd, summary in commands.items(): + for cmd, summary in COMMANDS.items(): print(" " + cmd + ' ' * (15 - len(cmd)) + summary) - if fdroid_modules: + if available_plugins: print(_('commands from plugin modules:')) - for command in sorted(fdroid_modules.keys()): - print(' {:15}{}'.format(command, fdroid_modules[command]['summary'])) + for command in sorted(available_plugins.keys()): + print(' {:15}{}'.format(command, available_plugins[command]['summary'])) print("") @@ -109,12 +109,12 @@ def preparse_plugin(module_name, module_dir): def find_plugins(): found_plugins = [{'name': x[1], 'dir': x[0].path} for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] - commands = {} + plugin_infos = {} for plugin_def in found_plugins: command_name = plugin_def['name'][7:] try: - commands[command_name] = preparse_plugin(plugin_def['name'], - plugin_def['dir']) + plugin_infos[command_name] = preparse_plugin(plugin_def['name'], + plugin_def['dir']) except Exception as e: # We need to keep module lookup fault tolerant because buggy # modules must not prevent fdroidserver from functioning @@ -122,20 +122,20 @@ def find_plugins(): # only raise exeption when a user specifies the broken # plugin in explicitly in command line raise e - return commands + return plugin_infos def main(): - fdroid_modules = find_plugins() + available_plugins = find_plugins() if len(sys.argv) <= 1: - print_help(fdroid_modules=fdroid_modules) + print_help(available_plugins=available_plugins) sys.exit(0) command = sys.argv[1] - if command not in commands and command not in fdroid_modules.keys(): + if command not in COMMANDS and command not in available_plugins.keys(): if command in ('-h', '--help'): - print_help(fdroid_modules=fdroid_modules) + print_help(available_plugins=available_plugins) sys.exit(0) elif command == '--version': output = _('no version info found!') @@ -162,11 +162,11 @@ def main(): else: from pkg_resources import get_distribution output = get_distribution('fdroidserver').version + '\n' - print(output), + print(output) sys.exit(0) else: print(_("Command '%s' not recognised.\n" % command)) - print_help(fdroid_modules=fdroid_modules) + print_help(available_plugins=available_plugins) sys.exit(1) verbose = any(s in sys.argv for s in ['-v', '--verbose']) @@ -196,10 +196,10 @@ def main(): sys.argv[0] += ' ' + command del sys.argv[1] - if command in commands.keys(): + if command in COMMANDS.keys(): mod = __import__('fdroidserver.' + command, None, None, [command]) else: - mod = __import__(fdroid_modules[command]['name'], None, None, [command]) + mod = __import__(available_plugins[command]['name'], None, None, [command]) system_langcode, system_encoding = locale.getdefaultlocale() if system_encoding is None or system_encoding.lower() not in ('utf-8', 'utf8'): diff --git a/tests/main.TestCase b/tests/main.TestCase index 35b80bc2..e05efd95 100755 --- a/tests/main.TestCase +++ b/tests/main.TestCase @@ -24,9 +24,9 @@ import fdroidserver.__main__ class MainTest(unittest.TestCase): '''this tests fdroid.py''' - def test_commands(self): + def test_COMMANDS_check(self): """make sure the built in sub-command defs didn't change unintentionally""" - self.assertListEqual([x for x in fdroidserver.__main__.commands.keys()], + self.assertListEqual([x for x in fdroidserver.__main__.COMMANDS.keys()], ['build', 'init', 'publish', @@ -55,6 +55,8 @@ class MainTest(unittest.TestCase): with mock.patch('fdroidserver.init.main', co): with mock.patch('sys.exit') as exit_mock: fdroidserver.__main__.main() + # note: this is sloppy, if `init` changes + # this might need changing too exit_mock.assert_called_once_with(0) co.assert_called_once_with() @@ -64,51 +66,102 @@ class MainTest(unittest.TestCase): with mock.patch('fdroidserver.server.main', co): with mock.patch('sys.exit') as exit_mock: fdroidserver.__main__.main() + # note: this is sloppy, if `deploy` changes + # this might need changing too exit_mock.assert_called_once_with(0) co.assert_called_once_with() def test_find_plugins(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('fdroid_testy.py', 'w') as f: + with open('fdroid_testy1.py', 'w') as f: f.write(textwrap.dedent("""\ fdroid_summary = "ttt" main = lambda: 'all good'""")) with TmpPyPath(tmpdir): plugins = fdroidserver.__main__.find_plugins() - self.assertIn('testy', plugins.keys()) - self.assertEqual(plugins['testy']['summary'], 'ttt') - self.assertEqual(__import__(plugins['testy']['name'], + self.assertIn('testy1', plugins.keys()) + self.assertEqual(plugins['testy1']['summary'], 'ttt') + self.assertEqual(__import__(plugins['testy1']['name'], None, None, - ['testy']) + ['testy1']) .main(), 'all good') def test_main_plugin_lambda(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('fdroid_testy.py', 'w') as f: + with open('fdroid_testy2.py', 'w') as f: f.write(textwrap.dedent("""\ fdroid_summary = "ttt" - main = lambda: pritn('all good')""")) + main = lambda: print('all good')""")) with TmpPyPath(tmpdir): - with mock.patch('sys.argv', ['', 'testy']): + with mock.patch('sys.argv', ['', 'testy2']): with mock.patch('sys.exit') as exit_mock: fdroidserver.__main__.main() exit_mock.assert_called_once_with(0) def test_main_plugin_def(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('fdroid_testy.py', 'w') as f: + with open('fdroid_testy3.py', 'w') as f: f.write(textwrap.dedent("""\ fdroid_summary = "ttt" def main(): - pritn('all good')""")) + print('all good')""")) with TmpPyPath(tmpdir): - with mock.patch('sys.argv', ['', 'testy']): + with mock.patch('sys.argv', ['', 'testy3']): with mock.patch('sys.exit') as exit_mock: fdroidserver.__main__.main() exit_mock.assert_called_once_with(0) + def test_main_broken_plugin(self): + """making sure broken plugins get their exceptions through""" + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('fdroid_testy4.py', 'w') as f: + f.write(textwrap.dedent("""\ + fdroid_summary = "ttt" + def main(): + raise Exception("this plugin is broken")""")) + with TmpPyPath(tmpdir): + with mock.patch('sys.argv', ['', 'testy4']): + with self.assertRaisesRegex(Exception, "this plugin is broken"): + fdroidserver.__main__.main() + + def test_main_malicious_plugin(self): + """The purpose of this test is to make sure code in plugins + doesn't get executed unintentionally. + """ + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('fdroid_testy5.py', 'w') as f: + f.write(textwrap.dedent("""\ + fdroid_summary = "ttt" + raise Exception("this plugin is malicious") + def main(): + print("evil things")""")) + with TmpPyPath(tmpdir): + with mock.patch('sys.argv', ['', 'lint']): + with mock.patch('sys.exit') as exit_mock: + fdroidserver.__main__.main() + # note: this is sloppy, if `lint` changes + # this might need changing too + exit_mock.assert_called_once_with(0) + + def test_main_prevent_plugin_override(self): + """making sure build-in subcommands cannot be overridden by plugins + """ + with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with open('fdroid_signatures.py', 'w') as f: + f.write(textwrap.dedent("""\ + fdroid_summary = "ttt" + def main(): + raise("plugin overrides don't get prevent!")""")) + with TmpPyPath(tmpdir): + with mock.patch('sys.argv', ['', 'signatures']): + with mock.patch('sys.exit') as exit_mock: + fdroidserver.__main__.main() + # note: this is sloppy, if `signatures` changes + # this might need changing too + self.assertEqual(exit_mock.call_count, 2) + def test_preparse_plugin_lookup_bad_name(self): self.assertRaises(ValueError, fdroidserver.__main__.preparse_plugin, @@ -121,7 +174,7 @@ class MainTest(unittest.TestCase): def test_preparse_plugin_lookup_summary_missing(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('fdroid_testy.py', 'w') as f: + with open('fdroid_testy6.py', 'w') as f: f.write(textwrap.dedent("""\ main = lambda: print('all good')""")) with TmpPyPath(tmpdir): @@ -134,7 +187,7 @@ class MainTest(unittest.TestCase): def test_preparse_plugin_lookup_module_file(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('fdroid_testy.py', 'w') as f: + with open('fdroid_testy7.py', 'w') as f: f.write(textwrap.dedent("""\ fdroid_summary = "ttt" main = lambda: pritn('all good')""")) @@ -143,24 +196,24 @@ class MainTest(unittest.TestCase): module_path = p[0][0].path module_name = p[0][1] d = fdroidserver.__main__.preparse_plugin(module_name, module_path) - self.assertDictEqual(d, {'name': 'fdroid_testy', + self.assertDictEqual(d, {'name': 'fdroid_testy7', 'summary': 'ttt'}) def test_preparse_plugin_lookup_module_dir(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - os.mkdir(os.path.join(tmpdir, 'fdroid_testy')) - with open('fdroid_testy/__main__.py', 'w') as f: + os.mkdir(os.path.join(tmpdir, 'fdroid_testy8')) + with open('fdroid_testy8/__main__.py', 'w') as f: f.write(textwrap.dedent("""\ fdroid_summary = "ttt" main = lambda: print('all good')""")) - with open('fdroid_testy/__init__.py', 'w') as f: + with open('fdroid_testy8/__init__.py', 'w') as f: pass with TmpPyPath(tmpdir): p = [x for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] module_path = p[0][0].path module_name = p[0][1] d = fdroidserver.__main__.preparse_plugin(module_name, module_path) - self.assertDictEqual(d, {'name': 'fdroid_testy', + self.assertDictEqual(d, {'name': 'fdroid_testy8', 'summary': 'ttt'}) From 3bc246ccad3169fc3662be9a206953de864bb21d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 14:34:21 +0200 Subject: [PATCH 0348/2775] scanner: ignore well known image types that are set executable --- fdroidserver/scanner.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 6560c4da..3ef9e06e 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import imghdr import json import os import re @@ -196,6 +197,8 @@ def scan_source(build_dir, build=metadata.Build()): for sp in safe_paths: if sp.match(path): return True + if imghdr.what(path) is not None: + return True return False gradle_compile_commands = get_gradle_compile_commands(build) @@ -277,7 +280,7 @@ def scan_source(build_dir, build=metadata.Build()): elif is_executable(filepath): if is_binary(filepath) and not safe_path(path_in_build_dir): - warnproblem('possible binary', path_in_build_dir) + warnproblem('executable binary, possibly code', path_in_build_dir) for p in scanignore: if p not in scanignore_worked: From d898ad04120ee466392682ea482dcc7a856d5645 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 15:12:04 +0200 Subject: [PATCH 0349/2775] scanner: make AARs and JARs trigger an error refs #491 --- fdroidserver/scanner.py | 7 +++---- tests/build.TestCase | 5 +++-- tests/scanner.TestCase | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 3ef9e06e..93297ff7 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -232,6 +232,8 @@ def scan_source(build_dir, build=metadata.Build()): count += handleproblem('shared library', path_in_build_dir, filepath) elif ext == 'a': count += handleproblem('static library', path_in_build_dir, filepath) + elif ext == 'aar': + count += handleproblem(_('Android AAR library'), path_in_build_dir, filepath) elif ext == 'class': count += handleproblem('Java compiled class', path_in_build_dir, filepath) elif ext == 'apk': @@ -243,10 +245,7 @@ def scan_source(build_dir, build=metadata.Build()): if curfile == 'gradle-wrapper.jar': removeproblem('gradle-wrapper.jar', path_in_build_dir, filepath) else: - warnproblem('JAR file', path_in_build_dir) - - elif ext == 'aar': - warnproblem('AAR file', path_in_build_dir) + count += handleproblem('JAR file', path_in_build_dir, filepath) elif ext == 'java': if not os.path.isfile(filepath): diff --git a/tests/build.TestCase b/tests/build.TestCase index 547c0b6e..033c6411 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -141,7 +141,8 @@ class BuildTest(unittest.TestCase): build = fdroidserver.metadata.Build() build.commit = '1.0' build.output = app.id + '.apk' - build.scanignore = ['baz.so'] + build.scandelete = ['baz.so'] + build.scanignore = ['foo.aar'] build.versionCode = '1' build.versionName = '1.0' vcs = mock.Mock() @@ -186,11 +187,11 @@ class BuildTest(unittest.TestCase): force=False, onserver=False, refresh=False ) - self.assertTrue(os.path.exists('baz.so')) self.assertTrue(os.path.exists('foo.aar')) self.assertTrue(os.path.isdir('build')) self.assertTrue(os.path.isdir('reports')) self.assertTrue(os.path.isdir('target')) + self.assertFalse(os.path.exists('baz.so')) self.assertFalse(os.path.exists('bin')) self.assertFalse(os.path.exists('build/reports')) self.assertFalse(os.path.exists('gen')) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 4392664e..6bb74f9a 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -99,7 +99,7 @@ class ScannerTest(unittest.TestCase): build = fdroidserver.metadata.Build() build.commit = '1.0' build.output = app.id + '.apk' - build.scanignore = ['baz.so'] + build.scanignore = ['baz.so', 'foo.aar'] build.versionCode = '1' build.versionName = '1.0' vcs = mock.Mock() From 84f225f2f2a9fd7c3d696ef69f9c5e710be2bdba Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 15:25:26 +0200 Subject: [PATCH 0350/2775] scanner: make problem descriptions translationable --- fdroidserver/scanner.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 93297ff7..a8d1449d 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -228,16 +228,16 @@ def scan_source(build_dir, build=metadata.Build()): path_in_build_dir = os.path.relpath(filepath, build_dir) _ignored, ext = common.get_extension(path_in_build_dir) - if ext == 'so': - count += handleproblem('shared library', path_in_build_dir, filepath) - elif ext == 'a': - count += handleproblem('static library', path_in_build_dir, filepath) + if ext == 'a': + count += handleproblem(_('static library'), path_in_build_dir, filepath) elif ext == 'aar': count += handleproblem(_('Android AAR library'), path_in_build_dir, filepath) elif ext == 'class': - count += handleproblem('Java compiled class', path_in_build_dir, filepath) + count += handleproblem(_('Java compiled class'), path_in_build_dir, filepath) + elif ext == 'so': + count += handleproblem(_('shared library'), path_in_build_dir, filepath) elif ext == 'apk': - removeproblem('APK file', path_in_build_dir, filepath) + removeproblem(_('Android APK file'), path_in_build_dir, filepath) elif ext == 'jar': for name in suspects_found(curfile): @@ -279,16 +279,16 @@ def scan_source(build_dir, build=metadata.Build()): elif is_executable(filepath): if is_binary(filepath) and not safe_path(path_in_build_dir): - warnproblem('executable binary, possibly code', path_in_build_dir) + warnproblem(_('executable binary, possibly code'), path_in_build_dir) for p in scanignore: if p not in scanignore_worked: - logging.error('Unused scanignore path: %s' % p) + logging.error(_('Unused scanignore path: %s') % p) count += 1 for p in scandelete: if p not in scandelete_worked: - logging.error('Unused scandelete path: %s' % p) + logging.error(_('Unused scandelete path: %s') % p) count += 1 return count From 2f5d780c49e62950c3e8f8ec86a3429f593c66d6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 15:45:39 +0200 Subject: [PATCH 0351/2775] scanner: always setup JSON data structure so functions work as API --- fdroidserver/scanner.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index a8d1449d..f1cc171d 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -34,7 +34,8 @@ from .exception import BuildException, VCSException config = None options = None -json_per_build = None +DEFAULT_JSON_PER_BUILD = {'errors': [], 'warnings': [], 'infos': []} +json_per_build = DEFAULT_JSON_PER_BUILD def get_gradle_compile_commands(build): @@ -338,7 +339,7 @@ def main(): if app.Disabled and not options.force: logging.info(_("Skipping {appid}: disabled").format(appid=appid)) - json_per_appid = json_per_appid['infos'].append('Skipping: disabled') + json_per_appid['disabled'] = json_per_build['infos'].append('Skipping: disabled') continue try: @@ -354,7 +355,7 @@ def main(): else: logging.info(_("{appid}: no builds specified, running on current source state") .format(appid=appid)) - json_per_build = {'errors': [], 'warnings': [], 'infos': []} + json_per_build = DEFAULT_JSON_PER_BUILD json_per_appid['current-source-state'] = json_per_build count = scan_source(build_dir) if count > 0: @@ -364,7 +365,7 @@ def main(): app.builds = [] for build in app.builds: - json_per_build = {'errors': [], 'warnings': [], 'infos': []} + json_per_build = DEFAULT_JSON_PER_BUILD json_per_appid[build.versionCode] = json_per_build if build.disable and not options.force: From 75acf63efa9e7d01397c3879e98720d17abc2edb Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 16:55:43 +0200 Subject: [PATCH 0352/2775] scanner: remove all gradle wrapper files --- fdroidserver/scanner.py | 25 ++++++------- tests/scanner.TestCase | 78 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index f1cc171d..034d4f3c 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -146,15 +146,17 @@ def scan_source(build_dir, build=metadata.Build()): return False def ignoreproblem(what, path_in_build_dir): - logging.info('Ignoring %s at %s' % (what, path_in_build_dir)) + msg = ('Ignoring %s at %s' % (what, path_in_build_dir)) + logging.info(msg) if json_per_build is not None: - json_per_build['infos'].append([what, path_in_build_dir]) + json_per_build['infos'].append([msg, path_in_build_dir]) return 0 def removeproblem(what, path_in_build_dir, filepath): - logging.info('Removing %s at %s' % (what, path_in_build_dir)) + msg = ('Removing %s at %s' % (what, path_in_build_dir)) + logging.info(msg) if json_per_build is not None: - json_per_build['infos'].append([what, path_in_build_dir]) + json_per_build['infos'].append([msg, path_in_build_dir]) os.remove(filepath) return 0 @@ -229,7 +231,12 @@ def scan_source(build_dir, build=metadata.Build()): path_in_build_dir = os.path.relpath(filepath, build_dir) _ignored, ext = common.get_extension(path_in_build_dir) - if ext == 'a': + if curfile in ('gradle-wrapper.jar', 'gradlew', 'gradlew.bat'): + removeproblem(curfile, path_in_build_dir, filepath) + elif ext == 'apk': + removeproblem(_('Android APK file'), path_in_build_dir, filepath) + + elif ext == 'a': count += handleproblem(_('static library'), path_in_build_dir, filepath) elif ext == 'aar': count += handleproblem(_('Android AAR library'), path_in_build_dir, filepath) @@ -237,16 +244,10 @@ def scan_source(build_dir, build=metadata.Build()): count += handleproblem(_('Java compiled class'), path_in_build_dir, filepath) elif ext == 'so': count += handleproblem(_('shared library'), path_in_build_dir, filepath) - elif ext == 'apk': - removeproblem(_('Android APK file'), path_in_build_dir, filepath) - elif ext == 'jar': for name in suspects_found(curfile): count += handleproblem('usual suspect \'%s\'' % name, path_in_build_dir, filepath) - if curfile == 'gradle-wrapper.jar': - removeproblem('gradle-wrapper.jar', path_in_build_dir, filepath) - else: - count += handleproblem('JAR file', path_in_build_dir, filepath) + count += handleproblem(_('Java JAR file'), path_in_build_dir, filepath) elif ext == 'java': if not os.path.isfile(filepath): diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 6bb74f9a..fc10a8af 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -5,10 +5,12 @@ import inspect import logging import optparse import os +import shutil import sys import tempfile import textwrap import unittest +import uuid from unittest import mock localmodule = os.path.realpath( @@ -80,6 +82,82 @@ class ScannerTest(unittest.TestCase): i += 1 self.assertEqual(count, i) + def test_scan_source_file_types(self): + """Build product files are not allowed, test they are detected""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + + fdroidserver.scanner.config = None + fdroidserver.scanner.options = mock.Mock() + fdroidserver.scanner.options.json = True + + keep = [ + 'arg.jar', + 'ascii.out', + 'baz.so', + 'sqlcipher.aar', + 'static.a', + ] + remove = [ + 'gradle-wrapper.jar', + 'gradlew', + 'gradlew.bat', + ] + for f in keep + remove: + with open(f, 'w') as fp: + fp.write('placeholder') + self.assertTrue(os.path.exists(f)) + binaries = [ + 'binary.out', + 'fake.png', + 'snippet.png', + ] + with open('binary.out', 'wb') as fp: + fp.write(b'\x00\x00') + fp.write(uuid.uuid4().bytes) + shutil.copyfile('binary.out', 'fake.png') + os.chmod('fake.png', 0o755) + os.system('ls -l binary.out') + with open('snippet.png', 'wb') as fp: + fp.write(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00' + b'\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\x00\x00\x00\x04sB' + b'IT\x08\x08\x08\x08|\x08d\x88\x00\x00\x00\tpHYs\x00\x00\n' + b'a\x00\x00\na\x01\xfc\xccJ%\x00\x00\x00\x19tEXtSoftware') + os.chmod('snippet.png', 0o755) + os.system('ls -l fake.png') + + count = fdroidserver.scanner.scan_source(testdir) + self.assertEqual(5, count, 'there should be this many errors') + + for f in keep + binaries: + self.assertTrue(os.path.exists(f), f + ' should still be there') + for f in remove: + self.assertFalse(os.path.exists(f), f + ' should have been removed') + + files = dict() + for section in ('errors', 'infos', 'warnings'): + files[section] = [] + for msg, f in fdroidserver.scanner.json_per_build[section]: + files[section].append(f) + + self.assertFalse('ascii.out' in files['errors'], + 'an ASCII .out file is not an error') + self.assertFalse('snippet.png' in files['errors'], + 'an executable valid image is not an error') + + self.assertTrue('arg.jar' in files['errors'], 'all JAR files are errors') + self.assertTrue('baz.so' in files['errors'], 'all .so files are errors') + self.assertTrue('binary.out' in files['errors'], 'a binary .out file is an error') + self.assertTrue('sqlcipher.aar' in files['errors'], 'all AAR files are errors') + self.assertTrue('static.a' in files['errors'], 'all .a files are errors') + + self.assertTrue('fake.png' in files['warnings'], + 'a random binary that is executable that is not an image is a warning') + + for f in remove: + self.assertTrue(f in files['infos'], + f + ' should be removed with an info message') + def test_build_local_scanner(self): """`fdroid build` calls scanner functions, test them here""" testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) From ee54dbce87c6cab9d74f83a22131c0940814e485 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 18:34:26 +0200 Subject: [PATCH 0353/2775] scanner: safely check options, for things using this API https://gitlab.com/fdroid/fdroidserver/-/issues/771#note_353495799 --- fdroidserver/scanner.py | 4 ++-- tests/build.TestCase | 1 - tests/scanner.TestCase | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 034d4f3c..a5965b2c 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -172,9 +172,9 @@ def scan_source(build_dir, build=metadata.Build()): return ignoreproblem(what, path_in_build_dir) if todelete(path_in_build_dir): return removeproblem(what, path_in_build_dir, filepath) - if options.json: + if options and options.json: json_per_build['errors'].append([what, path_in_build_dir]) - if not options.json or options.verbose: + if options and (options.verbose or not options.json): logging.error('Found %s at %s' % (what, path_in_build_dir)) return 1 diff --git a/tests/build.TestCase b/tests/build.TestCase index 033c6411..0495bb79 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -132,7 +132,6 @@ class BuildTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config fdroidserver.build.options = mock.Mock() - fdroidserver.build.options.json = False fdroidserver.build.options.notarball = True fdroidserver.build.options.skipscan = False diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index fc10a8af..6612cb21 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -36,7 +36,7 @@ class ScannerTest(unittest.TestCase): os.chdir(self.basedir) def test_scan_source_files(self): - fdroidserver.scanner.options = type('', (), {})() + fdroidserver.scanner.options = mock.Mock() fdroidserver.scanner.options.json = False source_files = os.path.join(self.basedir, 'source-files') projects = { From d7b3bca1e7fd20fb0a699bcee835ceedc19c01d0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 18:34:47 +0200 Subject: [PATCH 0354/2775] build: pass --verbose flag through to scanner --- fdroidserver/build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 13317701..922fe169 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -512,6 +512,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext else: # Scan before building... logging.info("Scanning source for common problems...") + scanner.options = options # pass verbose through count = scanner.scan_source(build_dir, build) if count > 0: if force: From 6590f3869e5f4ed231ad69343735250d46dc9833 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 21:26:03 +0200 Subject: [PATCH 0355/2775] scanner: error/warn on dex/gz/zip, closes #394 --- fdroidserver/scanner.py | 11 ++++++++++- tests/scanner.TestCase | 8 +++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index a5965b2c..9a74c6ca 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -162,16 +162,19 @@ def scan_source(build_dir, build=metadata.Build()): def warnproblem(what, path_in_build_dir): if toignore(path_in_build_dir): - return + return 0 logging.warning('Found %s at %s' % (what, path_in_build_dir)) if json_per_build is not None: json_per_build['warnings'].append([what, path_in_build_dir]) + return 0 def handleproblem(what, path_in_build_dir, filepath): if toignore(path_in_build_dir): return ignoreproblem(what, path_in_build_dir) if todelete(path_in_build_dir): return removeproblem(what, path_in_build_dir, filepath) + if 'src/test' in filepath or '/test/' in filepath: + return warnproblem(what, path_in_build_dir) if options and options.json: json_per_build['errors'].append([what, path_in_build_dir]) if options and (options.verbose or not options.json): @@ -242,8 +245,14 @@ def scan_source(build_dir, build=metadata.Build()): count += handleproblem(_('Android AAR library'), path_in_build_dir, filepath) elif ext == 'class': count += handleproblem(_('Java compiled class'), path_in_build_dir, filepath) + elif ext == 'dex': + count += handleproblem(_('Android DEX code'), path_in_build_dir, filepath) + elif ext == 'gz': + count += handleproblem(_('gzip file archive'), path_in_build_dir, filepath) elif ext == 'so': count += handleproblem(_('shared library'), path_in_build_dir, filepath) + elif ext == 'zip': + count += handleproblem(_('ZIP file archive'), path_in_build_dir, filepath) elif ext == 'jar': for name in suspects_found(curfile): count += handleproblem('usual suspect \'%s\'' % name, path_in_build_dir, filepath) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 6612cb21..354c2f64 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -95,14 +95,17 @@ class ScannerTest(unittest.TestCase): 'arg.jar', 'ascii.out', 'baz.so', + 'classes.dex', 'sqlcipher.aar', 'static.a', + 'src/test/resources/classes.dex', ] remove = [ 'gradle-wrapper.jar', 'gradlew', 'gradlew.bat', ] + os.makedirs('src/test/resources', exist_ok=True) for f in keep + remove: with open(f, 'w') as fp: fp.write('placeholder') @@ -127,7 +130,7 @@ class ScannerTest(unittest.TestCase): os.system('ls -l fake.png') count = fdroidserver.scanner.scan_source(testdir) - self.assertEqual(5, count, 'there should be this many errors') + self.assertEqual(6, count, 'there should be this many errors') for f in keep + binaries: self.assertTrue(os.path.exists(f), f + ' should still be there') @@ -148,11 +151,14 @@ class ScannerTest(unittest.TestCase): self.assertTrue('arg.jar' in files['errors'], 'all JAR files are errors') self.assertTrue('baz.so' in files['errors'], 'all .so files are errors') self.assertTrue('binary.out' in files['errors'], 'a binary .out file is an error') + self.assertTrue('classes.dex' in files['errors'], 'all classes.dex files are errors') self.assertTrue('sqlcipher.aar' in files['errors'], 'all AAR files are errors') self.assertTrue('static.a' in files['errors'], 'all .a files are errors') self.assertTrue('fake.png' in files['warnings'], 'a random binary that is executable that is not an image is a warning') + self.assertTrue('src/test/resources/classes.dex' in files['warnings'], + 'suspicious file but in a test dir is a warning') for f in remove: self.assertTrue(f in files['infos'], From 08372899354ef0b6b75996f6201d8e8456db3823 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 3 Jun 2020 23:40:01 +0200 Subject: [PATCH 0356/2775] scanner: fix regex for matching URLs in gradle maven{} blocks closes #465 This script generated gradle-maven-blocks.yaml: ```python import os import re import yaml pat = re.compile(r'\smaven\s*{[^}]+}') finds = set() for root, dirs, files in os.walk('.'): for f in files: if '.gradle' in f: with open(os.path.join(root, f), errors='surrogateescape') as fp: contents = fp.read() for m in pat.findall(contents): finds.add(m) with open('finds.yaml', 'w') as fp: yaml.dump(sorted(finds), fp, default_flow_style=False) ``` --- fdroidserver/scanner.py | 10 +- tests/gradle-maven-blocks.yaml | 778 +++++++++++++++++++++++++++++++++ tests/scanner.TestCase | 36 ++ 3 files changed, 819 insertions(+), 5 deletions(-) create mode 100644 tests/gradle-maven-blocks.yaml diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 9a74c6ca..1c30d189 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -37,6 +37,9 @@ options = None DEFAULT_JSON_PER_BUILD = {'errors': [], 'warnings': [], 'infos': []} json_per_build = DEFAULT_JSON_PER_BUILD +MAVEN_URL_REGEX = re.compile(r"""\smaven\s*{.*?(?:setUrl|url)\s*=?\s*(?:uri)?\(?\s*["']?([^\s"']+)["']?[^}]*}""", + re.DOTALL) + def get_gradle_compile_commands(build): compileCommands = ['compile', @@ -101,8 +104,6 @@ def scan_source(build_dir, build=metadata.Build()): if r.match(s) and not is_whitelisted(s): yield n - gradle_mavenrepo = re.compile(r'maven *{ *(url)? *[\'"]?([^ \'"]*)[\'"]?') - allowed_repos = [re.compile(r'^https://' + re.escape(repo) + r'/*') for repo in [ 'repo1.maven.org/maven2', # mavenCentral() 'jcenter.bintray.com', # jcenter() @@ -278,9 +279,8 @@ def scan_source(build_dir, build=metadata.Build()): count += handleproblem("usual suspect \'%s\'" % (name), path_in_build_dir, filepath) noncomment_lines = [line for line in lines if not common.gradle_comment.match(line)] - joined = re.sub(r'[\n\r\s]+', ' ', ' '.join(noncomment_lines)) - for m in gradle_mavenrepo.finditer(joined): - url = m.group(2) + no_comments = re.sub(r'/\*.*?\*/', '', ''.join(noncomment_lines), flags=re.DOTALL) + for url in MAVEN_URL_REGEX.findall(no_comments): if not any(r.match(url) for r in allowed_repos): count += handleproblem('unknown maven repo \'%s\'' % url, path_in_build_dir, filepath) diff --git a/tests/gradle-maven-blocks.yaml b/tests/gradle-maven-blocks.yaml new file mode 100644 index 00000000..f6587f94 --- /dev/null +++ b/tests/gradle-maven-blocks.yaml @@ -0,0 +1,778 @@ +- "\tmaven {\n\t\t\turl \"$rootDir/../node_modules/react-native-background-fetch/android/libs\"\ + \n\t\t}" +- "\tmaven {\n\t\t\turl \"https://plugins.gradle.org/m2/\"\n\t\t}" +- "\tmaven {\n\t\t\turl 'http://4thline.org/m2'\n\t\t}" +- "\tmaven {\n\t\t\turl 'https://maven.google.com/'\n\t\t\tname 'Google'\n\t\t}" +- "\tmaven {\n\t\turl \"file://$pwd/.m2repo\"\n\t}" +- "\tmaven {\n\t\turl \"https://jitpack.io\"\n\t}" +- "\tmaven {\n\t\turl 'https://maven.google.com/'\n\t\tname 'Google'\n\t}" +- "\tmaven {\n\t url 'https://maven.google.com'\n\t}" +- "\tmaven { url \"http://JRAF.org/static/maven/2\" }" +- "\tmaven { url \"http://dl.bintray.com/populov/maven\" }" +- "\tmaven { url \"https://jitpack.io\" }" +- "\tmaven { url 'http://maven.ghostscript.com/' }" +- "\tmaven { url 'https://jitpack.io' }" +- "\tmaven { url 'https://maven.fabric.io/public' }" +- "\tmaven { url MAVEN_REPO }" +- " maven {\n\t url 'https://jitpack.io'\n }" +- " maven {\n url rootProject.ext.mavenRepo\n \ + \ if (!rootProject.ext.mavenRepo.startsWith(\"file\")) {\n \ + \ credentials {\n username rootProject.ext.mavenUser\n\ + \ password rootProject.ext.mavenPassword\n \ + \ }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n url \"$rootDir/libs/gutenberg-mobile/node_modules/react-native/android\"\ + \n }" +- " maven {\n url \"file:~/.m2/\"\n artifactUrls \"\ + file:~/.m2/\"\n }" +- " maven {\n url \"https://maven-central-asia.storage-download.googleapis.com/repos/central/data/\"\ + \n content {\n excludeGroup(\"Kotlin/Native\"\ + )\n }" +- " maven {\n url \"https://maven-central-asia.storage-download.googleapis.com/repos/central/data/\"\ + \n }" +- " maven {\n url \"https://plugins.gradle.org/m2/\"\n }" +- " maven {\n url \"https://repo.commonsware.com.s3.amazonaws.com\"\ + \n }" +- " maven {\n url 'https://maven.fabric.io/public'\n }" +- " maven {\n // All of React Native (JS, Android binaries) is installed\ + \ from npm\n url \"$rootDir/react/node_modules/react-native/android\"\ + \n }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n // url \"$rootDir/../node_modules/react-native/android\"\ + \n\n // Replace AAR from original RN with AAR from react-native-v8\n\ + \ url(\"$rootDir/../node_modules/react-native-v8/dist\")\n }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n url \"$rootDir/../node_modules/react-native/android\"\ + \n }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n url(\"$rootDir/../node_modules/react-native/android\"\ + )\n }" +- " maven {\n // Android JSC is installed from npm\n url(\"\ + $rootDir/../node_modules/jsc-android/dist\")\n }" +- " maven {\n // Android JSC is installed from npm\n url(\"\ + $rootDir/react/node_modules/jsc-android/dist\")\n }" +- " maven {\n // Local Maven repo containing AARs with JSC library built\ + \ for Android\n // url \"$rootDir/../node_modules/jsc-android/dist\"\n\ + \n // prebuilt libv8android.so\n url(\"$rootDir/../node_modules/v8-android/dist\"\ + )\n }" +- " maven {\n // Local Maven repo containing AARs with JSC library built\ + \ for Android\n url \"$rootDir/../node_modules/jsc-android/dist\"\n \ + \ }" +- " maven {\n //noinspection GroovyAssignabilityCheck\n url\ + \ 'https://jitpack.io'\n }" +- " maven {\n //noinspection GroovyAssignabilityCheck\n url\ + \ 'https://s3.amazonaws.com/moat-sdk-builds'\n }" +- " maven {\n //url 'https://maven.google.com/'\n url 'https://jitpack.io'\n\ + \ name 'Google'\n }" +- " maven {\n name 'glide-snapshot'\n url 'http://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n name 'glide-snapshot'\n url 'https://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n name = \"sonatype\"\n\n def releasesRepoUrl =\ + \ \"https://oss.sonatype.org/service/local/staging/deploy/maven2/\"\n \ + \ def snapshotsRepoUrl = \"https://oss.sonatype.org/content/repositories/snapshots/\"\ + \n url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl\n\ + \n credentials {\n username ossrhUsername\n \ + \ password ossrhPassword\n }" +- " maven {\n url \"http://developer.huawei.com/repo/\"\n }" +- " maven {\n url \"http://dl.bintray.com/dasar/maven\"\n }" +- " maven {\n url \"http://dl.bintray.com/jenzz/maven\"\n }" +- " maven {\n url \"http://dl.bintray.com/journeyapps/maven\"\n \ + \ }" +- " maven {\n url \"http://dl.bintray.com/lukaville/maven\"\n }" +- " maven {\n url \"http://dl.bintray.com/ona/kujaku\"\n }" +- " maven {\n url \"http://dl.bintray.com/piasy/maven\"\n content\ + \ {\n includeGroupByRegex \"com\\\\.github\\\\.piasy\"\n \ + \ }" +- " maven {\n url \"http://kotlin.bintray.com/kotlin-dev\"\n \ + \ content {\n excludeGroup(\"Kotlin/Native\")\n }" +- " maven {\n url \"http://oss.sonatype.org/content/repositories/snapshots\"\ + \n }" +- " maven {\n url \"https://clojars.org/repo/\"\n }" +- " maven {\n url \"https://dl.bintray.com/kotlin/ktor\"\n content\ + \ {\n excludeGroup(\"Kotlin/Native\")\n }" +- " maven {\n url \"https://dl.bintray.com/soywiz/soywiz\"\n \ + \ content {\n excludeGroup(\"Kotlin/Native\")\n }" +- " maven {\n url \"https://dl.bintray.com/wire-android/third-party\"\n\ + \ }" +- " maven {\n url \"https://github.com/vector-im/jitsi_libre_maven/raw/master/releases\"\ + \n }" +- " maven {\n url \"https://jitpack.io\"\n\n }" +- " maven {\n url \"https://jitpack.io\"\n content {\n \ + \ // For some reason gradle attempts to get bugsnag from here, which returns\ + \ 522\n // after which gradle just drops jitpack. Exclude so it doesn't\ + \ bother trying.\n excludeGroupByRegex \".*bugsnag.*\"\n \ + \ }" +- " maven {\n url \"https://jitpack.io\"\n content {\n \ + \ excludeGroup(\"Kotlin/Native\")\n }" +- " maven {\n url \"https://jitpack.io\"\n }" +- " maven {\n url \"https://jitpack.io/\"\n }" +- " maven {\n url \"https://kotlin.bintray.com/kotlinx\"\n content\ + \ {\n excludeGroup(\"Kotlin/Native\")\n }" +- " maven {\n url \"https://maven-central-asia.storage-download.googleapis.com/repos/central/data/\"\ + \n }" +- " maven {\n url \"https://maven.fabric.io/public\"\n }" +- " maven {\n url \"https://maven.google.com\"\n name 'Google'\n\ + \ }" +- " maven {\n url \"https://maven.google.com\"\n }" +- " maven {\n url \"https://maven.google.com/\"\n }" +- " maven {\n url \"https://maven.mozilla.org/maven2\"\n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/snapshots\"\ + \n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/snapshots/\"\ + \n }" +- " maven {\n url \"https://plugins.gradle.org/m2/\"\n }" +- " maven {\n url \"https://repo1.maven.org/maven2\"\n jcenter()\n\ + \ }" +- " maven {\n url \"https://s3.amazonaws.com/repo.commonsware.com\"\n \ + \ }" +- " maven {\n url \"https://s3.amazonaws.com/repo.commonsware.com\"\n \ + \ }" +- " maven {\n url \"https://snapshots.maven.mozilla.org/maven2\"\n \ + \ }" +- " maven {\n url '${mavenUrl}" +- " maven {\n url 'http://maven.aliyun.com/nexus/content/repositories/releases/'\n\ + \ }" +- " maven {\n url 'http://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n url 'http://oss.sonatype.org/content/repositories/snapshots/'\n\ + \ }" +- " maven {\n url 'http://www.idescout.com/maven/repo/'\n name\ + \ 'IDEScout, Inc.'\n }" +- " maven {\n url 'http://www.idescout.com/maven/repo/'\n }" +- " maven {\n url 'https://clojars.org/repo'\n }" +- " maven {\n url 'https://dl.bintray.com/alexeydanilov/maven'\n \ + \ }" +- " maven {\n url 'https://dl.bintray.com/drummer-aidan/maven'\n \ + \ }" +- " maven {\n url 'https://dl.bintray.com/kotlin/kotlin-eap'\n \ + \ content {\n excludeGroup(\"Kotlin/Native\")\n }" +- " maven {\n url 'https://github.com/suckgamony/RapidDecoder/raw/master/repository'\n\ + \ }" +- " maven {\n url 'https://github.com/uPhyca/stetho-realm/raw/master/maven-repo'\n\ + \ }" +- " maven {\n url 'https://jitpack.io'\n content {\n \ + \ // Use this repo only for matrix SDK library\n includeGroupByRegex\ + \ \"com\\\\.github\\\\.Bubu\"\n // Also add subgroups, due to SDK\ + \ split into modules\n includeGroupByRegex \"com\\\\.github\\\\.Bubu\\\ + \\.matrix-android-sdk\"\n // And Olm library\n includeGroupByRegex\ + \ \"org\\\\.matrix\\\\.gitlab\\\\.matrix-org\"\n // And PhotoView\n\ + \ includeGroupByRegex \"com\\\\.github\\\\.chrisbanes\"\n \ + \ }" +- " maven {\n url 'https://jitpack.io'\n content {\n \ + \ // Use this repo only for olm library\n includeGroupByRegex\ + \ \"org\\\\.matrix\\\\.gitlab\\\\.matrix-org\"\n // And also for\ + \ FilePicker\n includeGroupByRegex \"com\\\\.github\\\\.jaiselrahman\"\ + \n // And monarchy\n includeGroupByRegex \"com\\\\\ + .github\\\\.Zhuinden\"\n // And ucrop\n includeGroupByRegex\ + \ \"com\\\\.github\\\\.yalantis\"\n // JsonViewer\n \ + \ includeGroupByRegex 'com\\\\.github\\\\.BillCarsonFr'\n }" +- " maven {\n url 'https://jitpack.io'\n }" +- " maven {\n url 'https://jitpack.io/'\n }" +- " maven {\n url 'https://maven.aliyun.com/repository/google'\n \ + \ name 'replace google()'\n }" +- " maven {\n url 'https://maven.aliyun.com/repository/jcenter'\n \ + \ name 'replace jcenter()'\n }" +- " maven {\n url 'https://maven.aliyun.com/repository/public'\n \ + \ name 'replace jcenter() and mavenCentral()'\n }" +- " maven {\n url 'https://maven.fabric.io/public'\n }" +- " maven {\n url 'https://maven.google.com'\n // Alternative\ + \ URL is 'https://dl.google.com/dl/android/maven2/'\n }" +- " maven {\n url 'https://maven.google.com'\n }" +- " maven {\n url 'https://maven.google.com/'\n name 'Google'\n\ + \ }" +- " maven {\n url 'https://maven.google.com/'\n }" +- " maven {\n url 'https://oss.sonatype.org/content/groups/public'\n \ + \ }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots/'\n\ + \ content {\n excludeGroup(\"Kotlin/Native\")\n \ + \ }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots/'\n\ + \ }" +- " maven {\n url 'https://plugins.gradle.org/m2'\n }" +- " maven {\n url 'https://plugins.gradle.org/m2/'\n }" +- " maven {\n url 'https://www.jitpack.io'\n }" +- " maven {\n url rootProject.ext.mavenRepo\n if (!rootProject.ext.mavenRepo.startsWith(\"\ + file\")) {\n credentials {\n username rootProject.ext.mavenUser\n\ + \ password rootProject.ext.mavenPassword\n }" +- " maven {\n url 'https://maven.fabric.io/public'\n }" +- " maven {\n url 'https://maven.google.com/'\n }" +- " maven {\n credentials {\n username System.env.ANDVIANE_USERNAME\n password System.env.ANDVIANE_PASSWORD\n }\n //url 'https://oss.sonatype.org/content/repositories/snapshots'\n url 'https://oss.sonatype.org/service/local/staging/deploy/maven2'\n }" +- " maven {\n // CUTR Releases\n url \"https://github.com/CUTR-at-USF/cutr-mvn-repo/raw/master/snapshots\"\ + \n }" +- " maven {\n // Git project library as local library project (ucrop) - see\ + \ https://jitpack.io/docs/\n url 'https://jitpack.io'\n }" +- " maven {\n // Need manual cleanup for new SNAPSHOT update if same name with\ + \ date change only:\n // Smack official SNAPSHOT repository accepted by F-Droid\n\ + \ url 'https://oss.sonatype.org/content/repositories/snapshots'\n\n \ + \ // Smack custom library for org.igniterealtime - not recognize by F-Droid\n\ + \ // url 'https://igniterealtime.org/repo/'\n\n // Custom library\ + \ for org.jitsi - maven-metadata.xml not compatible\n // Unable to load Maven\ + \ meta-data from https://github.com/jitsi/jitsi-maven-repository/tree/master/snapshots/org/jitsi/ice4j/2.0.0-SNAPSHOT/maven-metadata.xml.\n\ + \ // org.xml.sax.SAXParseException; lineNumber: 44; columnNumber: 91; Attribute\ + \ name \"data-pjax-transient\" associated with an element type \"meta\" must be\ + \ followed by the ' = ' character.\n // url 'https://github.com/jitsi/jitsi-maven-repository/tree/master/snapshots'\n\ + \ }" +- " maven {\n // OBA Releases - for comparator to sort alphanumeric routes\n\ + \ url \"http://nexus.onebusaway.org/nexus/content/repositories/releases\"\ + \n }" +- " maven {\n // TODO: Remove this after support library v24 public release.\n\ + \ url \"$rootDir/prebuilts/fullsdk/extras/android/m2repository\"\n }" +- " maven {\n // This maven repo contains artifacts for Flutter's Android embedding.\n\ + \ url 'http://download.flutter.io'\n }" +- " maven {\n // This maven repo is created when you run `flutter build aar`.\ + \ It contains compiled code\n // and resources for flutter_module itself.\n\ + \ url '../../flutter_module/build/host/outputs/repo'\n }" +- " maven {\n // Used only for PhotoView\n url \"https://jitpack.io\"\ + \n name 'JitPack Github wrapper'\n }" +- " maven {\n // for Amazon Maps\n url uri('../.m2/repository')\n \ + \ }" +- " maven {\n // for testlib\n url \"http://dl.bintray.com/acrowntest/ES_SDK\"\ + \n }" +- " maven {\n //url 'https://maven.google.com/'\n url 'https://jitpack.io'\n\ + \ name 'Google'\n }" +- " maven {\n url \"http://4thline.org/m2\"\n }" +- " maven {\n url \"http://maven.chunyu.mobi/content/groups/public/\"\n \ + \ credentials {\n username maven_user\n password maven_password\n\ + \ }" +- " maven {\n url \"https://dl.google.com/dl/android/maven2/\"\n }" +- " maven {\n url \"https://jitpack.io\"\n }" +- " maven {\n url \"https://maven.fabric.io/public\"\n }" +- " maven {\n url \"https://maven.google.com\"\n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/releases\"\ + \n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/snapshots\"\ + \n }" +- " maven {\n url \"https://repo.eclipse.org/content/repositories/paho-releases/\"\ + \n }" +- " maven {\n url '../..'\n }" +- " maven {\n url 'https://dl.bintray.com/amulyakhare/maven'\n }" +- " maven {\n url 'https://github.com/Goddchen/mvn-repo/raw/master/'\n }" +- " maven {\n url 'https://jitpack.io'\n }" +- " maven {\n url 'https://maven.fabric.io/public'\n }" +- " maven {\n url 'https://maven.google.com'\n // Alternative URL is\ + \ 'https://dl.google.com/dl/android/maven2/'\n url \"https://jitpack.io\"\ + \n }" +- " maven {\n url 'https://maven.google.com'\n }" +- " maven {\n url 'https://maven.google.com/'\n name 'Google'\n }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots/'\n\ + \ }" +- " maven {\n url 'https://raw.githubusercontent.com/felixb/mvn-repo/master'\n\ + \ }" +- " maven {\n url 'third_party/m2'\n }" +- " maven {\n url xwalkMavenRepo\n }" +- " maven {\n url(\"https://maven.fabric.io/public\")\n }" +- " maven {\n url(\"https://oss.sonatype.org/content/repositories/snapshots\"\ + )\n }" +- " maven {\n url \"$buildDir/repo\"\n }" +- " maven {\n url \"https://jitpack.io\"\n }" +- " maven {\n url \"https://maven.google.com\"\n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/snapshots/\"\ + \n }" +- " maven {\n url \"https://plugins.gradle.org/m2/\"\n }" +- " maven {\n url 'http://download.crashlytics.com/maven'\n }" +- " maven {\n url 'https://clojars.org/repo/'\n }" +- " maven {\n url 'https://maven.fabric.io/public'\n }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots/'\n\ + \ }" +- " maven {\n url 'https://raw.github.com/ark/ark/master/releases/'\n }" +- " maven {\n url 'https://raw.github.com/iFixit/ark/master/releases/'\n }" +- " maven {\n setUrl(\"https://plugins.gradle.org/m2/\")\n }" +- " maven {\n url 'https://maven.google.com'\n }" +- ' maven { + + // url "https://jitpack.io" + + // url "https://maven-central.storage.googleapis.com" + + // url "http://repo.spring.io/plugins-release/" + + // }' +- ' maven { url "https://maven.google.com" }' +- ' maven { setUrl("https://www.jitpack.io") }' +- ' maven { url "https://dl.bintray.com/bjoernq/maven" }' +- ' maven { url "https://dl.bintray.com/ligi/maven" }' +- ' maven { url "https://dl.bintray.com/lukaville/maven" }' +- ' maven { url "https://jetbrains.bintray.com/trove4j" }' +- ' maven { url "$rootDir/../node_modules/react-native/android" }' +- ' maven { url "file:///home/snowdream/workspace/git/mvn-repo/releases/" }' +- ' maven { url "file:///home/snowdream/workspace/git/mvn-repo/snapshots/" }' +- ' maven { url "http://dl.bintray.com/arturbosch/code-analysis" }' +- ' maven { url "http://dl.bintray.com/countly/maven" }' +- ' maven { url "http://dl.bintray.com/drummer-aidan/maven" }' +- ' maven { url "http://dl.bintray.com/drummer-aidan/maven/com/afollestad" }' +- ' maven { url "http://dl.bintray.com/lukaville/maven" }' +- ' maven { url "http://dl.bintray.com/mobisystech/maven" }' +- ' maven { url "http://dl.bintray.com/populov/maven" }' +- ' maven { url "http://kotlin.bintray.com/kotlin-dev" }' +- ' maven { url "http://maven.batch.com/release" }' +- ' maven { url "http://objectbox.net/beta-repo/" }' +- ' maven { url "http://oss.sonatype.org/content/repositories/snapshots/" }' +- ' maven { url "http://repo.commonsware.com.s3.amazonaws.com" }' +- ' maven { url "http://repo1.maven.org/maven2" }' +- ' maven { url "http://repository.apache.org/snapshots/" }' +- ' maven { url "http://snowdream.github.io/mvn-repo/releases/" }' +- ' maven { url "http://snowdream.github.io/mvn-repo/snapshots/" }' +- ' maven { url "http://storage.googleapis.com/r8-releases/raw/master" }' +- ' maven { url "https://clojars.org/repo" }' +- ' maven { url "https://clojars.org/repo/" }' +- ' maven { url "https://dl.bintray.com/acra/maven" }' +- ' maven { url "https://dl.bintray.com/asf/asf" }' +- ' maven { url "https://dl.bintray.com/badoo/maven" }' +- ' maven { url "https://dl.bintray.com/dasar/maven" }' +- ' maven { url "https://dl.bintray.com/drummer-aidan/maven" }' +- ' maven { url "https://dl.bintray.com/florent37/maven" }' +- ' maven { url "https://dl.bintray.com/gericop/maven" }' +- ' maven { url "https://dl.bintray.com/kotlin/ktor" }' +- ' maven { url "https://dl.bintray.com/markusamshove/maven" }' +- ' maven { url "https://dl.bintray.com/mockito/maven" }' +- ' maven { url "https://dl.bintray.com/robstoll/tutteli-jars" }' +- ' maven { url "https://dl.bintray.com/videolan/Android" }' +- ' maven { url "https://dl.bintray.com/wire-android/releases" }' +- ' maven { url "https://dl.bintray.com/wire-android/releases/" }' +- ' maven { url "https://dl.bintray.com/wire-android/snapshots" }' +- ' maven { url "https://dl.bintray.com/wire-android/snapshots/" }' +- ' maven { url "https://dl.bintray.com/wire-android/third-party" }' +- ' maven { url "https://dl.bintray.com/wire-android/third-party/" }' +- ' maven { url "https://dl.bintray.com/wordpress-mobile/maven" }' +- ' maven { url "https://dl.bintray.com/wordpress-mobile/react-native-mirror/" }' +- ' maven { url "https://fusesource.github.io/jansi/" }' +- ' maven { url "https://giphy.bintray.com/giphy-sdk" }' +- ' maven { url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases" + }' +- ' maven { url "https://jcenter.bintray.com" }' +- " maven { url \"https://jitpack.io\"\n }" +- ' maven { url "https://jitpack.io" }' +- ' maven { url "https://jitpack.io"}' +- ' maven { url "https://kotlin.bintray.com/kotlinx" }' +- ' maven { url "https://mapbox.bintray.com/mapbox" }' +- ' maven { url "https://maven-central-asia.storage-download.googleapis.com/repos/central/data/" + }' +- ' maven { url "https://maven.fabric.io/public" }' +- " maven { url \"https://maven.google.com\"\n }" +- ' maven { url "https://maven.google.com" }' +- ' maven { url "https://maven.google.com"}' +- ' maven { url "https://maven.google.com/" }' +- ' maven { url "https://oss.sonatype.org/content/groups/public" }' +- ' maven { url "https://oss.sonatype.org/content/groups/public/" }' +- ' maven { url "https://oss.sonatype.org/content/repositories/releases/" }' +- ' maven { url "https://oss.sonatype.org/content/repositories/snapshots" }' +- ' maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }' +- ' maven { url "https://plugins.gradle.org/m2" }' +- ' maven { url "https://plugins.gradle.org/m2/" }' +- ' maven { url "https://plugins.gradle.org/m2/"}' +- ' maven { url "https://raw.githubusercontent.com/guardianproject/gpmaven/master" + }' +- ' maven { url "https://repo.commonsware.com.s3.amazonaws.com" }' +- ' maven { url "https://repo.eclipse.org/content/groups/releases" }' +- ' maven { url "https://repo.maven.apache.org/maven2" }' +- ' maven { url "https://repo1.maven.org/maven2/" }' +- ' maven { url "https://s3.amazonaws.com/moat-sdk-builds" }' +- ' maven { url "https://s3.amazonaws.com/repo.commonsware.com" }' +- ' maven { url "https://www.jitpack.io" }' +- ' maven { url ''file:///usr/share/maven-repo'' }' +- ' maven { url ''http://dl.bintray.com/amulyakhare/maven'' }' +- ' maven { url ''http://download.crashlytics.com/maven'' }' +- ' maven { url ''http://guardian.github.com/maven/repo-releases'' }' +- ' maven { url ''http://igniterealtime.org/repo'' }' +- ' maven { url ''http://maven.ghostscript.com/'' }' +- ' maven { url ''http://nexus.testobject.org/nexus/content/repositories/testobject-public-alpha-repo'' + }' +- ' maven { url ''http://oss.sonatype.org/content/repositories/snapshots'' }' +- ' maven { url ''http://repo1.maven.org/maven2'' }' +- ' maven { url ''http://wordpress-mobile.github.io/WordPress-Android'' }' +- ' maven { url ''https://dl.bintray.com/badoo/maven'' }' +- ' maven { url ''https://dl.bintray.com/content/simonpoole/android'' }' +- ' maven { url ''https://dl.bintray.com/content/simonpoole/div'' }' +- ' maven { url ''https://dl.bintray.com/content/simonpoole/osm'' }' +- ' maven { url ''https://dl.bintray.com/florent37/maven'' }' +- ' maven { url ''https://dl.bintray.com/intercom/intercom-maven'' }' +- ' maven { url ''https://dl.bintray.com/jenly/maven'' }' +- ' maven { url ''https://dl.bintray.com/jetbrains/anko'' }' +- ' maven { url ''https://dl.bintray.com/kotlin/kotlin-eap'' }' +- ' maven { url ''https://dl.bintray.com/twofortyfouram/maven'' }' +- ' maven { url ''https://dl.bintray.com/umsdk/release'' }' +- ' maven { url ''https://dl.google.com/dl/android/maven2/'' }' +- ' maven { url ''https://github.com/FireZenk/maven-repo/raw/master/'' }' +- ' maven { url ''https://github.com/uPhyca/stetho-realm/raw/master/maven-repo'' }' +- ' maven { url ''https://guardian.github.com/maven/repo-releases'' }' +- ' maven { url ''https://igniterealtime.org/repo'' }' +- ' maven { url ''https://jitpack.io'' }' +- ' maven { url ''https://jitpack.io/'' }' +- ' maven { url ''https://maven.fabric.io/public'' }' +- ' maven { url ''https://maven.fabric.io/repo'' }' +- ' maven { url ''https://maven.google.com'' }' +- ' maven { url ''https://maven.google.com/'' }' +- ' maven { url ''https://oss.jfrog.org/artifactory/oss-snapshot-local/'' }' +- ' maven { url ''https://oss.sonatype.org/content/repositories/releases/'' }' +- ' maven { url ''https://oss.sonatype.org/content/repositories/snapshots'' }' +- ' maven { url ''https://oss.sonatype.org/content/repositories/snapshots/'' }' +- ' maven { url ''https://plugins.gradle.org/m2/'' }' +- ' maven { url ''https://plugins.gradle.org/m2/''}' +- ' maven { url ''https://repo1.maven.org/maven2'' }' +- ' maven { url ''https://repos.zeroturnaround.com/nexus/content/repositories/zt-public-releases'' + }' +- ' maven { url ''https://repository-achartengine.forge.cloudbees.com/snapshot/'' + }' +- ' maven { url ''https://s3.amazonaws.com/repo.commonsware.com'' }' +- ' maven { url ''https://www.jitpack.io'' }' +- ' maven { url ''https://zendesk.jfrog.io/zendesk/repo'' }' +- ' maven { url ''libs'' }' +- ' maven { url = "https://storage.googleapis.com/r8-releases/raw" }' +- ' maven { url = uri("https://jitpack.io") }' +- ' maven { url = uri("https://maven.fabric.io/public") }' +- ' maven { url MAVEN_REPO_CACHE }' +- ' maven { url(''http://releases.marmeladburk.fidesmo.com/'') }' +- ' maven {url "http://dl.bintray.com/tbruyelle/tbruyelle" }' +- ' maven {url "https://jitpack.io"}' +- ' maven {url ''http://maven.aliyun.com/nexus/content/groups/public/''}' +- " maven{\n url 'https://maven.fabric.io/public'\n }" +- " maven{\n url'https://plugins.gradle.org/m2/'\n }" +- " maven{\n url \"https://maven.google.com\"\n }" +- " maven{\n url 'https://maven.google.com'\n }" +- ' maven{ url "https://oss.sonatype.org/content/repositories/releases/" }' +- ' maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" }' +- ' maven{ url ''http://maven.aliyun.com/nexus/content/groups/public/''}' +- ' maven{ url ''https://jitpack.io'' }' +- ' maven{ url ''https://maven.aliyun.com/repository/google'' }' +- ' maven{ url ''https://maven.aliyun.com/repository/google''}' +- ' maven{ url ''https://maven.aliyun.com/repository/gradle-plugin''}' +- ' maven{ url ''https://maven.aliyun.com/repository/jcenter'' }' +- ' maven{ url ''https://maven.aliyun.com/repository/jcenter''}' +- ' maven{ url ''https://maven.aliyun.com/repository/public''}' +- ' maven{url "https://plugins.gradle.org/m2/"}' +- ' maven{url ''http://maven.aliyun.com/nexus/content/groups/public''}' +- "\tmaven {\n\t\t\t\turl \"https://oss.sonatype.org/content/repositories/snapshots\"\ + \n\t\t\t}" +- "\tmaven {\n\t\t\turl \"$rootDir/../node_modules/react-native-background-fetch/android/libs\"\ + \n\t\t}" +- "\tmaven {\n\t\t\turl \"https://jitpack.io\"\n\t\t}" +- "\tmaven {\n\t\t\turl \"https://plugins.gradle.org/m2/\"\n\t\t}" +- "\tmaven {\n\t\t\turl 'http://4thline.org/m2'\n\t\t}" +- "\tmaven {\n\t\t\turl 'https://maven.google.com/'\n\t\t\tname 'Google'\n\t\t}" +- "\tmaven {\n\t\t\turl 'https://plugins.gradle.org/m2/'\n\t\t}" +- "\tmaven {\n\t\turl \"file://$pwd/.m2repo\"\n\t}" +- "\tmaven {\n\t\turl \"https://jitpack.io\"\n\t}" +- "\tmaven {\n\t\turl 'https://maven.google.com/'\n\t\tname 'Google'\n\t}" +- "\tmaven {\n // Google Maven Repository\n url 'https://maven.google.com'\n\ + \ }" +- "\tmaven { url \"http://dl.bintray.com/populov/maven\" }" +- "\tmaven { url \"https://jitpack.io\" }" +- "\tmaven { url 'http://download.crashlytics.com/maven' }" +- "\tmaven { url 'http://maven.ghostscript.com/' }" +- "\tmaven { url 'https://jitpack.io' }" +- "\tmaven { url 'https://maven.fabric.io/public' }" +- "\tmaven { url MAVEN_REPO }" +- ' maven { url "http://repo1.maven.org/maven2" }' +- " maven {\n\t url 'https://jitpack.io'\n }" +- " maven {\n\t url System.getenv()['ANDROID_HOME'] + \"/extras/android/m2repository\"\ + \n }" +- " maven {\n url \"$buildDir/repo\"\n }" +- " maven {\n url \"file:~/.m2/\"\n artifactUrls \"\ + file:~/.m2/\"\n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/snapshots\"\ + \n }" +- " maven {\n url \"https://plugins.gradle.org/m2/\"\n }" +- " maven {\n url 'https://maven.fabric.io/public'\n }" +- " maven {\n url repository\n }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n // url \"$rootDir/../node_modules/react-native/android\"\ + \n\n // Replace AAR from original RN with AAR from react-native-v8\n\ + \ url(\"$rootDir/../node_modules/react-native-v8/dist\")\n }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n url \"$projectDir/../../node_modules/react-native/android\"\ + \n }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n url \"$projectDir/../../tests/react-test-app/node_modules/react-native/android\"\ + \n }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n url \"$rootDir/../node_modules/react-native/android\"\ + \n }" +- " maven {\n // All of React Native (JS, Obj-C sources, Android binaries)\ + \ is installed from npm\n url(\"$rootDir/../node_modules/react-native/android\"\ + )\n }" +- " maven {\n // Android JSC is installed from npm\n url(\"\ + $rootDir/../node_modules/jsc-android/dist\")\n }" +- " maven {\n // Local Maven repo containing AARs with JSC library built\ + \ for Android\n // url \"$rootDir/../node_modules/jsc-android/dist\"\n\ + \n // prebuilt libv8android.so\n url(\"$rootDir/../node_modules/v8-android/dist\"\ + )\n }" +- " maven {\n //noinspection GroovyAssignabilityCheck\n url\ + \ 'https://jitpack.io'\n }" +- " maven {\n //noinspection GroovyAssignabilityCheck\n url\ + \ 'https://s3.amazonaws.com/moat-sdk-builds'\n }" +- " maven {\n //url 'https://maven.google.com/'\n url 'https://jitpack.io'\n\ + \ name 'Google'\n }" +- " maven {\n name 'glide-snapshot'\n url 'http://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n url \"http://dl.bintray.com/countly/maven\"\n }" +- " maven {\n url \"./maven_repository/\"\n }" +- " maven {\n url \"http://dl.bintray.com/dasar/maven\"\n }" +- " maven {\n url \"http://dl.bintray.com/jenzz/maven\"\n }" +- " maven {\n url \"http://dl.bintray.com/journeyapps/maven\"\n \ + \ }" +- " maven {\n url \"http://dl.bintray.com/lukaville/maven\"\n }" +- " maven {\n url \"https://clojars.org/repo/\"\n }" +- " maven {\n url \"https://dl.bintray.com/videolan/Android\"\n \ + \ }" +- " maven {\n url \"https://github.com/jitsi/jitsi-maven-repository/raw/master/releases\"\ + \n }" +- " maven {\n url \"https://github.com/vector-im/jitsi_libre_maven/raw/master/releases\"\ + \n }" +- " maven {\n url \"https://jcenter.bintray.com\"\n }" +- " maven {\n url \"https://jitpack.io\"\n\n }" +- " maven {\n url \"https://jitpack.io\"\n content {\n \ + \ // For some reason gradle attempts to get bugsnag from here, which returns\ + \ 522\n // after which gradle just drops jitpack. Exclude so it doesn't\ + \ bother trying.\n excludeGroupByRegex \".*bugsnag.*\"\n \ + \ }" +- " maven {\n url \"https://jitpack.io\"\n }" +- " maven {\n url \"https://jitpack.io/\"\n }" +- " maven {\n url \"https://maven.fabric.io/public\"\n }" +- " maven {\n url \"https://maven.google.com\"\n name 'Google'\n\ + \ }" +- " maven {\n url \"https://maven.google.com\"\n }" +- " maven {\n url \"https://maven.google.com/\"\n name 'Google'\n\ + \ }" +- " maven {\n url \"https://maven.mozilla.org/maven2\"\n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/snapshots\"\ + \n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/snapshots/\"\ + \n }" +- " maven {\n url \"https://plugins.gradle.org/m2/\"\n }" +- " maven {\n url \"https://repo1.maven.org/maven2\"\n jcenter()\n\ + \ }" +- " maven {\n url \"https://repo1.maven.org/maven2\"\n }" +- " maven {\n url \"https://s3.amazonaws.com/repo.commonsware.com\"\n \ + \ }" +- " maven {\n url \"https://s3.amazonaws.com/repo.commonsware.com\"\n \ + \ }" +- " maven {\n url 'http://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n url 'http://oss.sonatype.org/content/repositories/snapshots/'\n\ + \ }" +- " maven {\n url 'http://www.idescout.com/maven/repo/'\n name\ + \ 'IDEScout, Inc.'\n }" +- " maven {\n url 'https://github.com/suckgamony/RapidDecoder/raw/master/repository'\n\ + \ }" +- " maven {\n url 'https://jitpack.io'\n content {\n \ + \ // Use this repo only for matrix SDK library\n includeGroupByRegex\ + \ \"com\\\\.github\\\\.Bubu\"\n // Also add subgroups, due to SDK\ + \ split into modules\n includeGroupByRegex \"com\\\\.github\\\\.Bubu\\\ + \\.matrix-android-sdk\"\n // And Olm library\n includeGroupByRegex\ + \ \"org\\\\.matrix\\\\.gitlab\\\\.matrix-org\"\n // And PhotoView\n\ + \ includeGroupByRegex \"com\\\\.github\\\\.chrisbanes\"\n \ + \ }" +- " maven {\n url 'https://jitpack.io'\n content {\n \ + \ // Use this repo only for matrix SDK library\n includeGroupByRegex\ + \ \"com\\\\.github\\\\.matrix-org\"\n // Also add subgroups, due\ + \ to SDK split into modules\n includeGroupByRegex \"com\\\\.github\\\ + \\.matrix-org\\\\.matrix-android-sdk\"\n // And Olm library\n \ + \ includeGroupByRegex \"org\\\\.matrix\\\\.gitlab\\\\.matrix-org\"\n\ + \ // And PhotoView\n includeGroupByRegex \"com\\\\\ + .github\\\\.chrisbanes\"\n }" +- " maven {\n url 'https://jitpack.io'\n }" +- " maven {\n url 'https://maven.fabric.io/public'\n }" +- " maven {\n url 'https://maven.google.com'\n }" +- " maven {\n url 'https://maven.google.com/'\n name 'Google'\n\ + \ }" +- " maven {\n url 'https://maven.google.com/'\n }" +- " maven {\n url 'https://mint.splunk.com/gradle/'\n }" +- " maven {\n url 'https://oss.sonatype.org/content/groups/public'\n \ + \ }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots/'\n\ + \ }" +- " maven {\n url 'https://plugins.gradle.org/m2/'\n }" +- " maven {\n url 'https://www.jitpack.io'\n }" +- " maven {\n url = \"${project.buildDir}" +- " maven {\n url(\"$rootDir/../node_modules/jsc-android/dist\")\n \ + \ }" +- " maven {\n url(\"$rootDir/../node_modules/react-native/android\")\n\ + \ }" +- " maven {\n // For the latest version of GeckoView (moving target!) use:\n\ + \ // https://index.taskcluster.net/v1/task/gecko.v2.mozilla-central.nightly.latest.mobile.android-api-16-opt/artifacts/public/android/maven\n\ + \ //\n // For discovering available versions go to:\n // \ + \ https://tools.taskcluster.net/index/gecko.v2.mozilla-central.nightly\n\n \ + \ // ARM GeckoView builds\n url \"https://index.taskcluster.net/v1/task/gecko.v2.mozilla-central.nightly\"\ + \ +\n \".${geckoview_nightly_date}" +- " maven {\n // Replace snapshots by releases for releases !\n url\ + \ \"https://linphone.org/snapshots/maven_repository\"\n }" +- " maven {\n // Switch to release for releases !\n url \"https://gitlab.linphone.org/BC/public/maven_repository/raw/master\"\ + \n }" +- " maven {\n // TODO: Remove this after support library v24 public release.\n\ + \ url \"$rootDir/prebuilts/fullsdk/extras/android/m2repository\"\n }" +- " maven {\n // Used only for PhotoView\n url \"https://jitpack.io\"\ + \n name 'JitPack Github wrapper'\n }" +- " maven {\n // aarch64 builds\n url \"https://index.taskcluster.net/v1/task/gecko.v2.mozilla-central.nightly\"\ + \ +\n \".${geckoview_nightly_date}" +- " maven {\n // x86 GeckoView builds\n url \"https://index.taskcluster.net/v1/task/gecko.v2.mozilla-central.nightly\"\ + \ +\n \".${geckoview_nightly_date}" +- " maven {\n //url 'https://maven.google.com/'\n url 'https://jitpack.io'\n\ + \ name 'Google'\n }" +- " maven {\n url \"http://4thline.org/m2\"\n }" +- " maven {\n url \"http://dl.bintray.com/lukaville/maven\"\n }" +- " maven {\n url \"https://dl.google.com/dl/android/maven2/\"\n }" +- " maven {\n url \"https://jitpack.io\"\n }" +- " maven {\n url \"https://linphone.org/maven_repository\"\n }" +- " maven {\n url \"https://maven.fabric.io/public\"\n }" +- " maven {\n url \"https://maven.google.com\"\n }" +- " maven {\n url \"https://oss.sonatype.org/content/repositories/snapshots\"\ + \n }" +- " maven {\n url \"https://repo.commonsware.com.s3.amazonaws.com\"\n }" +- " maven {\n url \"https://repo1.maven.org/maven2/\"\n }" +- " maven {\n url 'http://4thline.org/m2'\n }" +- " maven {\n url 'http://dl.bintray.com/amulyakhare/maven'\n }" +- " maven {\n url 'https://dl.bintray.com/amulyakhare/maven'\n }" +- " maven {\n url 'https://github.com/Goddchen/mvn-repo/raw/master/'\n }" +- " maven {\n url 'https://github.com/toxbee/mvn-repo/raw/master/maven-deploy'\n\ + \ }" +- " maven {\n url 'https://jitpack.io'\n }" +- " maven {\n url 'https://maven.fabric.io/public'\n }" +- " maven {\n url 'https://maven.google.com'\n // Alternative URL is\ + \ 'https://dl.google.com/dl/android/maven2/'\n url \"https://jitpack.io\"\ + \n }" +- " maven {\n url 'https://maven.google.com'\n }" +- " maven {\n url 'https://maven.google.com/'\n name 'Google'\n }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots'\n\ + \ }" +- " maven {\n url 'https://oss.sonatype.org/content/repositories/snapshots/'\n\ + \ }" +- " maven {\n url 'https://raw.github.com/nicolasjafelle/maven-repo/master/'\n\ + \ }" +- " maven {\n url 'https://raw.githubusercontent.com/felixb/mvn-repo/master'\n\ + \ }" +- " maven {\n url xwalkMavenRepo\n }" +- " maven {\n url \"https://github.com/Goddchen/mvn-repo/raw/master/\"\n }" +- " maven {\n url \"https://github.com/dahlgren/abs-aar/raw/master\"\n }" +- " maven {\n url \"https://jcenter.bintray.com\"\n }" +- " maven {\n url \"https://repo.commonsware.com.s3.amazonaws.com\"\n }" +- " maven {\n url 'http://download.crashlytics.com/maven'\n }" +- " maven {\n url 'https://maven.google.com/'\n name 'Google'\n }" +- " maven {\n url 'https://raw.github.com/ark/ark/master/releases/'\n }" +- " maven {\n url 'https://raw.github.com/iFixit/ark/master/releases/'\n }" +- " maven {\n setUrl(\"https://plugins.gradle.org/m2/\")\n }" +- " maven {\n url 'https://maven.google.com'\n }" +- ' maven { + + // url "https://jitpack.io" + + // url "https://maven-central.storage.googleapis.com" + + // url "http://repo.spring.io/plugins-release/" + + // }' +- ' maven { url "https://maven.google.com" }' +- ' maven { setUrl("https://plugins.gradle.org/m2/") }' +- ' maven { setUrl("https://www.jitpack.io") }' +- ' maven { url "http://dl.bintray.com/dasar/maven" }' +- ' maven { url "https://dl.bintray.com/bjoernq/maven" }' +- ' maven { url "https://dl.bintray.com/ligi/maven" }' +- ' maven { url "https://dl.bintray.com/lukaville/maven" }' +- ' maven { url "https://jetbrains.bintray.com/trove4j" }' +- ' maven { url "$rootDir/../node_modules/react-native/android" }' +- ' maven { url "file:${rootProject.projectDir}' +- ' maven { url "http://dl.bintray.com/amulyakhare/maven" }' +- ' maven { url "http://dl.bintray.com/arturbosch/code-analysis" }' +- ' maven { url "http://dl.bintray.com/countly/maven" }' +- ' maven { url "http://dl.bintray.com/davideas/maven" }' +- ' maven { url "http://dl.bintray.com/drummer-aidan/maven" }' +- ' maven { url "http://dl.bintray.com/drummer-aidan/maven/com/afollestad" }' +- ' maven { url "http://dl.bintray.com/lukaville/maven" }' +- ' maven { url "http://dl.bintray.com/populov/maven" }' +- ' maven { url "http://objectbox.net/beta-repo/" }' +- ' maven { url "http://repo.commonsware.com.s3.amazonaws.com" }' +- ' maven { url "http://repo.maven.apache.org/maven2" }' +- ' maven { url "https://clojars.org/repo" }' +- ' maven { url "https://clojars.org/repo/" }' +- ' maven { url "https://dl.bintray.com/android/android-tools/" }' +- ' maven { url "https://dl.bintray.com/drummer-aidan/maven" }' +- ' maven { url "https://dl.bintray.com/markusamshove/maven" }' +- ' maven { url "https://dl.bintray.com/mockito/maven/" }' +- ' maven { url "https://dl.bintray.com/osborn/Android" }' +- ' maven { url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases" + }' +- ' maven { url "https://jcenter.bintray.com" }' +- " maven { url \"https://jitpack.io\"\n }" +- ' maven { url "https://jitpack.io" }' +- ' maven { url "https://jitpack.io"}' +- ' maven { url "https://kotlin.bintray.com/kotlinx" }' +- ' maven { url "https://maven.fabric.io/public" }' +- " maven { url \"https://maven.google.com\"\n }" +- ' maven { url "https://maven.google.com" }' +- ' maven { url "https://maven.google.com"}' +- ' maven { url "https://maven.google.com/" }' +- ' maven { url "https://oss.sonatype.org/content/groups/public" }' +- ' maven { url "https://oss.sonatype.org/content/groups/public/" }' +- ' maven { url "https://oss.sonatype.org/content/repositories/releases/" }' +- ' maven { url "https://oss.sonatype.org/content/repositories/snapshots" }' +- ' maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }' +- ' maven { url "https://plugins.gradle.org/m2" }' +- ' maven { url "https://plugins.gradle.org/m2/" }' +- ' maven { url "https://plugins.gradle.org/m2/"}' +- ' maven { url "https://repo.commonsware.com.s3.amazonaws.com" }' +- ' maven { url "https://repo.commonsware.com.s3.amazonaws.com"}' +- ' maven { url "https://repo.eclipse.org/content/groups/releases" }' +- ' maven { url "https://repo.maven.apache.org/maven2" }' +- ' maven { url "https://repository.aspose.com/repo/" }' +- ' maven { url "https://s3.amazonaws.com/repo.commonsware.com" }' +- ' maven { url "https://www.jitpack.io" }' +- ' maven { url ''../../prebuilts/gradle-plugin'' }' +- ' maven { url ''../../prebuilts/tools/common/m2/internal'' }' +- ' maven { url ''../../prebuilts/tools/common/m2/repository'' }' +- ' maven { url ''file:///usr/share/maven-repo'' }' +- ' maven { url ''http://dl.bintray.com/amulyakhare/maven'' }' +- ' maven { url ''http://download.crashlytics.com/maven'' }' +- ' maven { url ''http://guardian.github.com/maven/repo-releases'' }' +- ' maven { url ''http://igniterealtime.org/repo'' }' +- ' maven { url ''http://repo1.maven.org/maven2'' }' +- ' maven { url ''http://wordpress-mobile.github.io/WordPress-Android'' }' +- ' maven { url ''https://dl.bintray.com/content/simonpoole/android'' }' +- ' maven { url ''https://dl.bintray.com/content/simonpoole/div'' }' +- ' maven { url ''https://dl.bintray.com/content/simonpoole/osm'' }' +- ' maven { url ''https://dl.bintray.com/twofortyfouram/maven'' }' +- ' maven { url ''https://dl.google.com/dl/android/maven2/'' }' +- ' maven { url ''https://guardian.github.com/maven/repo-releases'' }' +- ' maven { url ''https://igniterealtime.org/repo'' }' +- ' maven { url ''https://jitpack.io'' }' +- ' maven { url ''https://jitpack.io/'' }' +- ' maven { url ''https://maven.fabric.io/public'' }' +- ' maven { url ''https://maven.fabric.io/repo'' }' +- ' maven { url ''https://maven.google.com'' }' +- ' maven { url ''https://maven.google.com''}' +- ' maven { url ''https://maven.google.com/'' }' +- ' maven { url ''https://oss.jfrog.org/artifactory/oss-snapshot-local/'' }' +- ' maven { url ''https://oss.sonatype.org/content/repositories/snapshots'' }' +- ' maven { url ''https://oss.sonatype.org/content/repositories/snapshots/'' }' +- ' maven { url ''https://plugins.gradle.org/m2/'' }' +- ' maven { url ''https://repo1.maven.org/maven2'' /*maven-central with HTTPS*/}' +- ' maven { url ''https://repo1.maven.org/maven2'' }' +- ' maven { url ''https://repository-achartengine.forge.cloudbees.com/snapshot/'' + }' +- ' maven { url ''https://s3.amazonaws.com/repo.commonsware.com'' }' +- ' maven { url ''https://www.jitpack.io'' }' +- ' maven { url ''libs'' }' +- ' maven { url = uri("https://jitpack.io") }' +- ' maven { url = uri("https://maven.fabric.io/public") }' +- ' maven { url MAVEN_REPO_CACHE }' +- ' maven { url(''http://releases.marmeladburk.fidesmo.com/'') }' +- ' maven {url "http://dl.bintray.com/tbruyelle/tbruyelle" }' +- ' maven {url "https://clojars.org/repo/"}' +- ' maven {url "https://jitpack.io"}' +- " maven{\n url 'https://maven.fabric.io/public'\n }" +- " maven{\n url'https://plugins.gradle.org/m2/'\n }" +- " maven{\n url \"https://maven.google.com\"\n }" +- ' maven{ url "https://oss.sonatype.org/content/repositories/releases/" }' +- ' maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" }' +- ' maven{ url ''https://jitpack.io'' }' +- ' maven{ url ''https://maven.aliyun.com/repository/google''}' +- ' maven{ url ''https://maven.aliyun.com/repository/gradle-plugin''}' +- ' maven{ url ''https://maven.aliyun.com/repository/jcenter''}' +- ' maven{ url ''https://maven.aliyun.com/repository/public''}' +- ' maven{url "https://jitpack.io"}' +- ' maven{url "https://plugins.gradle.org/m2/"}' diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 354c2f64..67cef2fd 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -11,6 +11,7 @@ import tempfile import textwrap import unittest import uuid +import yaml from unittest import mock localmodule = os.path.realpath( @@ -82,6 +83,27 @@ class ScannerTest(unittest.TestCase): i += 1 self.assertEqual(count, i) + def test_scan_source_files_sneaky_maven(self): + """Check for sneaking in banned maven repos""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + fdroidserver.scanner.config = None + fdroidserver.scanner.options = mock.Mock() + fdroidserver.scanner.options.json = True + with open('build.gradle', 'w') as fp: + fp.write(textwrap.dedent(""" + maven { + "https://jitpack.io" + url 'https://maven.fabric.io/public' + } + maven { + "https://maven.google.com" + setUrl('https://evilcorp.com/maven') + } + """)) + count = fdroidserver.scanner.scan_source(testdir) + self.assertEqual(2, count, 'there should be this many errors') + def test_scan_source_file_types(self): """Build product files are not allowed, test they are detected""" testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) @@ -221,6 +243,20 @@ class ScannerTest(unittest.TestCase): self.assertTrue(os.path.exists('foo.aar')) self.assertFalse(os.path.exists('gradle-wrapper.jar')) + def test_gradle_maven_url_regex(self): + """Check the regex can find all the cases""" + with open(os.path.join(self.basedir, 'gradle-maven-blocks.yaml')) as fp: + data = yaml.safe_load(fp) + + urls = [] + for entry in data: + found = False + for m in fdroidserver.scanner.MAVEN_URL_REGEX.findall(entry): + urls.append(m) + found = True + self.assertTrue(found, 'this block should produce a URL:\n' + entry) + self.assertEqual(len(data), len(urls), 'each data example should produce a URL') + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 0216513da6deb3b1ee42768827b3c4fde3cdddb0 Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Wed, 10 Jun 2020 15:55:53 -0400 Subject: [PATCH 0357/2775] Upgrade NDK r21c to r21d --- buildserver/config.buildserver.py | 2 +- buildserver/provision-android-ndk | 2 +- examples/config.py | 2 +- makebuildserver | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py index ce848482..e09188ec 100644 --- a/buildserver/config.buildserver.py +++ b/buildserver/config.buildserver.py @@ -11,7 +11,7 @@ ndk_paths = { 'r18b': "/home/vagrant/android-ndk/r18b", 'r19c': "/home/vagrant/android-ndk/r19c", 'r20b': "/home/vagrant/android-ndk/r20b", - 'r21c': "/home/vagrant/android-ndk/r21c", + 'r21d': "/home/vagrant/android-ndk/r21d", } java_paths = { '8': "/usr/lib/jvm/java-8-openjdk-amd64", diff --git a/buildserver/provision-android-ndk b/buildserver/provision-android-ndk index 69bfd7d5..c241bab3 100644 --- a/buildserver/provision-android-ndk +++ b/buildserver/provision-android-ndk @@ -15,7 +15,7 @@ if [ ! -e $NDK_BASE/r10e ]; then mv android-ndk-r10e r10e fi -for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21c; do +for version in r11c r12b r13b r14b r15c r16b r17c r18b r19c r20b r21d; do if [ ! -e ${NDK_BASE}/${version} ]; then unzip /vagrant/cache/android-ndk-${version}-linux-x86_64.zip > /dev/null mv android-ndk-${version} ${version} diff --git a/examples/config.py b/examples/config.py index 77edf2b6..e5735591 100644 --- a/examples/config.py +++ b/examples/config.py @@ -22,7 +22,7 @@ # 'r18b': None, # 'r19c': None, # 'r20b': None, -# 'r21c': None, +# 'r21d': None, # } # Directory to store downloaded tools in (i.e. gradle versions) diff --git a/makebuildserver b/makebuildserver index a73fab7a..402a3dde 100755 --- a/makebuildserver +++ b/makebuildserver @@ -396,8 +396,8 @@ CACHE_FILES = [ '4c62514ec9c2309315fd84da6d52465651cdb68605058f231f1e480fcf2692e1'), ('https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip', '8381c440fe61fcbb01e209211ac01b519cd6adf51ab1c2281d5daad6ca4c8c8c'), - ('https://dl.google.com/android/repository/android-ndk-r21c-linux-x86_64.zip', - '214ebfcfa5108ba78f5b2cc8db4d575068f9c973ac7f27d2fa1987dfdb76c9e7'), + ('https://dl.google.com/android/repository/android-ndk-r21d-linux-x86_64.zip', + 'dd6dc090b6e2580206c64bcee499bc16509a5d017c6952dcd2bed9072af67cbd'), ] From 07992177bfe267153c7f23588bc5ae89b3b0a9f7 Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Wed, 10 Jun 2020 15:59:04 -0400 Subject: [PATCH 0358/2775] Add build tools 30.0.0 --- makebuildserver | 2 ++ 1 file changed, 2 insertions(+) diff --git a/makebuildserver b/makebuildserver index 402a3dde..3600422a 100755 --- a/makebuildserver +++ b/makebuildserver @@ -258,6 +258,8 @@ CACHE_FILES = [ '1e9393cbfd4a4b82e30e7f55ab38db4a5a3259db93d5821c63597bc74522fa08'), ('https://dl.google.com/android/repository/build-tools_r29.0.3-linux.zip', '5652d8cd5eaaade0b853bfe0ae6cbfa0706a6f70a0ebb25ca24a6f484ec3d855'), + ('https://dl.google.com/android/repository/build-tools_r30-linux.zip', + 'ed3b7f9b2d15e90a12c2e739adb749d7d834e2f953e677380206bd14db135c6c'), ('https://services.gradle.org/distributions/gradle-2.2.1-bin.zip', '420aa50738299327b611c10b8304b749e8d3a579407ee9e755b15921d95ff418'), ('https://services.gradle.org/distributions/gradle-2.3-bin.zip', From 294799e2f55217e66ddc783e61cef2b5bb26053d Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 11 Jun 2020 11:43:27 +0200 Subject: [PATCH 0359/2775] scanner: fix options handling closes fdroid/fdroidserver#789 --- fdroidserver/scanner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 1c30d189..ad33de13 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -176,9 +176,9 @@ def scan_source(build_dir, build=metadata.Build()): return removeproblem(what, path_in_build_dir, filepath) if 'src/test' in filepath or '/test/' in filepath: return warnproblem(what, path_in_build_dir) - if options and options.json: + if options and 'json' in vars(options) and options.json: json_per_build['errors'].append([what, path_in_build_dir]) - if options and (options.verbose or not options.json): + if options and (options.verbose or not ('json' in vars(options) and options.json)): logging.error('Found %s at %s' % (what, path_in_build_dir)) return 1 From 72fde0f10b26f36a7dad536b39a14394d2b2eace Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Thu, 11 Jun 2020 16:36:54 +0300 Subject: [PATCH 0360/2775] Detect .gitmodules and add submodules build line --- fdroidserver/import.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index 5a313bf8..a6098202 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -191,6 +191,10 @@ def main(): '$$flutter$$/bin/flutter build apk', ] + git_modules = os.path.join(tmp_importer_dir, '.gitmodules') + if os.path.exists(git_modules): + build.submodules = True + metadata.post_metadata_parse(app) app.builds.append(build) From 3a9f1e845c8b835e210bcc4d8affb326e22b7583 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Sat, 13 Jun 2020 02:59:39 +0200 Subject: [PATCH 0361/2775] scanner: fix wrong path being passed to function Also make rename the parameter in safe_path to make it clear that this is just a relative path. Closes fdroid/fdroidserver#791. --- fdroidserver/scanner.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index ad33de13..c28d2a83 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -200,12 +200,14 @@ def scan_source(build_dir, build=metadata.Build()): ] ] - def safe_path(path): - for sp in safe_paths: - if sp.match(path): - return True + def is_image_file(path): if imghdr.what(path) is not None: return True + + def safe_path(path_in_build_dir): + for sp in safe_paths: + if sp.match(path_in_build_dir): + return True return False gradle_compile_commands = get_gradle_compile_commands(build) @@ -289,7 +291,7 @@ def scan_source(build_dir, build=metadata.Build()): count += handleproblem('binary', path_in_build_dir, filepath) elif is_executable(filepath): - if is_binary(filepath) and not safe_path(path_in_build_dir): + if is_binary(filepath) and not (safe_path(path_in_build_dir) or is_image_file(filepath)): warnproblem(_('executable binary, possibly code'), path_in_build_dir) for p in scanignore: From 670328c9e524c90f516c8b111c48bfc3aaf4fc78 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 11 Jun 2020 12:28:52 +0200 Subject: [PATCH 0362/2775] scanner: allow microsoft appcenter, except appcenter-push This sdk is open source. It was added because appcenter has a dependency to play-services. It's possible though to build an app using appcenter that doesn't pull in play services, so we can't blanket ban the sdk. The appcenter-push modules has obvious refenrences to firebase, so it's safe to error on that. Ref: https://phabricator.wikimedia.org/T254980 --- fdroidserver/scanner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index ad33de13..471de17b 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -86,7 +86,7 @@ def scan_source(build_dir, build=metadata.Build()): r'''["']com.facebook.android['":]''', r'cloudrail', r'com.tencent.bugly', - r'com.microsoft.appcenter', + r'appcenter-push', ] } From f84818c15e290248713b918072f20f8fe3af838d Mon Sep 17 00:00:00 2001 From: Marcus Date: Mon, 15 Jun 2020 18:03:19 +0000 Subject: [PATCH 0363/2775] scanner: add a simple scan for blacklisted classes after build step add com.android.billing to blacklist, see https://gitlab.com/fdroid/fdroiddata/-/issues/2070#note_360611289 --- completion/bash-completion | 2 +- examples/config.py | 3 +++ fdroidserver/build.py | 5 +++++ fdroidserver/common.py | 2 ++ fdroidserver/scanner.py | 31 ++++++++++++++++++++++++++++++- tests/build.TestCase | 2 ++ tests/scanner.TestCase | 2 ++ 7 files changed, 45 insertions(+), 2 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index 7e2a15da..5f21621e 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -83,7 +83,7 @@ __complete_options() { __complete_build() { opts="-v -q -l -s -t -f -a -w" - lopts="--verbose --quiet --latest --stop --test --server --reset-server --skip-scan --no-tarball --force --all --wiki --no-refresh" + lopts="--verbose --quiet --latest --stop --test --server --reset-server --skip-scan --scan-binary --no-tarball --force --all --wiki --no-refresh" case "${prev}" in :) __vercode diff --git a/examples/config.py b/examples/config.py index e5735591..f01a2548 100644 --- a/examples/config.py +++ b/examples/config.py @@ -50,6 +50,9 @@ # Defaults to using an internal gradle wrapper (gradlew-fdroid). # gradle = "gradle" +# Always scan the APKs produced by `fdroid build` for known non-free classes +# scan_binary = True + # Set the maximum age (in days) of an index that a client should accept from # this repo. Setting it to 0 or not setting it at all disables this # functionality. If you do set this to a non-zero value, you need to ensure diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 922fe169..2799dc1b 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -806,6 +806,9 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext " Expected: '%s' / '%s'") % (version, str(vercode), build.versionName, str(build.versionCode))) + if (options.scan_binary or config.get('scan_binary')) and not options.skipscan: + if scanner.scan_binary(src): + raise BuildException("Found blacklisted packages in final apk!") # Copy the unsigned apk to our destination directory for further # processing (by publish.py)... @@ -899,6 +902,8 @@ def parse_commandline(): help=argparse.SUPPRESS) parser.add_argument("--skip-scan", dest="skipscan", action="store_true", default=False, help=_("Skip scanning the source code for binaries and other problems")) + parser.add_argument("--scan-binary", action="store_true", default=False, + help=_("Scan the resulting APK(s) for known non-free classes.")) parser.add_argument("--no-tarball", dest="notarball", action="store_true", default=False, help=_("Don't create a source tarball, useful when testing a build")) parser.add_argument("--no-refresh", dest="refresh", action="store_false", default=True, diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 4ce6d86a..48ebe899 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -114,6 +114,7 @@ default_config = { 'build_tools': MINIMUM_AAPT_VERSION, 'force_build_tools': False, 'java_paths': None, + 'scan_binary': False, 'ant': "ant", 'mvn3': "mvn", 'gradle': os.path.join(FDROID_PATH, 'gradlew-fdroid'), @@ -432,6 +433,7 @@ def find_sdk_tools_cmd(cmd): sdk_tools = os.path.join(config['sdk_path'], 'tools') if os.path.exists(sdk_tools): tooldirs.append(sdk_tools) + tooldirs.append(os.path.join(sdk_tools, 'bin')) sdk_platform_tools = os.path.join(config['sdk_path'], 'platform-tools') if os.path.exists(sdk_platform_tools): tooldirs.append(sdk_platform_tools) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 9ba94c6c..47526105 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -58,6 +58,36 @@ def get_gradle_compile_commands(build): return [re.compile(r'\s*' + c, re.IGNORECASE) for c in commands] +def scan_binary(apkfile): + usual_suspects = { + # The `apkanalyzer dex packages` output looks like this: + # M d 1 1 93 + # The first column has P/C/M/F for package, class, methos or field + # The second column has x/k/r/d for removed, kept, referenced and defined. + # We already filter for defined only in the apkanalyzer call. 'r' will be + # for things referenced but not distributed in the apk. + exp: re.compile(r'.[\s]*d[\s]*[0-9]*[\s]*[0-9*][\s]*[0-9]*[\s]*' + exp, re.IGNORECASE) for exp in [ + r'(com\.google\.firebase[^\s]*)', + r'(com\.google\.android\.gms[^\s]*)', + r'(com\.google\.tagmanager[^\s]*)', + r'(com\.google\.analytics[^\s]*)', + r'(com\.android\.billing[^\s]*)', + ] + } + logging.info("Scanning APK for known non-free classes.") + result = common.SdkToolsPopen(["apkanalyzer", "dex", "packages", "--defined-only", apkfile], output=False) + problems = 0 + for suspect, regexp in usual_suspects.items(): + matches = regexp.findall(result.output) + if matches: + for m in set(matches): + logging.debug("Found class '%s'" % m) + problems += 1 + if problems: + logging.critical("Found problems in %s" % apkfile) + return problems + + def scan_source(build_dir, build=metadata.Build()): """Scan the source code in the given directory (and all subdirectories) and return the number of fatal problems encountered @@ -308,7 +338,6 @@ def scan_source(build_dir, build=metadata.Build()): def main(): - global config, options, json_per_build # Parse command line... diff --git a/tests/build.TestCase b/tests/build.TestCase index 0495bb79..183f6661 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -131,7 +131,9 @@ class BuildTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config + fdroidserver.build.config = config fdroidserver.build.options = mock.Mock() + fdroidserver.build.options.scan_binary = False fdroidserver.build.options.notarball = True fdroidserver.build.options.skipscan = False diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 67cef2fd..17684074 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -194,8 +194,10 @@ class ScannerTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config + fdroidserver.build.config = config fdroidserver.build.options = mock.Mock() fdroidserver.build.options.json = False + fdroidserver.build.options.scan_binary = False fdroidserver.build.options.notarball = True fdroidserver.build.options.skipscan = False fdroidserver.scanner.options = fdroidserver.build.options From 0183592526a0374c48519d3cbc67a05dc437faf3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 6 Nov 2019 09:03:27 +0100 Subject: [PATCH 0364/2775] update: insert donation links based on FUNDING.yml GitHub has specified FUNDING.yml, a file to include in a git repo for pointing people to donation links. Since F-Droid also points people to donation links, this parses them to fill out Donate: and OpenCollective:. Specifying those in the metadata file takes precedence over the FUNDING.yml. This follows the same pattern as how `fdroid update` includes Fastlane/Triple-T metadata. This lets the git repo maintain those specific donations links themselves. https://help.github.com/en/articles/displaying-a-sponsor-button-in-your-repository#about-funding-files The test file was generated using: ```python import os, re, yaml found = dict() for root, dirs, files in os.walk('.'): for f in files: if f == 'FUNDING.yml': with open(os.path.join(root, f)) as fp: data = yaml.safe_load(fp) for k, v in data.items(): if k not in found: found[k] = set() if not v: continue if isinstance(v, list): for i in v: found[k].add(i) else: found[k].add(v) with open('gather-funding-names.yaml', 'w') as fp: output = dict() for k, v in found.items(): output[k] = sorted(v) yaml.dump(output, fp, default_flow_style=False) ``` --- fdroidserver/metadata.py | 6 +- fdroidserver/update.py | 118 +++++++++++++++++++++ tests/funding-usernames.yaml | 197 +++++++++++++++++++++++++++++++++++ tests/metadata.TestCase | 15 +++ tests/update.TestCase | 85 +++++++++++++++ 5 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 tests/funding-usernames.yaml diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index b1be88f8..ac838593 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -41,6 +41,10 @@ from fdroidserver.exception import MetaDataException, FDroidException srclibs = None warnings_action = None +# validates usernames based on a loose collection of rules from GitHub, GitLab, +# Liberapay and issuehunt. This is mostly to block abuse. +VALID_USERNAME_REGEX = re.compile(r'^[a-z\d](?:[a-z\d/._-]){0,38}$', re.IGNORECASE) + def warn_or_exception(value, cause=None): '''output warning or Exception depending on -W''' @@ -455,7 +459,7 @@ valuetypes = { ['LiberapayID']), FieldValidator("Open Collective", - r'^[0-9a-zA-Z_-]+$', + VALID_USERNAME_REGEX, ['OpenCollective']), FieldValidator("HTTP link", diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 3b7c5951..c83e3f21 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -31,10 +31,15 @@ import zipfile import hashlib import json import time +import yaml import copy from datetime import datetime from argparse import ArgumentParser from base64 import urlsafe_b64encode +try: + from yaml import CSafeLoader as SafeLoader +except ImportError: + from yaml import SafeLoader import collections from binascii import hexlify @@ -854,6 +859,118 @@ def _get_base_hash_extension(f): return base, None, extension +def sanitize_funding_yml_entry(entry): + """FUNDING.yml comes from upstream repos, entries must be sanitized""" + if type(entry) not in (bytes, int, float, list, str): + return + if isinstance(entry, bytes): + entry = entry.decode() + elif isinstance(entry, list): + if entry: + entry = entry[0] + else: + return + try: + entry = str(entry) + except (TypeError, ValueError): + return + if len(entry) > 2048: + logging.warning(_('Ignoring FUNDING.yml entry longer than 2048: %s') % entry[:2048]) + return + if '\n' in entry: + return + return entry.strip() + + +def sanitize_funding_yml_name(name): + """Sanitize usernames that come from FUNDING.yml""" + entry = sanitize_funding_yml_entry(name) + if entry: + m = metadata.VALID_USERNAME_REGEX.match(entry) + if m: + return m.group() + return + + +def insert_funding_yml_donation_links(apps): + """include donation links from FUNDING.yml in app's source repo + + GitHub made a standard file format for declaring donation + links. This parses that format from upstream repos to include in + metadata here. GitHub supports mostly proprietary services, so + this logic adds proprietary services only as Donate: links. + + FUNDING.yml can be either in the root of the project, or in the + ".github" subdir. + + https://help.github.com/en/articles/displaying-a-sponsor-button-in-your-repository#about-funding-files + + """ + + if not os.path.isdir('build'): + return # nothing to do + for packageName, app in apps.items(): + sourcedir = os.path.join('build', packageName) + if not os.path.isdir(sourcedir): + continue + for f in ([os.path.join(sourcedir, 'FUNDING.yml'), ] + + glob.glob(os.path.join(sourcedir, '.github', 'FUNDING.yml'))): + if not os.path.isfile(f): + continue + data = None + try: + with open(f) as fp: + data = yaml.load(fp, Loader=SafeLoader) + except yaml.YAMLError as e: + logging.error(_('Found bad funding file "{path}" for "{name}":') + .format(path=f, name=packageName)) + logging.error(e) + if not data or type(data) != dict: + continue + if not app.get('OpenCollective') and 'open_collective' in data: + s = sanitize_funding_yml_name(data['open_collective']) + if s: + app['OpenCollective'] = s + if not app.get('Donate'): + del(data['liberapay']) + del(data['open_collective']) + # this tuple provides a preference ordering + for k in ('custom', 'github', 'patreon', 'community_bridge', 'ko_fi', 'issuehunt'): + v = data.get(k) + if not v: + continue + if k == 'custom': + s = sanitize_funding_yml_entry(v) + if s: + app['Donate'] = s + break + elif k == 'community_bridge': + s = sanitize_funding_yml_name(v) + if s: + app['Donate'] = 'https://funding.communitybridge.org/projects/' + s + break + elif k == 'github': + s = sanitize_funding_yml_name(v) + if s: + app['Donate'] = 'https://github.com/sponsors/' + s + break + elif k == 'issuehunt': + s = sanitize_funding_yml_name(v) + if s: + app['Donate'] = 'https://issuehunt.io/r/' + s + break + elif k == 'ko_fi': + s = sanitize_funding_yml_name(v) + if s: + app['Donate'] = 'https://ko-fi.com/' + s + break + elif k == 'patreon': + s = sanitize_funding_yml_name(v) + if s: + app['Donate'] = 'https://patreon.com/' + s + break + + def copy_triple_t_store_metadata(apps): """Include store metadata from the app's source repo @@ -2179,6 +2296,7 @@ def main(): else: logging.warning(msg + '\n\t' + _('Use `fdroid update -c` to create it.')) + insert_funding_yml_donation_links(apps) copy_triple_t_store_metadata(apps) insert_obbs(repodirs[0], apps, apks) insert_localized_app_metadata(apps) diff --git a/tests/funding-usernames.yaml b/tests/funding-usernames.yaml new file mode 100644 index 00000000..04c08a13 --- /dev/null +++ b/tests/funding-usernames.yaml @@ -0,0 +1,197 @@ +bad: + - "Robert'); DROP TABLE Students; --" + - '' + - -a-b + - '1234567890123456789012345678901234567890' + - ~derp@darp---++asdf + - foo@bar.com + - me++ + - --me +bitcoin: + - 3Lbz4vdt15Fsa4wVD3Yk8uGf6ugKKY4zSc +community_bridge: [] +custom: + - bc1qvll2mp5ndwd4sgycu4ad2ken4clhjac7mdlcaj + - http://www.roguetemple.com/z/donate.php + - https://donate.openfoodfacts.org + - https://email.faircode.eu/donate/ + - https://etchdroid.depau.eu/donate/ + - https://f-droid.org/about/ + - https://flattr.com/github/bk138 + - https://gultsch.de/donate.html + - https://jahir.dev/donate + - https://kodi.tv/contribute/donate + - https://link.xbrowsersync.org/cryptos + - https://manyver.se/donate + - https://paypal.me/DanielQuahShaoHian + - https://paypal.me/deletescape + - https://paypal.me/freaktechnik + - https://paypal.me/hpoul + - https://paypal.me/imkosh + - https://paypal.me/paphonb + - https://paypal.me/vocabletrainer + - https://pendulums.io/donation.html + - https://play.google.com/store/apps/details?id=de.dennisguse.opentracks.playstore + - https://play.google.com/store/apps/details?id=eu.faircode.email + - https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/donate.png + - https://raw.githubusercontent.com/CarGuo/GSYGithubAppFlutter/master/thanks.jpg + - https://raw.githubusercontent.com/GanZhiXiong/GZXTaoBaoAppFlutter/blob/master/preview_images/thanks.png + - https://seriesgui.de/whypay + - https://transportr.app/donate/ + - https://www.bountysource.com/teams/nextcloud/issues?tracker_ids=38838206 + - https://www.donationalerts.com/r/blidingmage835 + - https://www.hellotux.com/f-droid + - https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8UH5MBVYM3J36 + - https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=E2FCXCT6837GL + - https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FMLNN8GXZKJEE + - https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K7HVLE6J7SXXA + - https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZD39ZE7MGEGBL&source=url + - https://www.paypal.me/SimpleMobileTools + - https://www.paypal.me/TheAlphamerc/ + - https://www.paypal.me/avirias + - https://www.paypal.me/btimofeev + - https://www.paypal.me/enricocid + - https://www.paypal.me/gsnathan + - https://www.paypal.me/nikita36078 + - https://www.paypal.me/sahdeep + - https://www.paypal.me/saulhenriquez + - https://www.simplemobiletools.com/donate + - https://www.youtube.com/watch?v=ZmrNc1ZhBkQ + - paypal.me/amangautam1 + - paypal.me/pools/c/8lCZfNnU0u + - paypal.me/psoffritti +github: + - 00-Evan + - adrcotfas + - afollestad + - ar- + - BarnabyShearer + - CarGuo + - cketti + - eighthave + - emansih + - GanZhiXiong + - gpeal + - hpoul + - i-- + - inorichi + - inputmice + - jahirfiquitiva + - johnjohndoe + - kaloudis + - kiwix + - ligi + - M66B + - mikepenz + - Mygod + - paroj + - PerfectSlayer + - sschueller + - tateisu + - tibbi + - westnordost + - x1unix + - xn--nding-jua + - zenorogue +issuehunt: + - bk138/multivnc +ko_fi: + - afollestad + - fennifith + - inorichi + - mastalab + - psoffritti +liberapay: + - ActivityDiary + - AndStatus + - BM835 + - Briar + - DAVx5 + - F-Droid-Data + - Feeel + - Fruit-Radar-Development + - Gadgetbridge + - GuardianProject + - Hocuri + - KOReader + - Kanedias + - Kunzisoft + - MaxK + - NovaVideoPlayer + - Phie + - Rudloff + - Schoumi + - Syncthing-Fork + - TeamNewPipe + - Telegram-FOSS + - Transportr + - Varlorg + - Wesnoth + - ZiiS + - ar- + - bk138 + - btimofeev + - bubblineyuri + - dennis.guse + - developerfromjokela + - devgianlu + - eneiluj + - experiment322 + - fdossena + - fennifith + - freaktechnik + - gsantner + - hisname + - hsn6 + - iNPUTmice + - inputmice + - k9mail + - matrixdotorg + - mmarif + - moezbhatti + - proninyaroslav + - quite + - renyuneyun + - rocketnine.space + - sanskritbscs + - sschueller + - sschueller/donate + - stefan-niedermann + - tasks + - teamkodi + - thermatk + - tom79 + - wallabag + - westnordost + - whyorean + - wilko + - xbrowsersync + - yeriomin + - zeh +open_collective: + - avirias + - curl + - libsodium + - manyverse + - mastalab + - tusky +otechie: [] +patreon: + - BaldPhone + - Bm835 + - FastHub + - Teamkodi + - andrestaltz + - bk138 + - depau + - iamSahdeep + - ligi + - ogre1 + - orhunp + - tiborkaputa + - tom79 + - westnordost + - xbrowsersync + - yairm210 + - zenorogue +tidelift: [] diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 3799e48c..5a574702 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -100,6 +100,21 @@ class MetadataTest(unittest.TestCase): self.assertRaises(fdroidserver.exception.MetaDataException, validator.check, 'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id') + def test_valid_funding_yml_regex(self): + """Check the regex can find all the cases""" + with open(os.path.join(self.basedir, 'funding-usernames.yaml')) as fp: + data = yaml.safe_load(fp) + + for k, entries in data.items(): + for entry in entries: + m = fdroidserver.metadata.VALID_USERNAME_REGEX.match(entry) + if k == 'custom': + pass + elif k == 'bad': + self.assertIsNone(m, 'this is an invalid %s username: {%s}' % (k, entry)) + else: + self.assertIsNotNone(m, 'this is a valid %s username: {%s}' % (k, entry)) + def test_read_metadata(self): def _build_yaml_representer(dumper, data): diff --git a/tests/update.TestCase b/tests/update.TestCase index 1465ad57..35932489 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -8,6 +8,7 @@ import inspect import logging import optparse import os +import random import shutil import subprocess import sys @@ -33,6 +34,12 @@ import fdroidserver.update from fdroidserver.common import FDroidPopen +DONATION_FIELDS = ( + 'Donate', + 'OpenCollective', +) + + class UpdateTest(unittest.TestCase): '''fdroid update''' @@ -972,6 +979,84 @@ class UpdateTest(unittest.TestCase): 'VercodeOperation': '', 'WebSite': ''}) + def test_insert_funding_yml_donation_links(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + os.mkdir('build') + content = textwrap.dedent(""" + community_bridge: '' + custom: [LINK1, LINK2] + github: USERNAME + issuehunt: USERNAME + ko_fi: USERNAME + liberapay: USERNAME + open_collective: USERNAME + otechie: USERNAME + patreon: USERNAME + """) + app = fdroidserver.metadata.App() + app.id = 'fake.app.id' + apps = {app.id: app} + os.mkdir(os.path.join('build', app.id)) + fdroidserver.update.insert_funding_yml_donation_links(apps) + for field in DONATION_FIELDS: + self.assertFalse(app.get(field)) + with open(os.path.join('build', app.id, 'FUNDING.yml'), 'w') as fp: + fp.write(content) + + fdroidserver.update.insert_funding_yml_donation_links(apps) + for field in DONATION_FIELDS: + self.assertIsNotNone(app.get(field), field) + self.assertEqual('LINK1', app.get('Donate')) + self.assertEqual('USERNAME', app.get('OpenCollective')) + + app['Donate'] = 'keepme' + app['OpenCollective'] = 'keepme' + fdroidserver.update.insert_funding_yml_donation_links(apps) + for field in DONATION_FIELDS: + self.assertEqual('keepme', app.get(field)) + + def test_insert_funding_yml_donation_links_with_corrupt_file(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + os.mkdir('build') + app = fdroidserver.metadata.App() + app.id = 'fake.app.id' + apps = {app.id: app} + os.mkdir(os.path.join('build', app.id)) + with open(os.path.join('build', app.id, 'FUNDING.yml'), 'w') as fp: + fp.write(textwrap.dedent(""" + opencollective: foo + custom: [] + liberapay: : + """)) + fdroidserver.update.insert_funding_yml_donation_links(apps) + for field in DONATION_FIELDS: + self.assertIsNone(app.get(field)) + + def test_sanitize_funding_yml(self): + with open(os.path.join(self.basedir, 'funding-usernames.yaml')) as fp: + data = yaml.safe_load(fp) + for k, entries in data.items(): + for entry in entries: + if k in 'custom': + m = fdroidserver.update.sanitize_funding_yml_entry(entry) + else: + m = fdroidserver.update.sanitize_funding_yml_name(entry) + if k == 'bad': + self.assertIsNone(m) + else: + self.assertIsNotNone(m) + self.assertIsNone(fdroidserver.update.sanitize_funding_yml_entry('foo\nbar')) + self.assertIsNone(fdroidserver.update.sanitize_funding_yml_entry( + ''.join(chr(random.randint(65, 90)) for _ in range(2049)))) + + # not recommended but valid entries + self.assertIsNotNone(fdroidserver.update.sanitize_funding_yml_entry(12345)) + self.assertIsNotNone(fdroidserver.update.sanitize_funding_yml_entry(5.0)) + self.assertIsNotNone(fdroidserver.update.sanitize_funding_yml_entry(' WhyIncludeWhitespace ')) + self.assertIsNotNone(fdroidserver.update.sanitize_funding_yml_entry(['first', 'second'])) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 62c8fd5999f057bdb6971dee5996549a41f8173d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Jun 2020 14:39:46 +0200 Subject: [PATCH 0365/2775] add Liberapay: field with username as data Liberapay was originally included using a numeric ID, since they had not yet finalized the public URLs. Now it is a username. So this logic prefers the username in Liberapay: field, and keeps the old LiberapayID: to ease migration. LiberapayID: will not override Liberapay:. Clients are expected to prefer Liberapay: over LiberapayID: --- .gitlab-ci.yml | 2 +- fdroidserver/lint.py | 6 ++++-- fdroidserver/metadata.py | 7 +++++++ fdroidserver/update.py | 4 ++++ tests/metadata/dump/com.politedroid.yaml | 1 + tests/metadata/dump/org.adaway.yaml | 3 ++- tests/metadata/dump/org.smssecure.smssecure.yaml | 1 + tests/metadata/dump/org.videolan.vlc.yaml | 1 + tests/metadata/info.guardianproject.checkey.yml | 1 + tests/metadata/obb.main.oldversion.yml | 1 + tests/metadata/org.adaway.yml | 1 + tests/repo/index-v1.json | 1 + tests/update.TestCase | 3 +++ 13 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0b5d96cd..a6480604 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,7 +36,7 @@ metadata_v0: - cd fdroiddata - ../tests/dump_internal_metadata_format.py - sed -i - -e '/kivy:\sfalse/d' + -e '/Liberapay:/d' -e '/OpenCollective/d' metadata/dump_*/*.yaml - diff -uw metadata/dump_* diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 4b7a8507..cf6a1119 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -141,9 +141,11 @@ regex_checks = { ], 'Donate': http_checks + [ (re.compile(r'.*flattr\.com'), - _("Flattr donation methods belong in the FlattrID flag")), + _("Flattr donation methods belong in the FlattrID: field")), (re.compile(r'.*liberapay\.com'), - _("Liberapay donation methods belong in the LiberapayID flag")), + _("Liberapay donation methods belong in the Liberapay: field")), + (re.compile(r'.*opencollective\.com'), + _("OpenCollective donation methods belong in the OpenCollective: field")), ], 'Changelog': http_checks, 'Author Name': [ diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index ac838593..a170699c 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -77,6 +77,7 @@ app_fields = set([ 'Changelog', 'Donate', 'FlattrID', + 'Liberapay', 'LiberapayID', 'OpenCollective', 'Bitcoin', @@ -121,6 +122,7 @@ yaml_app_field_order = [ 'Changelog', 'Donate', 'FlattrID', + 'Liberapay', 'LiberapayID', 'OpenCollective', 'Bitcoin', @@ -181,6 +183,7 @@ class App(dict): self.Changelog = '' self.Donate = None self.FlattrID = None + self.Liberapay = None self.LiberapayID = None self.OpenCollective = None self.Bitcoin = None @@ -454,6 +457,10 @@ valuetypes = { r'^[0-9a-z]+$', ['FlattrID']), + FieldValidator("Liberapay", + VALID_USERNAME_REGEX, + ['Liberapay']), + FieldValidator("Liberapay ID", r'^[0-9]+$', ['LiberapayID']), diff --git a/fdroidserver/update.py b/fdroidserver/update.py index c83e3f21..4c371da9 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -927,6 +927,10 @@ def insert_funding_yml_donation_links(apps): logging.error(e) if not data or type(data) != dict: continue + if not app.get('Liberapay') and 'liberapay' in data: + s = sanitize_funding_yml_name(data['liberapay']) + if s: + app['Liberapay'] = s if not app.get('OpenCollective') and 'open_collective' in data: s = sanitize_funding_yml_name(data['open_collective']) if s: diff --git a/tests/metadata/dump/com.politedroid.yaml b/tests/metadata/dump/com.politedroid.yaml index 48b4ac44..1fe59448 100644 --- a/tests/metadata/dump/com.politedroid.yaml +++ b/tests/metadata/dump/com.politedroid.yaml @@ -17,6 +17,7 @@ Disabled: null Donate: null FlattrID: null IssueTracker: https://github.com/miguelvps/PoliteDroid/issues +Liberapay: null LiberapayID: null License: GPL-3.0-only Litecoin: null diff --git a/tests/metadata/dump/org.adaway.yaml b/tests/metadata/dump/org.adaway.yaml index 00e59bd2..4732ad01 100644 --- a/tests/metadata/dump/org.adaway.yaml +++ b/tests/metadata/dump/org.adaway.yaml @@ -40,7 +40,8 @@ Disabled: null Donate: http://sufficientlysecure.org/index.php/adaway FlattrID: '369138' IssueTracker: https://github.com/dschuermann/ad-away/issues -LiberapayID: null +Liberapay: null +LiberapayID: '1234567890' License: GPL-3.0-only Litecoin: null MaintainerNotes: '' diff --git a/tests/metadata/dump/org.smssecure.smssecure.yaml b/tests/metadata/dump/org.smssecure.smssecure.yaml index 5fc47857..9587ce57 100644 --- a/tests/metadata/dump/org.smssecure.smssecure.yaml +++ b/tests/metadata/dump/org.smssecure.smssecure.yaml @@ -37,6 +37,7 @@ Disabled: null Donate: null FlattrID: null IssueTracker: https://github.com/SMSSecure/SMSSecure/issues +Liberapay: null LiberapayID: null License: GPL-3.0-only Litecoin: null diff --git a/tests/metadata/dump/org.videolan.vlc.yaml b/tests/metadata/dump/org.videolan.vlc.yaml index 5ab8783d..39d628d4 100644 --- a/tests/metadata/dump/org.videolan.vlc.yaml +++ b/tests/metadata/dump/org.videolan.vlc.yaml @@ -24,6 +24,7 @@ Disabled: null Donate: http://www.videolan.org/contribute.html#money FlattrID: null IssueTracker: http://www.videolan.org/support/index.html#bugs +Liberapay: null LiberapayID: null License: GPL-3.0-only Litecoin: null diff --git a/tests/metadata/info.guardianproject.checkey.yml b/tests/metadata/info.guardianproject.checkey.yml index 2a0119c4..78b75320 100644 --- a/tests/metadata/info.guardianproject.checkey.yml +++ b/tests/metadata/info.guardianproject.checkey.yml @@ -7,6 +7,7 @@ SourceCode: https://github.com/guardianproject/checkey IssueTracker: https://dev.guardianproject.info/projects/checkey/issues Translation: https://www.transifex.com/otf/checkey Bitcoin: 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk +Liberapay: GuardianProject AutoName: Checkey diff --git a/tests/metadata/obb.main.oldversion.yml b/tests/metadata/obb.main.oldversion.yml index 1d18e69c..a0792a3c 100644 --- a/tests/metadata/obb.main.oldversion.yml +++ b/tests/metadata/obb.main.oldversion.yml @@ -3,6 +3,7 @@ Categories: License: GPL-3.0-only SourceCode: https://github.com/eighthave/urzip Bitcoin: 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk +Liberapay: 12334 AutoName: OBB Main Old Version diff --git a/tests/metadata/org.adaway.yml b/tests/metadata/org.adaway.yml index 41bdb083..edfb2cd5 100644 --- a/tests/metadata/org.adaway.yml +++ b/tests/metadata/org.adaway.yml @@ -8,6 +8,7 @@ IssueTracker: https://github.com/dschuermann/ad-away/issues Translation: https://www.transifex.com/dominikschuermann/adaway Donate: http://sufficientlysecure.org/index.php/adaway FlattrID: '369138' +LiberapayID: '1234567890' AutoName: AdAway Summary: Block advertisements diff --git a/tests/repo/index-v1.json b/tests/repo/index-v1.json index bf6626d1..eef8b389 100644 --- a/tests/repo/index-v1.json +++ b/tests/repo/index-v1.json @@ -104,6 +104,7 @@ "Development" ], "suggestedVersionCode": "99999999", + "liberapay": "12334", "license": "GPL-3.0-only", "name": "OBB Main Old Version", "sourceCode": "https://github.com/eighthave/urzip", diff --git a/tests/update.TestCase b/tests/update.TestCase index 35932489..de2361f9 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -36,6 +36,7 @@ from fdroidserver.common import FDroidPopen DONATION_FIELDS = ( 'Donate', + 'Liberapay', 'OpenCollective', ) @@ -1008,9 +1009,11 @@ class UpdateTest(unittest.TestCase): for field in DONATION_FIELDS: self.assertIsNotNone(app.get(field), field) self.assertEqual('LINK1', app.get('Donate')) + self.assertEqual('USERNAME', app.get('Liberapay')) self.assertEqual('USERNAME', app.get('OpenCollective')) app['Donate'] = 'keepme' + app['Liberapay'] = 'keepme' app['OpenCollective'] = 'keepme' fdroidserver.update.insert_funding_yml_donation_links(apps) for field in DONATION_FIELDS: From 2c4e9beacb131830dc9cb5620906764ce4c0c57f Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 17 Jun 2020 10:33:55 +0200 Subject: [PATCH 0366/2775] scanner: add test with abs/rel paths as run from `fdroid build` https://gitlab.com/fdroid/fdroidserver/-/issues/791#note_361018050 !767 --- tests/scanner.TestCase | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 17684074..2dbfbbba 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -105,9 +105,17 @@ class ScannerTest(unittest.TestCase): self.assertEqual(2, count, 'there should be this many errors') def test_scan_source_file_types(self): - """Build product files are not allowed, test they are detected""" + """Build product files are not allowed, test they are detected + + This test runs as if `fdroid build` running to test the + difference between absolute and relative paths. + + """ testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) - os.chdir(testdir) + build_dir = os.path.join('build', 'fake.app') + abs_build_dir = os.path.join(testdir, build_dir) + os.makedirs(abs_build_dir, exist_ok=True) + os.chdir(abs_build_dir) fdroidserver.scanner.config = None fdroidserver.scanner.options = mock.Mock() @@ -151,8 +159,11 @@ class ScannerTest(unittest.TestCase): os.chmod('snippet.png', 0o755) os.system('ls -l fake.png') - count = fdroidserver.scanner.scan_source(testdir) + # run scanner as if from `fdroid build` + os.chdir(testdir) + count = fdroidserver.scanner.scan_source(build_dir) self.assertEqual(6, count, 'there should be this many errors') + os.chdir(build_dir) for f in keep + binaries: self.assertTrue(os.path.exists(f), f + ' should still be there') From 0ff3c561c08361a87a15641768cd2514e3646fc4 Mon Sep 17 00:00:00 2001 From: Marcus Date: Tue, 10 Mar 2020 14:56:03 +0000 Subject: [PATCH 0367/2775] add opencollective metadata and index field --- .gitlab-ci.yml | 1 + fdroidserver/index.py | 1 + fdroidserver/metadata.py | 8 ++++++++ tests/metadata/dump/com.politedroid.yaml | 1 + tests/metadata/dump/org.adaway.yaml | 1 + tests/metadata/dump/org.smssecure.smssecure.yaml | 1 + tests/metadata/dump/org.videolan.vlc.yaml | 1 + tests/metadata/info.guardianproject.urzip.yml | 2 ++ tests/repo/index-v1.json | 4 +++- tests/repo/index.xml | 2 ++ 10 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 07be4899..5274a68c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,6 +34,7 @@ metadata_v0: - ../tests/dump_internal_metadata_format.py - sed -i -e '/kivy:\sfalse/d' + -e '/OpenCollective/d' metadata/dump_*/*.yaml - diff -uw metadata/dump_* diff --git a/fdroidserver/index.py b/fdroidserver/index.py index fd659407..eb04d597 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -445,6 +445,7 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing addElementNonEmpty('litecoin', app.Litecoin, doc, apel) addElementNonEmpty('flattr', app.FlattrID, doc, apel) addElementNonEmpty('liberapay', app.LiberapayID, doc, apel) + addElementNonEmpty('openCollective', app.OpenCollective, doc, apel) # These elements actually refer to the current version (i.e. which # one is recommended. They are historically mis-named, and need diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index e8bde005..00056d14 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -66,6 +66,7 @@ app_fields = set([ 'Donate', 'FlattrID', 'LiberapayID', + 'OpenCollective', 'Bitcoin', 'Litecoin', 'Name', @@ -110,6 +111,7 @@ yaml_app_field_order = [ 'Donate', 'FlattrID', 'LiberapayID', + 'OpenCollective', 'Bitcoin', 'Litecoin', '\n', @@ -169,6 +171,7 @@ class App(dict): self.Donate = None self.FlattrID = None self.LiberapayID = None + self.OpenCollective = None self.Bitcoin = None self.Litecoin = None self.Name = None @@ -444,6 +447,10 @@ valuetypes = { r'^[0-9]+$', ['LiberapayID']), + FieldValidator("Open Collective", + r'^[0-9a-z-]+$', + ['OpenCollective']), + FieldValidator("HTTP link", r'^http[s]?://', ["WebSite", "SourceCode", "IssueTracker", "Translation", "Changelog", "Donate"]), @@ -1481,6 +1488,7 @@ def write_plaintext_metadata(mf, app, w_comment, w_field, w_build): w_field_nonempty('Donate') w_field_nonempty('FlattrID') w_field_nonempty('LiberapayID') + w_field_nonempty('OpenCollective') w_field_nonempty('Bitcoin') w_field_nonempty('Litecoin') mf.write('\n') diff --git a/tests/metadata/dump/com.politedroid.yaml b/tests/metadata/dump/com.politedroid.yaml index cc1bebbe..5d80e30e 100644 --- a/tests/metadata/dump/com.politedroid.yaml +++ b/tests/metadata/dump/com.politedroid.yaml @@ -23,6 +23,7 @@ Litecoin: null MaintainerNotes: '' Name: null NoSourceSince: '1.5' +OpenCollective: null Provides: null Repo: https://github.com/miguelvps/PoliteDroid.git RepoType: git diff --git a/tests/metadata/dump/org.adaway.yaml b/tests/metadata/dump/org.adaway.yaml index 577d0449..6412aaa3 100644 --- a/tests/metadata/dump/org.adaway.yaml +++ b/tests/metadata/dump/org.adaway.yaml @@ -46,6 +46,7 @@ Litecoin: null MaintainerNotes: '' Name: null NoSourceSince: '' +OpenCollective: null Provides: org.sufficientlysecure.adaway Repo: https://github.com/dschuermann/ad-away.git RepoType: git diff --git a/tests/metadata/dump/org.smssecure.smssecure.yaml b/tests/metadata/dump/org.smssecure.smssecure.yaml index 42e59f07..688e7d26 100644 --- a/tests/metadata/dump/org.smssecure.smssecure.yaml +++ b/tests/metadata/dump/org.smssecure.smssecure.yaml @@ -43,6 +43,7 @@ Litecoin: null MaintainerNotes: '' Name: null NoSourceSince: '' +OpenCollective: null Provides: null Repo: https://github.com/SMSSecure/SMSSecure RepoType: git diff --git a/tests/metadata/dump/org.videolan.vlc.yaml b/tests/metadata/dump/org.videolan.vlc.yaml index 70638ad5..5ab8783d 100644 --- a/tests/metadata/dump/org.videolan.vlc.yaml +++ b/tests/metadata/dump/org.videolan.vlc.yaml @@ -45,6 +45,7 @@ MaintainerNotes: 'Instructions and dependencies here: http://wiki.videolan.org/A ' Name: null NoSourceSince: '' +OpenCollective: null Provides: null Repo: git://git.videolan.org/vlc-ports/android.git RepoType: git diff --git a/tests/metadata/info.guardianproject.urzip.yml b/tests/metadata/info.guardianproject.urzip.yml index 8bb3cd1e..bab1d763 100644 --- a/tests/metadata/info.guardianproject.urzip.yml +++ b/tests/metadata/info.guardianproject.urzip.yml @@ -1,6 +1,8 @@ AutoName: Urzip:本地应用的信息 AutoUpdateMode: None Bitcoin: 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk +LiberapayID: '9999999' +OpenCollective: f-droid-just-testing Categories: - Development - GuardianProject diff --git a/tests/repo/index-v1.json b/tests/repo/index-v1.json index a5a1d1e9..f69e7aec 100644 --- a/tests/repo/index-v1.json +++ b/tests/repo/index-v1.json @@ -184,8 +184,10 @@ "suggestedVersionCode": "2147483647", "description": "

It\u2019s Urzip \u662f\u4e00\u4e2a\u83b7\u5f97\u5df2\u5b89\u88c5 APK \u76f8\u5173\u4fe1\u606f\u7684\u5b9e\u7528\u5de5\u5177\u3002\u5b83\u4ece\u60a8\u7684\u8bbe\u5907\u4e0a\u5df2\u5b89\u88c5\u7684\u6240\u6709\u5e94\u7528\u5f00\u59cb\uff0c\u4e00\u952e\u89e6\u6478\u5373\u53ef\u663e\u793a APK \u7684\u6307\u7eb9\uff0c\u5e76\u4e14\u63d0\u4f9b\u5230\u8fbe virustotal.com \u548c androidobservatory.org \u7684\u5feb\u6377\u94fe\u63a5\uff0c\u8ba9\u60a8\u65b9\u4fbf\u5730\u4e86\u89e3\u7279\u5b9a APK \u7684\u6863\u6848\u3002\u5b83\u8fd8\u53ef\u4ee5\u8ba9\u60a8\u5bfc\u51fa\u7b7e\u540d\u8bc1\u4e66\u548c\u751f\u6210 ApkSignaturePin Pin \u6587\u4ef6\u4f9b TrustedIntents \u5e93\u4f7f\u7528\u3002

\u2605 Urzip \u652f\u6301\u4e0b\u5217\u8bed\u8a00\uff1a Deutsch, English, espa\u00f1ol, suomi, \u65e5\u672c\u8a9e, \ud55c\uad6d\uc5b4, Norsk, portugu\u00eas (Portugal), \u0420\u0443\u0441\u0441\u043a\u0438\u0439, Sloven\u0161\u010dina, T\u00fcrk\u00e7e \u6ca1\u770b\u5230\u60a8\u7684\u8bed\u8a00\uff1f\u5e2e\u5fd9\u7ffb\u8bd1\u672c\u5e94\u7528\u5427\uff1a https://www.transifex.com/projects/p/urzip

\u2605 \u81f4\u7528\u6237\uff1a\u6211\u4eec\u8fd8\u7f3a\u5c11\u4f60\u559c\u6b22\u7684\u529f\u80fd\uff1f\u53d1\u73b0\u4e86\u4e00\u4e2a bug\uff1f\u8bf7\u544a\u8bc9\u6211\u4eec\uff01\u6211\u4eec\u4e50\u4e8e\u542c\u53d6\u60a8\u7684\u610f\u89c1\u3002\u8bf7\u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u81f3: support@guardianproject.info \u6216\u8005\u52a0\u5165\u6211\u4eec\u7684\u804a\u5929\u5ba4 https://guardianproject.info/contact

", "issueTracker": "https://dev.guardianproject.info/projects/urzip/issues", + "liberapayID": "9999999", "license": "GPL-3.0-only", "name": "urzip-\u03c0\u00c7\u00c7\u03c0\u00c7\u00c7\u73b0\u4ee3\u6c49\u8bed\u901a\u7528\u5b57-\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438-\u0639\u0631\u0628\u064a1234", + "openCollective": "f-droid-just-testing", "sourceCode": "https://github.com/guardianproject/urzip", "summary": "\u4e00\u4e2a\u5b9e\u7528\u5de5\u5177\uff0c\u83b7\u53d6\u5df2\u5b89\u88c5\u5728\u60a8\u7684\u8bbe\u5907\u4e0a\u7684\u5e94\u7528\u7684\u6709\u5173\u4fe1\u606f", "webSite": "https://dev.guardianproject.info/projects/urzip", @@ -677,4 +679,4 @@ } ] } -} \ No newline at end of file +} diff --git a/tests/repo/index.xml b/tests/repo/index.xml index 313e8876..20b526dc 100644 --- a/tests/repo/index.xml +++ b/tests/repo/index.xml @@ -357,6 +357,8 @@ https://github.com/guardianproject/urzip https://dev.guardianproject.info/projects/urzip/issues 1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk + 9999999 + f-droid-just-testing 2147483647 From 6bbf0a1722c51f16788fd8cab44136ff5ba04f73 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Jun 2020 14:39:46 +0200 Subject: [PATCH 0368/2775] add Liberapay: field with username as data Liberapay was originally included using a numeric ID, since they had not yet finalized the public URLs. Now it is a username. So this logic prefers the username in Liberapay: field, and keeps the old LiberapayID: to ease migration. LiberapayID: will not override Liberapay:. Clients are expected to prefer Liberapay: over LiberapayID: # Conflicts: # fdroidserver/update.py # tests/metadata/info.guardianproject.checkey.yml # tests/metadata/obb.main.oldversion.yml # tests/metadata/org.adaway.yml # tests/update.TestCase --- .gitlab-ci.yml | 2 +- fdroidserver/lint.py | 6 ++++-- fdroidserver/metadata.py | 11 +++++++++++ tests/metadata/dump/com.politedroid.yaml | 1 + tests/metadata/dump/org.adaway.yaml | 3 ++- tests/metadata/dump/org.smssecure.smssecure.yaml | 1 + tests/metadata/dump/org.videolan.vlc.yaml | 1 + tests/metadata/info.guardianproject.checkey.txt | 1 + tests/metadata/obb.main.oldversion.txt | 1 + tests/metadata/org.adaway.json | 1 + tests/repo/index-v1.json | 1 + 11 files changed, 25 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5274a68c..1507e504 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -33,7 +33,7 @@ metadata_v0: - echo "accepted_formats = ('txt', 'yml')" >> config.py - ../tests/dump_internal_metadata_format.py - sed -i - -e '/kivy:\sfalse/d' + -e '/Liberapay:/d' -e '/OpenCollective/d' metadata/dump_*/*.yaml - diff -uw metadata/dump_* diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 465954cc..6f8a768e 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -139,9 +139,11 @@ regex_checks = { ], 'Donate': http_checks + [ (re.compile(r'.*flattr\.com'), - _("Flattr donation methods belong in the FlattrID flag")), + _("Flattr donation methods belong in the FlattrID: field")), (re.compile(r'.*liberapay\.com'), - _("Liberapay donation methods belong in the LiberapayID flag")), + _("Liberapay donation methods belong in the Liberapay: field")), + (re.compile(r'.*opencollective\.com'), + _("OpenCollective donation methods belong in the OpenCollective: field")), ], 'Changelog': http_checks, 'Author Name': [ diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 00056d14..14a6f512 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -36,6 +36,10 @@ from fdroidserver.exception import MetaDataException, FDroidException srclibs = None warnings_action = None +# validates usernames based on a loose collection of rules from GitHub, GitLab, +# Liberapay and issuehunt. This is mostly to block abuse. +VALID_USERNAME_REGEX = re.compile(r'^[a-z\d](?:[a-z\d/._-]){0,38}$', re.IGNORECASE) + def warn_or_exception(value): '''output warning or Exception depending on -W''' @@ -65,6 +69,7 @@ app_fields = set([ 'Changelog', 'Donate', 'FlattrID', + 'Liberapay', 'LiberapayID', 'OpenCollective', 'Bitcoin', @@ -110,6 +115,7 @@ yaml_app_field_order = [ 'Changelog', 'Donate', 'FlattrID', + 'Liberapay', 'LiberapayID', 'OpenCollective', 'Bitcoin', @@ -170,6 +176,7 @@ class App(dict): self.Changelog = '' self.Donate = None self.FlattrID = None + self.Liberapay = None self.LiberapayID = None self.OpenCollective = None self.Bitcoin = None @@ -443,6 +450,10 @@ valuetypes = { r'^[0-9a-z]+$', ['FlattrID']), + FieldValidator("Liberapay", + VALID_USERNAME_REGEX, + ['Liberapay']), + FieldValidator("Liberapay ID", r'^[0-9]+$', ['LiberapayID']), diff --git a/tests/metadata/dump/com.politedroid.yaml b/tests/metadata/dump/com.politedroid.yaml index 5d80e30e..4837a93c 100644 --- a/tests/metadata/dump/com.politedroid.yaml +++ b/tests/metadata/dump/com.politedroid.yaml @@ -17,6 +17,7 @@ Disabled: null Donate: null FlattrID: null IssueTracker: https://github.com/miguelvps/PoliteDroid/issues +Liberapay: null LiberapayID: null License: GPL-3.0-only Litecoin: null diff --git a/tests/metadata/dump/org.adaway.yaml b/tests/metadata/dump/org.adaway.yaml index 6412aaa3..ebabcb37 100644 --- a/tests/metadata/dump/org.adaway.yaml +++ b/tests/metadata/dump/org.adaway.yaml @@ -40,7 +40,8 @@ Disabled: null Donate: http://sufficientlysecure.org/index.php/adaway FlattrID: '369138' IssueTracker: https://github.com/dschuermann/ad-away/issues -LiberapayID: null +Liberapay: null +LiberapayID: '1234567890' License: GPL-3.0-only Litecoin: null MaintainerNotes: '' diff --git a/tests/metadata/dump/org.smssecure.smssecure.yaml b/tests/metadata/dump/org.smssecure.smssecure.yaml index 688e7d26..a979e9c1 100644 --- a/tests/metadata/dump/org.smssecure.smssecure.yaml +++ b/tests/metadata/dump/org.smssecure.smssecure.yaml @@ -37,6 +37,7 @@ Disabled: null Donate: null FlattrID: null IssueTracker: https://github.com/SMSSecure/SMSSecure/issues +Liberapay: null LiberapayID: null License: GPL-3.0-only Litecoin: null diff --git a/tests/metadata/dump/org.videolan.vlc.yaml b/tests/metadata/dump/org.videolan.vlc.yaml index 5ab8783d..39d628d4 100644 --- a/tests/metadata/dump/org.videolan.vlc.yaml +++ b/tests/metadata/dump/org.videolan.vlc.yaml @@ -24,6 +24,7 @@ Disabled: null Donate: http://www.videolan.org/contribute.html#money FlattrID: null IssueTracker: http://www.videolan.org/support/index.html#bugs +Liberapay: null LiberapayID: null License: GPL-3.0-only Litecoin: null diff --git a/tests/metadata/info.guardianproject.checkey.txt b/tests/metadata/info.guardianproject.checkey.txt index c6d7557c..1ad98833 100644 --- a/tests/metadata/info.guardianproject.checkey.txt +++ b/tests/metadata/info.guardianproject.checkey.txt @@ -5,6 +5,7 @@ Source Code:https://github.com/guardianproject/checkey Issue Tracker:https://dev.guardianproject.info/projects/checkey/issues Translation:https://www.transifex.com/otf/checkey Bitcoin:1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk +Liberapay:GuardianProject Auto Name:Checkey diff --git a/tests/metadata/obb.main.oldversion.txt b/tests/metadata/obb.main.oldversion.txt index 0a4e4956..52095f10 100644 --- a/tests/metadata/obb.main.oldversion.txt +++ b/tests/metadata/obb.main.oldversion.txt @@ -2,6 +2,7 @@ Categories:Development License:GPL-3.0-only Source Code:https://github.com/eighthave/urzip Bitcoin:1Fi5xUHiAPRKxHvyUGVFGt9extBe8Srdbk +Liberapay:12334 Auto Name:OBB Main Old Version diff --git a/tests/metadata/org.adaway.json b/tests/metadata/org.adaway.json index df71f112..c74017f5 100644 --- a/tests/metadata/org.adaway.json +++ b/tests/metadata/org.adaway.json @@ -22,6 +22,7 @@ "Donate": "http://sufficientlysecure.org/index.php/adaway", "FlattrID": "369138", "IssueTracker": "https://github.com/dschuermann/ad-away/issues", + "LiberapayID": "1234567890", "License": "GPL-3.0-only", "Provides": "org.sufficientlysecure.adaway", "Repo": "https://github.com/dschuermann/ad-away.git", diff --git a/tests/repo/index-v1.json b/tests/repo/index-v1.json index f69e7aec..9ce9ddb9 100644 --- a/tests/repo/index-v1.json +++ b/tests/repo/index-v1.json @@ -104,6 +104,7 @@ "Development" ], "suggestedVersionCode": "99999999", + "liberapay": "12334", "license": "GPL-3.0-only", "name": "OBB Main Old Version", "sourceCode": "https://github.com/eighthave/urzip", From cad4dc18c6d875ab32183767cb5de88010e21585 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 18 Jun 2020 08:01:34 +0200 Subject: [PATCH 0369/2775] bump to version v1.1.8 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2ffcc1fd..9d1f1bdf 100755 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ with open("README.md", "r") as fh: setup(name='fdroidserver', - version='1.1.7', + version='1.1.8', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From 238f0482574e5942427dc7ae8f68c4d9c2bdebc7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 24 Jun 2020 20:54:16 +0200 Subject: [PATCH 0370/2775] update: fix crash when liberapay: or open_collective: not in FUNDING.yml closes #799 --- fdroidserver/update.py | 6 ++++-- tests/update.TestCase | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 4c371da9..06ed01de 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -936,8 +936,10 @@ def insert_funding_yml_donation_links(apps): if s: app['OpenCollective'] = s if not app.get('Donate'): - del(data['liberapay']) - del(data['open_collective']) + if 'liberapay' in data: + del(data['liberapay']) + if 'open_collective' in data: + del(data['open_collective']) # this tuple provides a preference ordering for k in ('custom', 'github', 'patreon', 'community_bridge', 'ko_fi', 'issuehunt'): v = data.get(k) diff --git a/tests/update.TestCase b/tests/update.TestCase index de2361f9..eee01734 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -1019,6 +1019,47 @@ class UpdateTest(unittest.TestCase): for field in DONATION_FIELDS: self.assertEqual('keepme', app.get(field)) + def test_insert_funding_yml_donation_links_one_at_a_time(self): + """Exercise the FUNDING.yml code one entry at a time""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + os.mkdir('build') + + app = fdroidserver.metadata.App() + app.id = 'fake.app.id' + apps = {app.id: app} + os.mkdir(os.path.join('build', app.id)) + fdroidserver.update.insert_funding_yml_donation_links(apps) + for field in DONATION_FIELDS: + self.assertIsNone(app.get(field)) + + content = textwrap.dedent(""" + community_bridge: 'blah-de-blah' + github: USERNAME + issuehunt: USERNAME + ko_fi: USERNAME + liberapay: USERNAME + open_collective: USERNAME + patreon: USERNAME + """) + for line in content.split('\n'): + if not line: + continue + app = fdroidserver.metadata.App() + app.id = 'fake.app.id' + apps = {app.id: app} + with open(os.path.join('build', app.id, 'FUNDING.yml'), 'w') as fp: + fp.write(line) + data = yaml.load(line) + fdroidserver.update.insert_funding_yml_donation_links(apps) + if 'liberapay' in data: + self.assertEqual(data['liberapay'], app.get('Liberapay')) + elif 'open_collective' in data: + self.assertEqual(data['open_collective'], app.get('OpenCollective')) + else: + for v in data.values(): + self.assertEqual(app.get('Donate', '').split('/')[-1], v) + def test_insert_funding_yml_donation_links_with_corrupt_file(self): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) os.chdir(testdir) From 7e8c244473d2a163a12719efd8ab55f6230acee9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Jun 2020 14:33:07 +0200 Subject: [PATCH 0371/2775] provision-apt-get-install: ensure gpg is installed The basebox installs gpg, but when this script is used to provision a GitLab CI Runner, gpg was missing. It is used in some builds. --- buildserver/provision-apt-get-install | 1 + 1 file changed, 1 insertion(+) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index 7123b8a6..d4481b32 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -71,6 +71,7 @@ packages=" git-core git-svn gperf + gpg javacc libarchive-zip-perl libexpat1-dev From 1e6f99988a585eeb3237142eb99c543b52039925 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 24 Jun 2020 20:54:42 +0200 Subject: [PATCH 0372/2775] fix typo when looking for build.gradle.kts --- fdroidserver/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 48ebe899..04a17fd3 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2038,7 +2038,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= build_gradle_kts = build_gradle + ".kts" if os.path.exists(build_gradle): gradlefile = build_gradle - elif os.path.exist(build_gradle_kts): + elif os.path.exists(build_gradle_kts): gradlefile = build_gradle_kts regsub_file(r'compileSdkVersion[ =]+[0-9]+', r'compileSdkVersion %s' % n, From 49d414635aab32090fe8dc2521bb8cdb6107d768 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 23 Jun 2020 13:40:00 +0200 Subject: [PATCH 0373/2775] lint: fix OpenCollective field validator closes fdroiddata#2077 --- fdroidserver/metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 14a6f512..57c675c7 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -459,7 +459,7 @@ valuetypes = { ['LiberapayID']), FieldValidator("Open Collective", - r'^[0-9a-z-]+$', + r'^[0-9A-Za-z-]+$', ['OpenCollective']), FieldValidator("HTTP link", From 87164740836507e2ee06a6d14328fe3afaf3c855 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 24 Jun 2020 21:49:59 +0200 Subject: [PATCH 0374/2775] bump to v1.1.9 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9d1f1bdf..31de6e30 100755 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ with open("README.md", "r") as fh: setup(name='fdroidserver', - version='1.1.8', + version='1.1.9', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From d0f426e076bf1507919586c2652699390ef7382f Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 24 Jun 2020 20:50:21 +0200 Subject: [PATCH 0375/2775] replace $$srclib$$ with an absolute path closes #725 --- fdroidserver/build.py | 3 +-- fdroidserver/common.py | 5 ++-- tests/common.TestCase | 52 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 2799dc1b..e8880c02 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -541,8 +541,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext # Substitute source library paths into commands... for name, number, libpath in srclibpaths: - libpath = os.path.relpath(libpath, root_dir) - cmd = cmd.replace('$$' + name + '$$', libpath) + cmd = cmd.replace('$$' + name + '$$', os.path.join(os.getcwd(), libpath)) p = FDroidPopen(['bash', '-x', '-c', cmd], cwd=root_dir) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 04a17fd3..39c87aec 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2116,8 +2116,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= # Substitute source library paths into prebuild commands for name, number, libpath in srclibpaths: - libpath = os.path.relpath(libpath, root_dir) - cmd = cmd.replace('$$' + name + '$$', libpath) + cmd = cmd.replace('$$' + name + '$$', os.path.join(os.getcwd(), libpath)) p = FDroidPopen(['bash', '-x', '-c', '--', cmd], cwd=root_dir) if p.returncode != 0: @@ -2744,7 +2743,7 @@ def set_FDroidPopen_env(build=None): def replace_build_vars(cmd, build): cmd = cmd.replace('$$COMMIT$$', build.commit) cmd = cmd.replace('$$VERSION$$', build.versionName) - cmd = cmd.replace('$$VERCODE$$', build.versionCode) + cmd = cmd.replace('$$VERCODE$$', str(build.versionCode)) return cmd diff --git a/tests/common.TestCase b/tests/common.TestCase index 4dc51e5c..49e46af7 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -288,6 +288,58 @@ class CommonTest(unittest.TestCase): self.assertIsNotNone(re.search('android:versionName="%s"' % build.versionName, filedata)) self.assertIsNotNone(re.search('android:versionCode="%s"' % build.versionCode, filedata)) + def test_prepare_sources_with_prebuild_subdir(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + app_build_dir = os.path.join(testdir, 'build', 'com.example') + shutil.copytree(os.path.join(self.basedir, 'source-files', 'fdroid', 'fdroidclient'), + app_build_dir) + + subdir = 'baz/bar' + subdir_path = os.path.join(app_build_dir, subdir) + os.makedirs(subdir_path) + with open(os.path.join(subdir_path, 'build.gradle'), 'w') as fp: + fp.write('// just a test placeholder') + + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + + srclibname = 'FakeSrcLib' + srclib_testdir = os.path.join(testdir, 'build', 'srclib') + os.makedirs(os.path.join(srclib_testdir, srclibname, 'testdirshouldexist')) + fdroidserver.metadata.srclibs = { + srclibname: { + 'RepoType': 'git', + 'Repo': 'https://example.com/foo/fakesrclib', + 'Subdir': None, + 'Prepare': None, + } + } + + app = fdroidserver.metadata.App() + app.id = 'app.has.srclibs' + build = fdroidserver.metadata.Build() + build.commit = 'master' + build.gradle = ['yes'] + build.prebuild = 'test -d $$FakeSrcLib$$/testdirshouldexist' # actual test condition + build.srclibs = [srclibname + '@1.2.3'] + build.subdir = subdir + build.versionCode = 0xcafe + build.versionName = 'vCAFE' + + class FakeVcs(): + # no need to change to the correct commit here + def gotorevision(self, rev, refresh=True): + pass + + # no srclib info needed, but it could be added... + def getsrclib(self): + return None + + fdroidserver.common.prepare_source(FakeVcs(), app, build, + app_build_dir, srclib_testdir, app_build_dir, + onserver=True, refresh=False) # do not clone in this test + def test_prepare_sources_refresh(self): packageName = 'org.fdroid.ci.test.app' testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) From 5fce16c8477752bc6d3233f829e3288ef90a4a69 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 24 Jun 2020 21:33:31 +0200 Subject: [PATCH 0376/2775] remove unused, confusing arg to common.getsrclib() --- fdroidserver/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 39c87aec..374789b0 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1841,7 +1841,7 @@ def parse_srclib_spec(spec): return (name, ref, number, subdir) -def getsrclib(spec, srclib_dir, subdir=None, basepath=False, +def getsrclib(spec, srclib_dir, basepath=False, raw=False, prepare=True, preponly=False, refresh=True, build=None): """Get the specified source library. @@ -1976,7 +1976,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= if build.srclibs: logging.info("Collecting source libraries") for lib in build.srclibs: - srclibpaths.append(getsrclib(lib, srclib_dir, build, preponly=onserver, + srclibpaths.append(getsrclib(lib, srclib_dir, preponly=onserver, refresh=refresh, build=build)) for name, number, libpath in srclibpaths: From a4177e5ec36f65557e22653655abb0e7a1915dcd Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 2 Jun 2020 13:32:11 +0200 Subject: [PATCH 0377/2775] add test for correct whatsnew handling without CVC --- tests/run-tests | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/run-tests b/tests/run-tests index 9c5d85d9..d685ea1f 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -607,6 +607,19 @@ grep -F 'info.guardianproject.urzip_100.apk' repo/index-v1.json repo/index.xml grep -F 'info.guardianproject.urzip_100_b4964fd.apk' repo/index-v1.json ! grep -F 'info.guardianproject.urzip_100_b4964fd.apk' repo/index.xml +#------------------------------------------------------------------------------# +echo_header "test whatsnew from fastlane without CVC set" +REPOROOT=`create_test_dir` +cd $REPOROOT +fdroid_init_with_prebuilt_keystore +echo "accepted_formats = ['txt', 'yml']" >> config.py +mkdir -p metadata/com.politedroid/en-US/changelogs/ +cp $WORKSPACE/tests/repo/com.politedroid_6.apk repo +cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata +echo "whatsnew test" > metadata/com.politedroid/en-US/changelogs/6.txt +sed -i -e '/Current Version/d' metadata/com.politedroid.txt +$fdroid update --pretty --nosign +grep -F 'whatsnew' repo/index-v1.json #------------------------------------------------------------------------------# echo_header "test metadata checks" From 03881154c65402e3b921e841a097aea6625efd73 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 3 Jun 2020 21:28:20 +0200 Subject: [PATCH 0378/2775] metadata: make linkresolver an actual object Previously this was magically capturing the apps dict when passing it around as a function. This also moved the code to the metadata module. Add a test doing read_metadata where the linkresolver is used. This happens when the apps we read have a [[app.id]] link to another app. --- fdroidserver/index.py | 12 +- fdroidserver/metadata.py | 27 +- tests/metadata.TestCase | 8 + tests/xref/metadata/aarddict.android.yml | 104 ++++ tests/xref/metadata/org.coolreader.yml | 551 +++++++++++++++++ .../org.geometerplus.zlibrary.ui.android.yml | 556 ++++++++++++++++++ 6 files changed, 1240 insertions(+), 18 deletions(-) create mode 100644 tests/xref/metadata/aarddict.android.yml create mode 100644 tests/xref/metadata/org.coolreader.yml create mode 100644 tests/xref/metadata/org.geometerplus.zlibrary.ui.android.yml diff --git a/fdroidserver/index.py b/fdroidserver/index.py index c19b6277..195b23e7 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -58,11 +58,6 @@ def make(apps, sortedids, apks, repodir, archive): """ from fdroidserver.update import METADATA_VERSION - def _resolve_description_link(appid): - if appid in apps: - return "fdroid.app:" + appid, apps[appid].Name - raise MetaDataException("Cannot resolve app id " + appid) - if not common.options.nosign: common.assert_config_keystore(common.config) @@ -117,7 +112,7 @@ def make(apps, sortedids, apks, repodir, archive): if apk['packageName'] == packageName: newapp = copy.copy(app) # update wiki needs unmodified description newapp['Description'] = metadata.description_html(app['Description'], - _resolve_description_link) + metadata.DescriptionResolver(apps)) appsWithPackages[packageName] = newapp break @@ -311,11 +306,6 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing value = str(apk[key]) addElement(name, value, doc, parent) - def addElementCDATA(name, value, doc, parent): - el = doc.createElement(name) - el.appendChild(doc.createCDATASection(value)) - parent.appendChild(el) - def addElementCheckLocalized(name, app, key, doc, parent, default=''): """Fill in field from metadata or localized block diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index a170699c..ee58b1b4 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -616,7 +616,7 @@ class DescriptionFormatter: warn_or_exception(_("Unterminated ]]")) url = txt[2:index] if self.linkResolver: - url, urltext = self.linkResolver(url) + url, urltext = self.linkResolver.resolve_description_link(url) else: urltext = url res_html += '
' + html.escape(urltext, quote=False) + '' @@ -899,14 +899,9 @@ def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): if xref: # Parse all descriptions at load time, just to ensure cross-referencing # errors are caught early rather than when they hit the build server. - def linkres(appid): - if appid in apps: - return ("fdroid.app:" + appid, "Dummy name - don't know yet") - warn_or_exception(_("Cannot resolve app id {appid}").format(appid=appid)) - for appid, app in apps.items(): try: - description_html(app.Description, linkres) + description_html(app.Description, DummyDescriptionResolver(apps)) except MetaDataException as e: warn_or_exception(_("Problem with description of {appid}: {error}") .format(appid=appid, error=str(e))) @@ -1679,3 +1674,21 @@ def add_metadata_arguments(parser): '''add common command line flags related to metadata processing''' parser.add_argument("-W", choices=['error', 'warn', 'ignore'], default='error', help=_("force metadata errors (default) to be warnings, or to be ignored.")) + + +class DescriptionResolver: + def __init__(self, apps): + self.apps = apps + + def resolve_description_link(self, appid): + if appid in self.apps: + if self.apps[appid].Name: + return "fdroid.app:" + appid, self.apps[appid].Name + raise MetaDataException("Cannot resolve app id " + appid) + + +class DummyDescriptionResolver(DescriptionResolver): + def resolve_description_link(self, appid): + if appid in self.apps: + return "fdroid.app:" + appid, "Dummy name - don't know yet" + warn_or_exception(_("Cannot resolve app id {appid}").format(appid=appid)) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 5a574702..49151083 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -905,6 +905,14 @@ class MetadataTest(unittest.TestCase): 'Subdir': None, 'Prepare': None}}) + def test_read_xref_metadata(self): + fdroidserver.common.config = {'accepted_formats': ['yml']} + os.chdir('xref') + fdroidserver.metadata.warnings_action = 'error' + apps = fdroidserver.metadata.read_metadata(xref=True) + self.assertListEqual(list(apps.keys()), + ['aarddict.android', 'org.coolreader', 'org.geometerplus.zlibrary.ui.android']) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) diff --git a/tests/xref/metadata/aarddict.android.yml b/tests/xref/metadata/aarddict.android.yml new file mode 100644 index 00000000..d679c6b0 --- /dev/null +++ b/tests/xref/metadata/aarddict.android.yml @@ -0,0 +1,104 @@ +Categories: + - Reading +License: GPL-3.0-only +WebSite: http://aarddict.org +SourceCode: https://github.com/aarddict/android +IssueTracker: https://github.com/aarddict/android/issues +Donate: http://aarddict.org/android +FlattrID: '80944' + +AutoName: Aard +Description: |- + '''Note:''' This app is no longer maintained. + + * looks up words fast even with huge dictionaries like English Wikipedia + * looks up words in multiple dictionaries in multiple languages without switching + * works great as an offline Wikipedia reader + * uses same the efficient, highly compressed dictionary data storage format as the desktop version + * it can integrate with both [[org.geometerplus.zlibrary.ui.android]] and [[org.coolreader]] + + Ready-made dictionaries can be found on the website, or you can roll your own + with the tools on the website. + +RepoType: git +Repo: https://github.com/aarddict/android.git + +Builds: + - versionName: 1.3.1 + versionCode: 10 + commit: 1.3.1 + prebuild: mv lib libs + + - versionName: 1.4.0 + versionCode: 12 + commit: 7df930161256324e31b2c720281629f58446b6d6 + prebuild: mv lib libs + + - versionName: 1.4.1 + versionCode: 13 + commit: b81c9c8c52de5f65b550e3c608a610962582e5cd + prebuild: mv lib libs + + - versionName: 1.6.1 + versionCode: 16 + commit: 1.6.1 + target: android-17 + + - versionName: 1.6.2 + versionCode: 17 + commit: 1.6.2 + target: android-17 + + - versionName: 1.6.3 + versionCode: 18 + commit: 1.6.3 + target: android-17 + + - versionName: 1.6.4 + versionCode: 19 + commit: 1.6.4 + target: android-17 + + - versionName: 1.6.5 + versionCode: 20 + commit: 1.6.5 + target: android-17 + + - versionName: 1.6.6 + versionCode: 21 + commit: 1.6.6 + target: android-17 + + - versionName: 1.6.7 + versionCode: 22 + commit: 1.6.7 + target: android-17 + + - versionName: 1.6.8 + versionCode: 23 + commit: 1.6.8 + target: android-17 + + - versionName: 1.6.9 + versionCode: 24 + commit: 1.6.9 + target: android-17 + + - versionName: 1.6.10 + versionCode: 25 + commit: 1.6.10 + target: android-17 + + - versionName: 1.6.11 + versionCode: 26 + commit: 1.6.11 + target: android-17 + +MaintainerNotes: |- + Github site points to https://github.com/itkach/aard2-android (itkach.aard2) as successor. + We cannot point to this app as all its builds are disabled (as of 2018-10-16). + +AutoUpdateMode: Version %v +UpdateCheckMode: Tags +CurrentVersion: 1.6.11 +CurrentVersionCode: 26 diff --git a/tests/xref/metadata/org.coolreader.yml b/tests/xref/metadata/org.coolreader.yml new file mode 100644 index 00000000..e1dc1df9 --- /dev/null +++ b/tests/xref/metadata/org.coolreader.yml @@ -0,0 +1,551 @@ +Categories: + - Reading +License: GPL-2.0-only +AuthorName: Vadim Lopatin +AuthorEmail: coolreader.org@gmail.com +WebSite: https://sourceforge.net/projects/crengine/ +SourceCode: https://github.com/buggins/coolreader +IssueTracker: https://github.com/buggins/coolreader/issues +Donate: https://sourceforge.net/p/crengine/donate + +AutoName: Cool Reader +Description: |- + An e-book reader. Supported formats: FB2, TXT, RTF, TCR, HTML, EPUB, CHM. Browse + free books online and add your own OPDS shares. + + The default dictionary app is non-free. However, you can choose + [[aarddict.android]] as a dictionary from the Dictionary section of the + Settings. + +RepoType: git +Repo: https://github.com/buggins/coolreader + +Builds: + - versionName: 3.0.39-35 + versionCode: 60 + commit: 68ad007ac1272ef322fd61cb6591618723422380 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.40-1 + versionCode: 64 + commit: cr3.0.40-1 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.40-6 + versionCode: 69 + commit: cr3.0.40-6 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.41-3 + versionCode: 75 + commit: cr3.0.41-3 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.41-9 + versionCode: 81 + commit: cr3.0.41-9 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.42-6 + versionCode: 86 + commit: cr3.0.42-6 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.43-4 + versionCode: 94 + commit: cr3.0.43-4 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.43-6 + versionCode: 96 + commit: cr3.0.43-6 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.44-03 + versionCode: 103 + commit: cr3.0.44-3 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.44-09 + versionCode: 109 + commit: cr3.0.44-9 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.45-04 + versionCode: 114 + disable: tag points to wrong version + commit: unknown - see disabled + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.45-09 + versionCode: 119 + disable: tag points to wrong version + commit: unknown - see disabled + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.45-11 + versionCode: 121 + commit: 6c42a9b65090da9640ccb6ee317bb32de24201fb + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.45-14 + versionCode: 124 + commit: cr3.0.45-14 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.46-1 + versionCode: 131 + commit: cr3.0.46-1 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.46-5 + versionCode: 135 + commit: cr3.0.46-5 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.46-11 + versionCode: 141 + commit: cr3.0.46-11 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.48-5 + versionCode: 155 + commit: cr3.0.48-5 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.49-2 + versionCode: 162 + commit: cr3.0.49-2 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.49-5 + versionCode: 165 + commit: cr3.0.49-5 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.49-9 + versionCode: 169 + commit: cr3.0.49-9 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.49-16 + versionCode: 176 + commit: cr3.0.49-16 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.51-7 + versionCode: 197 + commit: cr3.0.51-7 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.52-1 + versionCode: 241 + commit: cr3.0.52-1 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.52-4 + versionCode: 244 + commit: cr3.0.52-4 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.53-3 + versionCode: 247 + commit: cr3.0.53-3 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.53-10 + versionCode: 255 + commit: cr3.0.53-10 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.53-14 + versionCode: 259 + commit: cr3.0.53-14 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.53-18 + versionCode: 263 + commit: c555ecd66d18b218fb255733c8b33a0825992f76 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.53-19 + versionCode: 264 + commit: cr3.0.53-19 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.54-5 + versionCode: 275 + commit: cr3.0.54-5 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.54-9 + versionCode: 279 + commit: cr3.0.54-9 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.54-33 + versionCode: 303 + commit: cr3.0.54-33 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.54-38 + versionCode: 308 + commit: cr3.0.54-38 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.54-47 + versionCode: 447 + commit: cr3.0.54-47 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.55-5 + versionCode: 505 + commit: cr3.0.55-5 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.55-9 + versionCode: 509 + commit: cr3.0.55-9 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.55-14 + versionCode: 514 + commit: cr3.0.55-14 + subdir: android + rm: + - android/build.properties + buildjni: + - yes + + - versionName: 3.0.55-30 + versionCode: 530 + commit: cr3.0.55-30 + subdir: android + rm: + - android/ant.properties + buildjni: + - yes + + - versionName: 3.0.55-32 + versionCode: 532 + commit: cr3.0.55-32 + subdir: android + rm: + - android/ant.properties + buildjni: + - yes + + - versionName: 3.0.56-5 + versionCode: 565 + disable: builds ok but crashes at cr3.0.56-5 + commit: cr3.0.56-5 + subdir: android + rm: + - android/ant.properties + target: android-14 + buildjni: + - yes + + - versionName: 3.0.57-15 + versionCode: 625 + disable: builds ok but crashes at cr3.0.57-15 + commit: cr3.0.57-15 + subdir: android + rm: + - android/ant.properties + target: android-14 + buildjni: + - yes + + - versionName: 3.0.57-16 + versionCode: 626 + disable: builds ok but crashes at 2f3d5fb86df316d + commit: 2f3d5fb86df316d + subdir: android + rm: + - android/ant.properties + target: android-14 + buildjni: + - yes + + - versionName: 3.1.2-27 + versionCode: 847 + commit: cr3-3.1.2-27 + subdir: android + rm: + - android/ant.properties + target: android-16 + buildjni: + - yes + + - versionName: 3.1.2-38 + versionCode: 858 + disable: ndk build errors + commit: cr3-3.1.2-38 + subdir: android + buildjni: + - yes + + - versionName: 3.1.2-39 + versionCode: 859 + commit: cr3-3.1.2-39-market + subdir: android + rm: + - android/build.properties + target: android-19 + buildjni: + - yes + + - versionName: 3.1.2-48 + versionCode: 868 + commit: cr3.1.2-48 + subdir: android + rm: + - android/build.properties + target: android-19 + buildjni: + - yes + + - versionName: 3.1.2-50 + versionCode: 870 + commit: cr3.1.2-50 + subdir: android + rm: + - android/build.properties + target: android-19 + buildjni: + - yes + + - versionName: 3.1.2-51 + versionCode: 871 + commit: cr3-3.1.2-51 + subdir: android + rm: + - android/build.properties + target: android-19 + buildjni: + - yes + + - versionName: 3.1.2-55 + versionCode: 875 + commit: cr3-3.1.2-55 + subdir: android + rm: + - android/build.properties + target: android-19 + buildjni: + - yes + + - versionName: 3.1.2-68 + versionCode: 888 + commit: cr3.1.2-68 + subdir: android + rm: + - android/build.properties + target: android-22 + buildjni: + - yes + + - versionName: 3.1.2-72 + versionCode: 892 + commit: cr3.1.2-71 + subdir: android + rm: + - android/build.properties + prebuild: sed -i -e 's/^APP_ABI\s*:=.*/APP_ABI := all/' jni/Application.mk + target: android-22 + buildjni: + - yes + + - versionName: 3.1.2-87 + versionCode: 907 + commit: 1e07d15d4644c690 + subdir: android + rm: + - android/build.properties + prebuild: sed -i -e 's/^APP_ABI\s*:=.*/APP_ABI := all/' jni/Application.mk + target: android-22 + scanignore: + - cr3wx + buildjni: + - yes + + - versionName: 3.2.9-1 + versionCode: 2091 + commit: bf48e5b7a5e89e5fc8b1f971573b5046e6b27bd3 + subdir: android + gradle: + - yes + output: app/build/outputs/apk/release/app-universal-release-unsigned.apk + rm: + - android/build.properties + prebuild: sed -i -e 's/^APP_ABI\s*:=.*/APP_ABI := all/' jni/Application.mk + scanignore: + - cr3wx + ndk: r16b + + - versionName: 3.2.38-1 + versionCode: 32380 + commit: cr3.2.38 + subdir: android/app + gradle: + - yes + rm: + - cr3wx/src/resources/crrcconv.exe + prebuild: + - sed -i -e 's/\r//' ../gradle/wrapper/gradle-wrapper.properties + - sed -i -e 's/enable true/enable false/' build.gradle + ndk: r21 + +AutoUpdateMode: None +UpdateCheckMode: Tags +CurrentVersion: 3.2.39-1 +CurrentVersionCode: 32390 diff --git a/tests/xref/metadata/org.geometerplus.zlibrary.ui.android.yml b/tests/xref/metadata/org.geometerplus.zlibrary.ui.android.yml new file mode 100644 index 00000000..ff2897eb --- /dev/null +++ b/tests/xref/metadata/org.geometerplus.zlibrary.ui.android.yml @@ -0,0 +1,556 @@ +AntiFeatures: + - NonFreeAdd + - UpstreamNonFree +Categories: + - Reading +License: GPL-2.0-or-later +AuthorName: Nikolay Pultsin +AuthorEmail: geometer@fbreader.org +AuthorWebSite: https://fbreader.org/ +WebSite: https://fbreader.org/FBReaderJ +SourceCode: https://github.com/geometer/FBReaderJ +IssueTracker: https://github.com/geometer/FBReaderJ/issues +Changelog: https://raw.githubusercontent.com/geometer/FBReaderJ/HEAD/ChangeLog +Donate: https://fbreader.org/donation/make.php + +AutoName: FBReader +Description: |- + '''N.B'''There are three different apks to cover the different versions of + Android. Donut covers 1.5-1.6; Froyo covers 2.0-2.3 and Honeycomb covers 3.0+. + x86 and MIPS are supported natively in all apks. + + An e-book reader. Features include the ability to stock up on books from online + OPDS libraries like Project Gutenberg straight from the app. F-Droid.org has two + other addon apps that provide text-to-speech functionality and one to support + ''local'' OPDS shares. + + Anti-features: Addons. While there are some addons for this app that are free, + the dictionaries that are suggested are not. However, it does support + [[aarddict.android]], as long as that is installed beforehand '''and''' you + choose it via the Dictionary section of the settings. + +RepoType: git +Repo: https://github.com/geometer/FBReaderJ.git + +Builds: + - versionName: 0.99.11 + versionCode: 9911 + commit: 0.99.11 + antcommands: + - package + + - versionName: 0.99.12 + versionCode: 9912 + commit: 0.99.12 + antcommands: + - package + + - versionName: 0.99.15 + versionCode: 9915 + commit: 0.99.15 + antcommands: + - package + + - versionName: 0.99.18 + versionCode: 9918 + commit: 0.99.18 + antcommands: + - package + + - versionName: 1.0.9 + versionCode: 10011 + commit: 1.0.9 + antcommands: + - package + + - versionName: 1.0.11 + versionCode: 10013 + commit: 1.0.11 + antcommands: + - package + + - versionName: 1.0.12 + versionCode: 10014 + commit: fd349108eff9caa9152a + antcommands: + - package + + - versionName: 1.1.0 + versionCode: 10100 + commit: 5eb993e1fac2898d2361 + antcommands: + - package + + - versionName: 1.1.1 + versionCode: 10101 + commit: 1.1.1 + antcommands: + - package + + - versionName: 1.1.2 + versionCode: 10102 + commit: 1.1.2 + antcommands: + - package + + - versionName: 1.1.8 + versionCode: 101081 + commit: 1.1.8 + antcommands: + - package + + - versionName: 1.1.9 + versionCode: 101091 + commit: 1.1.9 + antcommands: + - package + + - versionName: 1.1.10 + versionCode: 101101 + commit: 13ee5d79431815dd694e + antcommands: + - package + + - versionName: 1.2.2 + versionCode: 102021 + commit: e63c553aeb032da828b270a735f0171d8d22c54c + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + target: android-10 + buildjni: + - yes + + - versionName: 1.2.3 + versionCode: 102031 + commit: 46d83bb4351c2f6ec51e0d9aa6202c86c1297e7f + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + target: android-10 + buildjni: + - yes + + - versionName: 1.2.4 + versionCode: 102041 + commit: 6426bcf131d4 + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + target: android-10 + buildjni: + - yes + + - versionName: 1.2.6 + versionCode: 102061 + commit: 1.2.6 + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + target: android-10 + buildjni: + - yes + + - versionName: 1.3.3 + versionCode: 103031 + commit: 1.3.3 + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + target: android-10 + buildjni: + - yes + + - versionName: 1.3.6 + versionCode: 103061 + commit: a16e3eb7ff731edea99248f8a7c1633148a26236 + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + target: android-10 + buildjni: + - yes + + - versionName: 1.5.5 + versionCode: 105051 + commit: 1.5.5 + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + target: android-10 + buildjni: + - yes + + - versionName: 1.6.1 + versionCode: 106011 + commit: 1.6.1 + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.6.4-Donut + versionCode: 106040 + commit: af881fe37 + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.6.4-Froyo + versionCode: 106041 + commit: 696ed7704 + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.6.4 + versionCode: 106042 + commit: b3b4667ccb + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.2-Donut + versionCode: 107019 + commit: a4a5e506b + forceversion: true + forcevercode: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.2-Froyo + versionCode: 107020 + commit: 33ffc7e5b + forceversion: true + forcevercode: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.2-Honeycomb + versionCode: 107021 + commit: 0520159677 + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.3-Donut + versionCode: 107040 + commit: 2c6253dd + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.3-Froyo + versionCode: 107041 + commit: 934bf7f5 + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.3-Honeycomb + versionCode: 107042 + commit: c4a3c7a9a + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.8-Donut + versionCode: 107080 + commit: c1470c9be1 + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.8-Froyo + versionCode: 107084 + commit: 1.7.8 + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.7.8-Honeycomb + versionCode: 107085 + commit: 1.7.8-ics + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + buildjni: + - yes + + - versionName: 1.8.2-Donut + versionCode: 108020 + commit: 9bec0ff445e66a + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + androidupdate: + - third-party/AmbilWarna + - . + buildjni: + - yes + + - versionName: 1.8.2-Froyo + versionCode: 108021 + commit: 0f02d4e9232227 + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + androidupdate: + - third-party/AmbilWarna + - . + buildjni: + - yes + + - versionName: 1.8.2-Honeycomb+ + versionCode: 108022 + commit: 1112df415d + forceversion: true + prebuild: + - mkdir res/drawable + - find icons -iname "*.*" -exec cp {} res/drawable \; + androidupdate: + - third-party/AmbilWarna + - . + buildjni: + - yes + + - versionName: 2.0.6-gb + versionCode: 2000610 + disable: missing res with android-9 + commit: 2.0.6 + patch: + - fbreader-2.0.6.patch + srclibs: + - PDFParseLib@36d7479ce85638eb4f0ff9c875ec77680177da5d + - ApacheHttpClient@4.2.5 + - NanoHttpd@Release-2.0.5 + - JsonSimple@tag_release_1_1_1 + forceversion: true + rm: + - libs/*jar + - obsolete/lib/*.jar + prebuild: + - echo -e "sdk.dir=$$SDK$$\nndk.dir=$$NDK$$\n" >> local.properties + - cp local.properties third-party/AmbilWarna/ + - cp local.properties third-party/android-filechooser/code/ + - cp local.properties third-party/drag-sort-listview/library/ + - pushd $$ApacheHttpClient$$/httpmime/ + - $$MVN3$$ package + - popd + - cp $$ApacheHttpClient$$/httpmime/target/httpmime-4.2.5.jar libs/ + - pushd $$NanoHttpd$$ + - $$MVN3$$ package + - popd + - cp $$NanoHttpd$$/core/target/nanohttpd-2.0.5.jar libs/ + - cp -fR $$JsonSimple$$/src/main/java/org src/ + - cp -fR $$PDFParseLib$$/pdfparse-lib/src/main/java/org src/ + - rm -fR src/com/paragon + androidupdate: + - third-party/AmbilWarna + - third-party/android-filechooser/code + - third-party/drag-sort-listview/library + - . + target: android-14 + buildjni: + - yes + + - versionName: 2.0.6-ics + versionCode: 2000620 + commit: b1dd70ff149560889e7548762046da4933e51e94 + patch: + - fbreader-2.0.6.patch + srclibs: + - FBReaderJ@2.0.6 + - PDFParseLib@36d7479ce85638eb4f0ff9c875ec77680177da5d + - ApacheHttpClient@4.2.5 + - NanoHttpd@Release-2.0.5 + - JsonSimple@tag_release_1_1_1 + forceversion: true + rm: + - libs/*jar + - obsolete/lib/*.jar + prebuild: + - echo -e "sdk.dir=$$SDK$$\nndk.dir=$$NDK$$\n" >> local.properties + - cp local.properties third-party/AmbilWarna/ + - cp local.properties third-party/android-filechooser/code/ + - cp local.properties third-party/drag-sort-listview/library/ + - pushd $$ApacheHttpClient$$/httpmime/ + - $$MVN3$$ package + - popd + - cp $$ApacheHttpClient$$/httpmime/target/httpmime-4.2.5.jar libs/ + - pushd $$NanoHttpd$$ + - $$MVN3$$ package + - popd + - cp $$NanoHttpd$$/core/target/nanohttpd-2.0.5.jar libs/ + - cp -fR $$JsonSimple$$/src/main/java/org src/ + - cp -fR $$PDFParseLib$$/pdfparse-lib/src/main/java/org src/ + - rm -fR src/com/paragon + - sed -i -e '/com.google.android.gms.version/d' -e '/google_play_services/d' AndroidManifest.xml + - sed -i -e '/google.services.lib.dir/d' project.properties + - rm -fR src/org/geometerplus/android/fbreader/network/auth + - cp -fR $$FBReaderJ$$/src/org/geometerplus/android/fbreader/network/auth src/org/geometerplus/android/fbreader/network/ + androidupdate: + - third-party/AmbilWarna + - third-party/android-filechooser/code + - third-party/drag-sort-listview/library + - . + target: android-14 + buildjni: + - yes + + - versionName: 2.1-ics + versionCode: 2010020 + commit: 33139e2b04ae36388956a57373ba74e8cc0ef23c + patch: + - fbreader-2.0.6.patch + srclibs: + - FBReaderJ@2.1 + - PDFParseLib@36d7479ce85638eb4f0ff9c875ec77680177da5d + - ApacheHttpClient@4.2.5 + - NanoHttpd@Release-2.0.5 + - JsonSimple@tag_release_1_1_1 + forceversion: true + rm: + - libs/*jar + - obsolete/lib/*.jar + prebuild: + - echo -e "sdk.dir=$$SDK$$\nndk.dir=$$NDK$$\n" >> local.properties + - cp local.properties third-party/AmbilWarna/ + - cp local.properties third-party/android-filechooser/code/ + - cp local.properties third-party/drag-sort-listview/library/ + - pushd $$ApacheHttpClient$$/httpmime/ + - $$MVN3$$ package + - popd + - cp $$ApacheHttpClient$$/httpmime/target/httpmime-4.2.5.jar libs/ + - pushd $$NanoHttpd$$ + - $$MVN3$$ package + - popd + - cp $$NanoHttpd$$/core/target/nanohttpd-2.0.5.jar libs/ + - cp -fR $$JsonSimple$$/src/main/java/org src/ + - cp -fR $$PDFParseLib$$/pdfparse-lib/src/main/java/org src/ + - rm -fR src/com/paragon + - sed -i -e '/com.google.android.gms.version/d' -e '/google_play_services/d' AndroidManifest.xml + - sed -i -e '/google.services.lib.dir/d' project.properties + - rm -fR src/org/geometerplus/android/fbreader/network/auth + - cp -fR $$FBReaderJ$$/src/org/geometerplus/android/fbreader/network/auth src/org/geometerplus/android/fbreader/network/ + androidupdate: + - third-party/AmbilWarna + - third-party/android-filechooser/code + - third-party/drag-sort-listview/library + - . + target: android-14 + buildjni: + - yes + + - versionName: 2.5.9-ics + versionCode: 2050920 + commit: 43e14feedf10ad53ec68bf42b1644f488889381c + srclibs: + - FBReaderJ@2.5.9 + - PDFParseLib@36d7479ce85638eb4f0ff9c875ec77680177da5d + - ApacheHttpClient@4.2.5 + - NanoHttpd@Release-2.0.5 + - JsonSimple@tag_release_1_1_1 + forceversion: true + rm: + - libs/*jar + - obsolete/lib/*.jar + - src/org/geometerplus/android/fbreader/dict/OpenDictionary.java + - src/org/geometerplus/android/fbreader/dict/Lingvo.java + extlibs: + - android/android-support-v4.jar + prebuild: + - echo -e "sdk.dir=$$SDK$$\nndk.dir=$$NDK$$\n" >> local.properties + - cp local.properties third-party/AmbilWarna/ + - cp local.properties third-party/android-filechooser/code/ + - cp local.properties third-party/drag-sort-listview/library/ + - echo 'APP_PLATFORM := android-11' >> jni/Application.mk + - pushd $$ApacheHttpClient$$/httpmime/ + - $$MVN3$$ package -Dmaven.javadoc.skip=true + - popd + - cp $$ApacheHttpClient$$/httpmime/target/httpmime-4.2.5.jar libs/ + - pushd $$NanoHttpd$$ + - $$MVN3$$ package + - popd + - cp $$NanoHttpd$$/core/target/nanohttpd-2.0.5.jar libs/ + - cp -fR $$JsonSimple$$/src/main/java/org src/ + - cp -fR $$PDFParseLib$$/pdfparse-lib/src/main/java/org src/ + - rm -fR src/com/paragon + - sed -i -e '/com.google.android.gms.version/d' -e '/google_play_services/d' AndroidManifest.xml + - sed -i -e '/google.services.lib.dir/d' project.properties + - mkdir third-party/drag-sort-listview/library/libs + - cp libs/android-support-v4.jar third-party/drag-sort-listview/library/libs/&& + sed -i -e '/Lingvo/d' src/org/geometerplus/android/fbreader/dict/DictionaryUtil.java + - rm -fR src/org/geometerplus/android/fbreader/network/auth + - cp -fR $$FBReaderJ$$/src/org/geometerplus/android/fbreader/network/auth src/org/geometerplus/android/fbreader/network/ + - sed -i -e '/^\s*OpenDictionary.collect/d' src/org/geometerplus/android/fbreader/dict/DictionaryUtil.java + androidupdate: + - third-party/AmbilWarna + - third-party/android-filechooser/code + - third-party/drag-sort-listview/library + - . + target: android-21 + buildjni: + - yes + +MaintainerNotes: |- + * LingvoIntegration and OpenDictionary APIs are non-free. Remove jars and patch + depending code. Currently done with rm and sed in prebuilds. + * %v tags are currently targeting gingerbread, but have ressource conflicts + with target=android-9; they build with target=android-14 + * %v-ics tags are actually based on the yotaphone branch, so we have to + use raw commits for the ice-cream-sandwich branch (look for "Merge + branch 'master' into ice-cream-sandwich" after a commit with "version + => ...") + * ics branch uses google play, so we have to sed AM.xml and ant files. + /fbreader/network/ depends on Google Play Services, so these are + removed and replaced with the master branch which does not depend on + these. + * UCM is set to master branch, we don't care for target or device specific + releases. + + TODO: + * make gingerbread/master available for android-9! + +ArchivePolicy: 6 versions +AutoUpdateMode: None +UpdateCheckMode: Tags ^[0-9.]*$ +VercodeOperation: '%c + 10' +CurrentVersion: 2.5.9 +CurrentVersionCode: 2050920 From ee162d9e623f672db0e4a2c74bb6daf1f1c19233 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 3 Jun 2020 21:30:11 +0200 Subject: [PATCH 0379/2775] gitignore tests/repo/status --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 57da9fb8..d0955dac 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ README.rst tmp/ /tests/repo/icons* /tests/repo/latestapps.dat +/tests/repo/status # files used in manual testing /config.py From ee4ee85cbd8adf108f5685cf42cc91ee80eb4d75 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 3 Jun 2020 21:41:28 +0200 Subject: [PATCH 0380/2775] update:archive_old_apks: handle apps with no CVC If an app doesn't have a CVC, we can just skip any special archive handling. Also rename weirdly named `res` to `apkList`. --- fdroidserver/update.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 06ed01de..2963071d 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -2009,19 +2009,19 @@ def make_categories_txt(repodir, categories): def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversions): - def filter_apk_list_sorted(apk_list): - res = [] + apkList = [] currentVersionApk = None for apk in apk_list: if apk['packageName'] == appid: - if apk['versionCode'] == common.version_code_string_to_int(app.CurrentVersionCode): - currentVersionApk = apk - continue - res.append(apk) + if app.CurrentVersionCode is not None: + if apk['versionCode'] == common.version_code_string_to_int(app.CurrentVersionCode): + currentVersionApk = apk + continue + apkList.append(apk) # Sort the apk list by version code. First is highest/newest. - sorted_list = sorted(res, key=lambda apk: apk['versionCode'], reverse=True) + sorted_list = sorted(apkList, key=lambda apk: apk['versionCode'], reverse=True) if currentVersionApk: # Insert apk which corresponds to currentVersion at the front sorted_list.insert(0, currentVersionApk) From 8c71637d43346ffb06c556d175d16dfb5c7c0df6 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 3 Jun 2020 22:26:03 +0200 Subject: [PATCH 0381/2775] update: make copy_triple_t_store_metadata and insert_localized_app_metadata not assume /repo This will enable copying the localized metadata to the archive as well. --- fdroidserver/update.py | 20 ++++++++++---------- tests/update.TestCase | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 2963071d..99595e86 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -977,7 +977,7 @@ def insert_funding_yml_donation_links(apps): break -def copy_triple_t_store_metadata(apps): +def copy_triple_t_store_metadata(apps, repodir): """Include store metadata from the app's source repo The Triple-T Gradle Play Publisher is a plugin that has a standard @@ -1091,14 +1091,14 @@ def copy_triple_t_store_metadata(apps): dirname = SCREENSHOT_DIRS[tt_screenshot_dirs.index(dirname)] else: locale = segments[-2] - destdir = os.path.join('repo', packageName, locale, dirname) + destdir = os.path.join(repodir, packageName, locale, dirname) os.makedirs(destdir, mode=0o755, exist_ok=True) sourcefile = os.path.join(root, f) destfile = os.path.join(destdir, repofilename) _strip_and_copy_image(sourcefile, destfile) -def insert_localized_app_metadata(apps): +def insert_localized_app_metadata(apps, repodir): """scans standard locations for graphics and localized text Scans for localized description files, changelogs, store graphics, and @@ -1113,7 +1113,7 @@ def insert_localized_app_metadata(apps): ...as well as the /metadata// directory. If it finds them, they will be added to the dict of all packages, with the - versions in the /metadata/ folder taking precendence over the what + versions in the /metadata/ folder taking precedence over the what is in the app's source repo. The is the locale of the files supplied in that directory, using @@ -1142,7 +1142,7 @@ def insert_localized_app_metadata(apps): logging.debug(packageName + ' does not have app metadata, skipping l18n scan.') continue locale = segments[-1] - destdir = os.path.join('repo', packageName, locale) + destdir = os.path.join(repodir, packageName, locale) # flavours specified in build receipt build_flavours = "" @@ -1180,7 +1180,7 @@ def insert_localized_app_metadata(apps): base, extension = common.get_extension(f) if locale == 'images': locale = segments[-2] - destdir = os.path.join('repo', packageName, locale) + destdir = os.path.join(repodir, packageName, locale) if base in GRAPHIC_NAMES and extension in ALLOWED_EXTENSIONS: os.makedirs(destdir, mode=0o755, exist_ok=True) _strip_and_copy_image(os.path.join(root, f), destdir) @@ -1188,7 +1188,7 @@ def insert_localized_app_metadata(apps): if d in SCREENSHOT_DIRS: if locale == 'images': locale = segments[-2] - destdir = os.path.join('repo', packageName, locale) + destdir = os.path.join(repodir, packageName, locale) for f in glob.glob(os.path.join(root, d, '*.*')): _ignored, extension = common.get_extension(f) if extension in ALLOWED_EXTENSIONS: @@ -1196,7 +1196,7 @@ def insert_localized_app_metadata(apps): os.makedirs(screenshotdestdir, mode=0o755, exist_ok=True) _strip_and_copy_image(f, screenshotdestdir) - repodirs = sorted(glob.glob(os.path.join('repo', '[A-Za-z]*', '[a-z][a-z]*'))) + repodirs = sorted(glob.glob(os.path.join(repodir, '[A-Za-z]*', '[a-z][a-z]*'))) for d in repodirs: if not os.path.isdir(d): continue @@ -2303,9 +2303,9 @@ def main(): logging.warning(msg + '\n\t' + _('Use `fdroid update -c` to create it.')) insert_funding_yml_donation_links(apps) - copy_triple_t_store_metadata(apps) + copy_triple_t_store_metadata(apps, repodirs[0]) insert_obbs(repodirs[0], apps, apks) - insert_localized_app_metadata(apps) + insert_localized_app_metadata(apps, repodirs[0]) translate_per_build_anti_features(apps, apks) # Scan the archive repo for apks as well diff --git a/tests/update.TestCase b/tests/update.TestCase index eee01734..11f544cd 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -103,7 +103,7 @@ class UpdateTest(unittest.TestCase): build_conversations.gradle = ['free'] apps['eu.siacs.conversations']['builds'] = [build_conversations] - fdroidserver.update.insert_localized_app_metadata(apps) + fdroidserver.update.insert_localized_app_metadata(apps, 'repo') appdir = os.path.join('repo', 'info.guardianproject.urzip', 'en-US') self.assertTrue(os.path.isfile(os.path.join( @@ -183,7 +183,7 @@ class UpdateTest(unittest.TestCase): os.chdir(tmptestsdir) apps = fdroidserver.metadata.read_metadata(xref=True) - fdroidserver.update.copy_triple_t_store_metadata(apps) + fdroidserver.update.copy_triple_t_store_metadata(apps, 'repo') # TODO ideally, this would compare the whole dict like in metadata.TestCase's test_read_metadata() correctlocales = [ @@ -211,7 +211,7 @@ class UpdateTest(unittest.TestCase): apps = fdroidserver.metadata.read_metadata(xref=True) self.assertTrue(packageName in apps) - fdroidserver.update.copy_triple_t_store_metadata(apps) + fdroidserver.update.copy_triple_t_store_metadata(apps, 'repo') correctlocales = ['de-DE', 'en-US', 'fr-FR', 'kn-IN'] app = apps[packageName] self.assertEqual('android@piwigo.org', app['authorEmail']) From e66683720b6f6e02c08d2d06f5ba55bfd33ed5a7 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 3 Jun 2020 22:27:09 +0200 Subject: [PATCH 0382/2775] move index sorting to index module This is a historic detail of the index format, so move it there. For wiki update and status json there's really no reason why this should be done in alphabetic app name order. Use the default sort order by appid. --- fdroidserver/index.py | 6 ++++-- fdroidserver/update.py | 23 +++++++++-------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 195b23e7..00d3f3f8 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -44,13 +44,12 @@ from fdroidserver.common import FDroidPopen, FDroidPopenBytes, load_stats_fdroid from fdroidserver.exception import FDroidException, VerificationException, MetaDataException -def make(apps, sortedids, apks, repodir, archive): +def make(apps, apks, repodir, archive): """Generate the repo index files. This requires properly initialized options and config objects. :param apps: fully populated apps list - :param sortedids: app package IDs, sorted :param apks: full populated apks list :param repodir: the repo directory :param archive: True if this is the archive repo, False if it's the @@ -101,6 +100,9 @@ def make(apps, sortedids, apks, repodir, archive): if mirrors: repodict['mirrors'] = mirrors + # Historically the index has been sorted by App Name, so we enforce this ordering here + sortedids = sorted(apps, key=lambda appid: apps[appid].Name.upper()) + appsWithPackages = collections.OrderedDict() for packageName in sortedids: app = apps[packageName] diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 99595e86..f2575f07 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -126,7 +126,7 @@ def disabled_algorithms_allowed(): return options.allow_disabled_algorithms or config['allow_disabled_algorithms'] -def status_update_json(apps, sortedids, apks): +def status_update_json(apps, apks): """Output a JSON file with metadata about this `fdroid update` run :param apps: fully populated list of all applications @@ -141,7 +141,7 @@ def status_update_json(apps, sortedids, apks): output['failedBuilds'] = dict() output['noPackages'] = [] - for appid in sortedids: + for appid in apps: app = apps[appid] for af in app.get('AntiFeatures', []): antiFeatures = output['antiFeatures'] # JSON camelCase @@ -177,7 +177,7 @@ def status_update_json(apps, sortedids, apks): common.write_status_json(output, options.pretty) -def update_wiki(apps, sortedids, apks): +def update_wiki(apps, apks): """Update the wiki :param apps: fully populated list of all applications @@ -193,7 +193,7 @@ def update_wiki(apps, sortedids, apks): generated_pages = {} generated_redirects = {} - for appid in sortedids: + for appid in apps: app = metadata.App(apps[appid]) wikidata = '' @@ -2319,11 +2319,6 @@ def main(): # Apply information from latest apks to the application and update dates apply_info_from_latest_apk(apps, apks + archapks) - # Sort the app list by name, then the web site doesn't have to by default. - # (we had to wait until we'd scanned the apks to do this, because mostly the - # name comes from there!) - sortedids = sorted(apps.keys(), key=lambda appid: apps[appid].Name.upper()) - # APKs are placed into multiple repos based on the app package, providing # per-app subscription feeds for nightly builds and things like it if config['per_app_repos']: @@ -2333,7 +2328,7 @@ def main(): appdict = dict() appdict[appid] = app if os.path.isdir(repodir): - index.make(appdict, [appid], apks, repodir, False) + index.make(appdict, apks, repodir, False) else: logging.info(_('Skipping index generation for {appid}').format(appid=appid)) return @@ -2342,7 +2337,7 @@ def main(): archive_old_apks(apps, apks, archapks, repodirs[0], repodirs[1], config['archive_older']) # Make the index for the main repo... - index.make(apps, sortedids, apks, repodirs[0], False) + index.make(apps, apks, repodirs[0], False) make_categories_txt(repodirs[0], categories) # If there's an archive repo, make the index for it. We already scanned it @@ -2350,7 +2345,7 @@ def main(): if len(repodirs) > 1: archived_apps = copy.deepcopy(apps) apply_info_from_latest_apk(archived_apps, archapks) - index.make(archived_apps, sortedids, archapks, repodirs[1], True) + index.make(archived_apps, archapks, repodirs[1], True) git_remote = config.get('binary_transparency_remote') if git_remote or os.path.isdir(os.path.join('binary_transparency', '.git')): @@ -2381,8 +2376,8 @@ def main(): # Update the wiki... if options.wiki: - update_wiki(apps, sortedids, apks + archapks) - status_update_json(apps, sortedids, apks + archapks) + update_wiki(apps, apks + archapks) + status_update_json(apps, apks + archapks) logging.info(_("Finished")) From d720c99ae517384b7f1d445108a40067b9097b52 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 3 Jun 2020 22:28:18 +0200 Subject: [PATCH 0383/2775] refactor update.py:main This makes update.py:main a lot saner by removing a lot of the implicit assumptions between the different stages of generating the repository index. * mostly unify repo and archive processing, that means the archive is now actually getting the same treatment regarding i.e. fastlane data. Previously the archive didn't get considered at all here. * already filter the list of apps to include in a repo in update.py and give that prefiltered list to index. This makes sure we actually only copy fastlane/triple-t/etc. stuff for apps ending up in the index. This both, can save a lot of time if there are a lot of old /build dirs lying around and doesn't clutter /repo with things that aren't referenced from the index. Closes fdroid/fdroidserver#524 --- fdroidserver/index.py | 36 ++++++---------- fdroidserver/update.py | 97 +++++++++++++++++++++++++++++++++--------- 2 files changed, 90 insertions(+), 43 deletions(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 00d3f3f8..af5c3522 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -21,7 +21,6 @@ # along with this program. If not, see . import collections -import copy import json import logging import os @@ -41,7 +40,7 @@ from . import metadata from . import net from . import signindex from fdroidserver.common import FDroidPopen, FDroidPopenBytes, load_stats_fdroid_signing_key_fingerprints -from fdroidserver.exception import FDroidException, VerificationException, MetaDataException +from fdroidserver.exception import FDroidException, VerificationException def make(apps, apks, repodir, archive): @@ -49,8 +48,9 @@ def make(apps, apks, repodir, archive): This requires properly initialized options and config objects. - :param apps: fully populated apps list - :param apks: full populated apks list + :param apps: OrderedDict of apps to go into the index, each app should have + at least one associated apk + :param apks: list of apks to go into the index :param repodir: the repo directory :param archive: True if this is the archive repo, False if it's the main one. @@ -60,6 +60,12 @@ def make(apps, apks, repodir, archive): if not common.options.nosign: common.assert_config_keystore(common.config) + # Historically the index has been sorted by App Name, so we enforce this ordering here + sortedids = sorted(apps, key=lambda appid: apps[appid].Name.upper()) + sortedapps = collections.OrderedDict() + for appid in sortedids: + sortedapps[appid] = apps[appid] + repodict = collections.OrderedDict() repodict['timestamp'] = datetime.utcnow().replace(tzinfo=timezone.utc) repodict['version'] = METADATA_VERSION @@ -100,24 +106,6 @@ def make(apps, apks, repodir, archive): if mirrors: repodict['mirrors'] = mirrors - # Historically the index has been sorted by App Name, so we enforce this ordering here - sortedids = sorted(apps, key=lambda appid: apps[appid].Name.upper()) - - appsWithPackages = collections.OrderedDict() - for packageName in sortedids: - app = apps[packageName] - if app['Disabled']: - continue - - # only include apps with packages - for apk in apks: - if apk['packageName'] == packageName: - newapp = copy.copy(app) # update wiki needs unmodified description - newapp['Description'] = metadata.description_html(app['Description'], - metadata.DescriptionResolver(apps)) - appsWithPackages[packageName] = newapp - break - requestsdict = collections.OrderedDict() for command in ('install', 'uninstall'): packageNames = [] @@ -133,9 +121,9 @@ def make(apps, apks, repodir, archive): fdroid_signing_key_fingerprints = load_stats_fdroid_signing_key_fingerprints() - make_v0(appsWithPackages, apks, repodir, repodict, requestsdict, + make_v0(sortedapps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fingerprints) - make_v1(appsWithPackages, apks, repodir, repodict, requestsdict, + make_v1(sortedapps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fingerprints) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index f2575f07..64c5c6b3 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -2166,6 +2166,71 @@ def create_metadata_from_template(apk): logging.info(_("Generated skeleton metadata for {appid}").format(appid=apk['packageName'])) +def read_names_from_apks(apps, apks): + """This is a stripped down copy of apply_info_from_latest_apk that only parses app names""" + for appid, app in apps.items(): + bestver = UNSET_VERSION_CODE + for apk in apks: + if apk['packageName'] == appid: + if apk['versionCode'] > bestver: + bestver = apk['versionCode'] + bestapk = apk + + if bestver == UNSET_VERSION_CODE: + if app.Name is None: + app.Name = app.AutoName or appid + app.icon = None + else: + if app.Name is None: + app.Name = bestapk['name'] + + +def render_app_descriptions(apps, all_apps): + """ + Renders the app html description. + For resolving inter-app links it needs the full list of apps, even if they end up in + separate repos (i.e. archive or per app repos). + """ + for app in apps.values(): + app['Description'] = metadata.description_html(app['Description'], metadata.DescriptionResolver(all_apps)) + + +def get_apps_with_packages(apps, apks): + """Returns a deepcopy of that subset apps that actually has any associated packages. Skips disabled apps.""" + appsWithPackages = collections.OrderedDict() + for packageName in apps: + app = apps[packageName] + if app['Disabled']: + continue + + # only include apps with packages + for apk in apks: + if apk['packageName'] == packageName: + newapp = copy.copy(app) + appsWithPackages[packageName] = newapp + break + return appsWithPackages + + +def prepare_apps(apps, apks, repodir): + """Encapsulates all necessary preparation steps before we can build an index out of apps and apks. + + :param apps: All apps as read from metadata + :param apks: list of apks that belong into repo, this gets modified in place + :param repodir: the target repository directory, metadata files will be copied here + :return: the relevant subset of apps (as a deepcopy) + """ + apps_with_packages = get_apps_with_packages(apps, apks) + apply_info_from_latest_apk(apps_with_packages, apks) + render_app_descriptions(apps_with_packages, apps) + insert_funding_yml_donation_links(apps) + copy_triple_t_store_metadata(apps_with_packages, repodir) + insert_obbs(repodir, apps_with_packages, apks) + translate_per_build_anti_features(apps_with_packages, apks) + insert_localized_app_metadata(apps_with_packages, repodir) + return apps_with_packages + + config = None options = None start_timestamp = time.gmtime() @@ -2302,12 +2367,6 @@ def main(): else: logging.warning(msg + '\n\t' + _('Use `fdroid update -c` to create it.')) - insert_funding_yml_donation_links(apps) - copy_triple_t_store_metadata(apps, repodirs[0]) - insert_obbs(repodirs[0], apps, apks) - insert_localized_app_metadata(apps, repodirs[0]) - translate_per_build_anti_features(apps, apks) - # Scan the archive repo for apks as well if len(repodirs) > 1: archapks, cc = process_apks(apkcache, repodirs[1], knownapks, options.use_date_from_apk) @@ -2316,8 +2375,18 @@ def main(): else: archapks = [] - # Apply information from latest apks to the application and update dates - apply_info_from_latest_apk(apps, apks + archapks) + # We need app.Name populated for all apps regardless of which repo they end up in + # for the old-style inter-app links, so let's do it before we do anything else. + # This will be done again (as part of apply_info_from_latest_apk) for repo and archive + # separately later on, but it's fairly cheap anyway. + read_names_from_apks(apps, apks + archapks) + + if len(repodirs) > 1: + archive_old_apks(apps, apks, archapks, repodirs[0], repodirs[1], config['archive_older']) + archived_apps = prepare_apps(apps, archapks, repodirs[1]) + index.make(archived_apps, archapks, repodirs[1], True) + + repoapps = prepare_apps(apps, apks, repodirs[0]) # APKs are placed into multiple repos based on the app package, providing # per-app subscription feeds for nightly builds and things like it @@ -2333,20 +2402,10 @@ def main(): logging.info(_('Skipping index generation for {appid}').format(appid=appid)) return - if len(repodirs) > 1: - archive_old_apks(apps, apks, archapks, repodirs[0], repodirs[1], config['archive_older']) - # Make the index for the main repo... - index.make(apps, apks, repodirs[0], False) + index.make(repoapps, apks, repodirs[0], False) make_categories_txt(repodirs[0], categories) - # If there's an archive repo, make the index for it. We already scanned it - # earlier on. - if len(repodirs) > 1: - archived_apps = copy.deepcopy(apps) - apply_info_from_latest_apk(archived_apps, archapks) - index.make(archived_apps, archapks, repodirs[1], True) - git_remote = config.get('binary_transparency_remote') if git_remote or os.path.isdir(os.path.join('binary_transparency', '.git')): from . import btlog From 07caa889205edb94955c6c26946a77bfc426edac Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 24 Jun 2020 17:14:01 +0200 Subject: [PATCH 0384/2775] don't include the localized metadata things for /archive We haven't done this so far and it's a potential big change in archive size and update performance. --- fdroidserver/update.py | 22 +++++++++++++--------- tests/update.TestCase | 6 +++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 64c5c6b3..babc3254 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -977,7 +977,7 @@ def insert_funding_yml_donation_links(apps): break -def copy_triple_t_store_metadata(apps, repodir): +def copy_triple_t_store_metadata(apps): """Include store metadata from the app's source repo The Triple-T Gradle Play Publisher is a plugin that has a standard @@ -1091,14 +1091,14 @@ def copy_triple_t_store_metadata(apps, repodir): dirname = SCREENSHOT_DIRS[tt_screenshot_dirs.index(dirname)] else: locale = segments[-2] - destdir = os.path.join(repodir, packageName, locale, dirname) + destdir = os.path.join('repo', packageName, locale, dirname) os.makedirs(destdir, mode=0o755, exist_ok=True) sourcefile = os.path.join(root, f) destfile = os.path.join(destdir, repofilename) _strip_and_copy_image(sourcefile, destfile) -def insert_localized_app_metadata(apps, repodir): +def insert_localized_app_metadata(apps): """scans standard locations for graphics and localized text Scans for localized description files, changelogs, store graphics, and @@ -1142,7 +1142,7 @@ def insert_localized_app_metadata(apps, repodir): logging.debug(packageName + ' does not have app metadata, skipping l18n scan.') continue locale = segments[-1] - destdir = os.path.join(repodir, packageName, locale) + destdir = os.path.join('repo', packageName, locale) # flavours specified in build receipt build_flavours = "" @@ -1180,7 +1180,7 @@ def insert_localized_app_metadata(apps, repodir): base, extension = common.get_extension(f) if locale == 'images': locale = segments[-2] - destdir = os.path.join(repodir, packageName, locale) + destdir = os.path.join('repo', packageName, locale) if base in GRAPHIC_NAMES and extension in ALLOWED_EXTENSIONS: os.makedirs(destdir, mode=0o755, exist_ok=True) _strip_and_copy_image(os.path.join(root, f), destdir) @@ -1188,7 +1188,7 @@ def insert_localized_app_metadata(apps, repodir): if d in SCREENSHOT_DIRS: if locale == 'images': locale = segments[-2] - destdir = os.path.join(repodir, packageName, locale) + destdir = os.path.join('repo', packageName, locale) for f in glob.glob(os.path.join(root, d, '*.*')): _ignored, extension = common.get_extension(f) if extension in ALLOWED_EXTENSIONS: @@ -1196,7 +1196,7 @@ def insert_localized_app_metadata(apps, repodir): os.makedirs(screenshotdestdir, mode=0o755, exist_ok=True) _strip_and_copy_image(f, screenshotdestdir) - repodirs = sorted(glob.glob(os.path.join(repodir, '[A-Za-z]*', '[a-z][a-z]*'))) + repodirs = sorted(glob.glob(os.path.join('repo', '[A-Za-z]*', '[a-z][a-z]*'))) for d in repodirs: if not os.path.isdir(d): continue @@ -2224,10 +2224,14 @@ def prepare_apps(apps, apks, repodir): apply_info_from_latest_apk(apps_with_packages, apks) render_app_descriptions(apps_with_packages, apps) insert_funding_yml_donation_links(apps) - copy_triple_t_store_metadata(apps_with_packages, repodir) + # This is only currently done for /repo because doing it for the archive + # will take a lot of time and bloat the archive mirrors and index + if repodir == 'repo': + copy_triple_t_store_metadata(apps_with_packages) insert_obbs(repodir, apps_with_packages, apks) translate_per_build_anti_features(apps_with_packages, apks) - insert_localized_app_metadata(apps_with_packages, repodir) + if repodir == 'repo': + insert_localized_app_metadata(apps_with_packages) return apps_with_packages diff --git a/tests/update.TestCase b/tests/update.TestCase index 11f544cd..eee01734 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -103,7 +103,7 @@ class UpdateTest(unittest.TestCase): build_conversations.gradle = ['free'] apps['eu.siacs.conversations']['builds'] = [build_conversations] - fdroidserver.update.insert_localized_app_metadata(apps, 'repo') + fdroidserver.update.insert_localized_app_metadata(apps) appdir = os.path.join('repo', 'info.guardianproject.urzip', 'en-US') self.assertTrue(os.path.isfile(os.path.join( @@ -183,7 +183,7 @@ class UpdateTest(unittest.TestCase): os.chdir(tmptestsdir) apps = fdroidserver.metadata.read_metadata(xref=True) - fdroidserver.update.copy_triple_t_store_metadata(apps, 'repo') + fdroidserver.update.copy_triple_t_store_metadata(apps) # TODO ideally, this would compare the whole dict like in metadata.TestCase's test_read_metadata() correctlocales = [ @@ -211,7 +211,7 @@ class UpdateTest(unittest.TestCase): apps = fdroidserver.metadata.read_metadata(xref=True) self.assertTrue(packageName in apps) - fdroidserver.update.copy_triple_t_store_metadata(apps, 'repo') + fdroidserver.update.copy_triple_t_store_metadata(apps) correctlocales = ['de-DE', 'en-US', 'fr-FR', 'kn-IN'] app = apps[packageName] self.assertEqual('android@piwigo.org', app['authorEmail']) From 3ebc44c54ff47337c1a666df91d9f4245cfd97a5 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 24 Jun 2020 20:30:26 +0200 Subject: [PATCH 0385/2775] fix tests after they switched to yaml --- tests/metadata.TestCase | 1 - tests/run-tests | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 49151083..f9ba731d 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -906,7 +906,6 @@ class MetadataTest(unittest.TestCase): 'Prepare': None}}) def test_read_xref_metadata(self): - fdroidserver.common.config = {'accepted_formats': ['yml']} os.chdir('xref') fdroidserver.metadata.warnings_action = 'error' apps = fdroidserver.metadata.read_metadata(xref=True) diff --git a/tests/run-tests b/tests/run-tests index d685ea1f..a5435351 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -612,12 +612,11 @@ echo_header "test whatsnew from fastlane without CVC set" REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo "accepted_formats = ['txt', 'yml']" >> config.py mkdir -p metadata/com.politedroid/en-US/changelogs/ cp $WORKSPACE/tests/repo/com.politedroid_6.apk repo -cp $WORKSPACE/tests/metadata/com.politedroid.txt metadata +cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata echo "whatsnew test" > metadata/com.politedroid/en-US/changelogs/6.txt -sed -i -e '/Current Version/d' metadata/com.politedroid.txt +sed -i -e '/CurrentVersion/d' metadata/com.politedroid.yml $fdroid update --pretty --nosign grep -F 'whatsnew' repo/index-v1.json From f70a4e11dd753e0202ccae28862de64ab3314c1e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 25 Jun 2020 11:52:15 +0200 Subject: [PATCH 0386/2775] jenkins-setup-build-environment: --skip-scan on old builds The scanner has gotten stricter: !758 [skip ci] since this only affects jenkins.debian.net --- jenkins-setup-build-environment | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index 8c483a90..3a0c6c6d 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -112,6 +112,6 @@ fi # if it can't build fdroid, then its really broken ../fdroid build --verbose --stop --latest org.fdroid.fdroid # Gradle, JNI, preassemble -../fdroid build --verbose --stop org.adaway:55 +../fdroid build --verbose -stop --skip-scan org.adaway:55 # building old versions should still work -../fdroid build --verbose --stop org.fdroid.fdroid:102350 +../fdroid build --verbose --stop --skip-scan org.fdroid.fdroid:102350 From e659a5353dea91bf964585c68bf35a9314ec0656 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 25 Jun 2020 18:06:35 +0200 Subject: [PATCH 0387/2775] provision-apt-get-install: gpg needs to come from stretch-backports https://gitlab.com/eighthave/fdroiddata/-/jobs/611438997 Otherwise it fails to install: ``` gpg : Depends: gpgconf (= 2.2.20-1~bpo9+1) Depends: libassuan0 (>= 2.5.0) but 2.4.3-2 is to be installed Depends: libgpg-error0 (>= 1.35) but 1.26-2 is to be installed ``` * 7e8c244473d2a163a12719efd8ab55f6230acee9 * !769 --- buildserver/provision-apt-get-install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index d4481b32..89ed189f 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -71,7 +71,7 @@ packages=" git-core git-svn gperf - gpg + gpg/stretch-backports javacc libarchive-zip-perl libexpat1-dev From 174bbf0bdcb13ae85b4ceee6ddb450a2286276be Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 29 Jun 2020 09:56:37 +0200 Subject: [PATCH 0388/2775] jenkins-setup-build-environment: fix my stoopid typo --- jenkins-setup-build-environment | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index 3a0c6c6d..c47359b0 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -112,6 +112,6 @@ fi # if it can't build fdroid, then its really broken ../fdroid build --verbose --stop --latest org.fdroid.fdroid # Gradle, JNI, preassemble -../fdroid build --verbose -stop --skip-scan org.adaway:55 +../fdroid build --verbose --stop --skip-scan org.adaway:55 # building old versions should still work ../fdroid build --verbose --stop --skip-scan org.fdroid.fdroid:102350 From d8b73dd241aadc3bb01adfac40af449f855edcff Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sat, 4 Jul 2020 18:56:10 +0200 Subject: [PATCH 0389/2775] Add timstamp to logs --- fdroidserver/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index 770d8c13..4d0c4785 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -173,7 +173,7 @@ def main(): quiet = any(s in sys.argv for s in ['-q', '--quiet']) # Helpful to differentiate warnings from errors even when on quiet - logformat = '%(levelname)s: %(message)s' + logformat = '%(asctime)s %(levelname)s: %(message)s' loglevel = logging.INFO if verbose: loglevel = logging.DEBUG From 393f08ff25e1d104dfdddbf8a3d1d289d9489a05 Mon Sep 17 00:00:00 2001 From: xynngh Date: Tue, 7 Jul 2020 14:02:56 +0400 Subject: [PATCH 0390/2775] Add gradle 6.5.1 --- gradlew-fdroid | 3 ++- makebuildserver | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index bd290a66..9e76fb35 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -138,6 +138,7 @@ get_sha() { '6.4') echo 'b888659f637887e759749f6226ddfcb1cb04f828c58c41279de73c463fdbacc9' ;; '6.4.1') echo 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd' ;; '6.5') echo '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f' ;; + '6.5.1') echo '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a' ;; *) exit 1 esac } @@ -158,7 +159,7 @@ d_plugin_k=(4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 d_plugin_v=(6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 3600422a..11a1d1cf 100755 --- a/makebuildserver +++ b/makebuildserver @@ -376,6 +376,8 @@ CACHE_FILES = [ 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd'), ('https://services.gradle.org/distributions/gradle-6.5-bin.zip', '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f'), + ('https://services.gradle.org/distributions/gradle-6.5.1-bin.zip', + '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From cfed640adcf9005c396b20080b3bf1dbf0b6e990 Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Sat, 18 Jul 2020 19:17:42 -0400 Subject: [PATCH 0391/2775] Add buildTools 30.0.1 --- makebuildserver | 2 ++ 1 file changed, 2 insertions(+) diff --git a/makebuildserver b/makebuildserver index 11a1d1cf..7328b622 100755 --- a/makebuildserver +++ b/makebuildserver @@ -260,6 +260,8 @@ CACHE_FILES = [ '5652d8cd5eaaade0b853bfe0ae6cbfa0706a6f70a0ebb25ca24a6f484ec3d855'), ('https://dl.google.com/android/repository/build-tools_r30-linux.zip', 'ed3b7f9b2d15e90a12c2e739adb749d7d834e2f953e677380206bd14db135c6c'), + ('https://dl.google.com/android/repository/build-tools_r30.0.1-linux.zip', + '560eace2cc6ca16011fbb97c92c39aa0441d54dbfc13837dfbdb4a6bdf9c9da8'), ('https://services.gradle.org/distributions/gradle-2.2.1-bin.zip', '420aa50738299327b611c10b8304b749e8d3a579407ee9e755b15921d95ff418'), ('https://services.gradle.org/distributions/gradle-2.3-bin.zip', From 3de9e46702a08dab85a1ee0518e47886f5658453 Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Sat, 18 Jul 2020 19:22:50 -0400 Subject: [PATCH 0392/2775] Add platform-29_r04 --- makebuildserver | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makebuildserver b/makebuildserver index 7328b622..5442cbab 100755 --- a/makebuildserver +++ b/makebuildserver @@ -198,8 +198,8 @@ CACHE_FILES = [ '020c4c090bc82ce87ebaae5d1a922e21b39a1d03c78ffa43f0c3e42fc7d28169'), ('https://dl.google.com/android/repository/platform-28_r06.zip', '8452dbbf9668a428abb243c4f02a943b7aa83af3cca627629a15c4c09f28e7bd'), - ('https://dl.google.com/android/repository/platform-29_r02.zip', - 'de5b5a88e3ba94e3d83972ffe6d0b7f97088998f84a3c1b7c0848aa7951ac7f4'), + ('https://dl.google.com/android/repository/platform-29_r04.zip', + 'c9eaf2ce4e8fa6f5a8036bd3c95363d003733bf0a1bd349718cadf802db44c69'), ('https://dl.google.com/android/repository/build-tools_r19.1-linux.zip', '3833b409f78c002a83244e220be380ea6fa44d604e0d47de4b7e5daefe7cd3f4'), ('https://dl.google.com/android/repository/build-tools_r20-linux.zip', From d4296fdf3b96fb91b752f892f2841f78828bcd34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 22 Jul 2020 13:09:26 +0200 Subject: [PATCH 0393/2775] add official checksums for basebox-buster64 0.6.0 --- makebuildserver | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/makebuildserver b/makebuildserver index 5442cbab..6ea403ca 100755 --- a/makebuildserver +++ b/makebuildserver @@ -46,6 +46,19 @@ tail = None BASEBOX_DEFAULT = 'fdroid/basebox-stretch64' BASEBOX_VERSION_DEFAULT = '0.5.1' BASEBOX_CHECKSUMS = { + '0.6.0': { + 'libvirt': { + 'box.img': '82c2c3548cf48f0f4c6601f40f8bec36ff37e9a74d6f717067a526250ad790ad', + 'metadata.json': '9b5f62362ce3cd25c50881d8ae124879fc21ed4fdb16cc78d57058f116680f25', + 'Vagrantfile': '4435901624f21dad201c3bd7f0d8d4ece842bc9fbbb70e312eee54f07173f24e', + }, + 'vritualbox': { + 'box-disk1.vmdk': '6b536f26dcee137aca9a3f5f6f20aef795193ef2e8c387a0ffbdb7c5fe2ec0fb', + 'box.ovf': 'cbdd6315187d4ce8ff15ed5a00a2c8b0d33abe6b0356439ce4d8d9ac3724f875', + 'metadata.json': '098439524f76cafe026140b787ca419297a055a3f6006b9d60e6d5326d18ba99', + 'Vagrantfile': '95c64a0e82a6420845c05038c4c97b3aba629b09eb2b78e879423d06f6b54a54', + } + }, '0.5.1': { 'libvirt': { 'box.img': 'ad015940b866e36a593ef5fa0035ec6703f74a7f082ab76a1d2bd9463714cd4a', From 10fa912c16e5b1df105792d7bbd869a77b28ab2d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 9 Jul 2020 09:34:04 +0200 Subject: [PATCH 0394/2775] deploy: remove git remotes not enabled in servergitmirrors If the repo operator removes an item from servergitmirrors, it should auto- matically remove the remote. --- fdroidserver/server.py | 14 ++++++++++---- tests/server.TestCase | 13 +++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index cc930eb6..d406da1d 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -45,6 +45,7 @@ BINARY_TRANSPARENCY_DIR = 'binary_transparency' AUTO_S3CFG = '.fdroid-server-update-s3cfg' USER_S3CFG = 's3cfg' +REMOTE_HOSTNAME_REGEX = re.compile(r'\W*\w+\W+(\w+).*') def update_awsbucket(repo_section): @@ -384,15 +385,17 @@ def update_servergitmirrors(servergitmirrors, repo_section): repo = git.Repo.init(git_mirror_path) + enabled_remotes = [] for remote_url in servergitmirrors: - hostname = re.sub(r'\W*\w+\W+(\w+).*', r'\1', remote_url) - r = git.remote.Remote(repo, hostname) + name = REMOTE_HOSTNAME_REGEX.sub(r'\1', remote_url) + enabled_remotes.append(name) + r = git.remote.Remote(repo, name) if r in repo.remotes: - r = repo.remote(hostname) + r = repo.remote(name) if 'set_url' in dir(r): # force remote URL if using GitPython 2.x r.set_url(remote_url) else: - repo.create_remote(hostname, remote_url) + repo.create_remote(name, remote_url) logging.info('Mirroring to: ' + remote_url) # sadly index.add don't allow the --all parameter @@ -414,6 +417,9 @@ def update_servergitmirrors(servergitmirrors, repo_section): # push for every remote. This will overwrite the git history for remote in repo.remotes: + if remote.name not in enabled_remotes: + repo.delete_remote(remote) + continue if remote.name == 'gitlab': logging.debug('Writing .gitlab-ci.yml to deploy to GitLab Pages') with open(os.path.join(git_mirror_path, ".gitlab-ci.yml"), "wt") as out_file: diff --git a/tests/server.TestCase b/tests/server.TestCase index 8bd769ea..4236d6e5 100755 --- a/tests/server.TestCase +++ b/tests/server.TestCase @@ -148,6 +148,19 @@ class ServerTest(unittest.TestCase): virustotal_apikey = os.getenv('VIRUSTOTAL_API_KEY') fdroidserver.server.upload_to_virustotal('repo', virustotal_apikey) + def test_remote_hostname_regex(self): + for remote_url, name in ( + ('git@github.com:guardianproject/fdroid-repo', 'github'), + ('git@gitlab.com:guardianproject/fdroid-repo', 'gitlab'), + ('https://github.com:guardianproject/fdroid-repo', 'github'), + ('https://gitlab.com/guardianproject/fdroid-repo', 'gitlab'), + ('https://salsa.debian.org/foo/repo', 'salsa'), + ): + self.assertEqual( + name, + fdroidserver.server.REMOTE_HOSTNAME_REGEX.sub(r'\1', remote_url) + ) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 2858c73b871c539d67766309568cf78937e6e210 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 30 Jul 2020 14:55:46 +0200 Subject: [PATCH 0395/2775] gradlew-fdroid: more robust method for handling Windows linefeeds The bash pattern matching was getting confused by the Windows linefeeds, this strips them before the string hits the bash pattern tricks. * https://github.com/premnirmal/StockTicker/issues/145 --- gradlew-fdroid | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 9e76fb35..a0b02d24 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -167,10 +167,10 @@ v_all=${plugin_v[@]} for f in {.,..}/gradle/wrapper/gradle-wrapper.properties; do [[ -f $f ]] || continue while IFS='' read -r line || [ -n "$line" ]; do + line=$(printf $line | tr -d '\r') # strip Windows linefeeds if [[ $line == 'distributionUrl='* ]]; then wrapper_ver=${line#*/gradle-} wrapper_ver=${wrapper_ver%-*.zip} - wrapper_ver=$(printf $wrapper_ver | tr -d '\r') # strip Windows linefeeds break 2 fi done < $f @@ -186,14 +186,13 @@ fi for f in {.,..}/build.gradle{,.kts}; do [[ -f $f ]] || continue while IFS='' read -r line || [ -n "$line" ]; do + line=$(printf $line | tr -d '\r') # strip Windows linefeeds if [[ -z "$plugin_pver" && $line == *'com.android.tools.build:gradle:'* ]]; then plugin_pver=${line#*[\'\"]com.android.tools.build:gradle:} plugin_pver=${plugin_pver%[\'\"]*} - plugin_pver=$(printf $plugin_pver | tr -d '\r') # strip Windows linefeeds elif [[ -z "$wrapper_ver" && $line == *'gradleVersion = '* ]]; then wrapper_ver=${line#*gradleVersion*=*[\'\"]} wrapper_ver=${wrapper_ver%[\'\"]*} - wrapper_ver=$(printf $wrapper_ver | tr -d '\r') # strip Windows linefeeds fi done < $f done From 960d31af2a27625cb0d1f0dac9b2fe9c9a92ba06 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 7 Jul 2020 10:20:03 +0200 Subject: [PATCH 0396/2775] import: standardize on 'appid' var name for Application ID The rest of the fdroidserver code uses 'appid' or 'packageName'. The official Android name is "Application ID". "Package Name" is the Java term, and it is used in Android in Java code. --- fdroidserver/import.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index a6098202..c7286e08 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -127,9 +127,9 @@ def main(): paths = common.get_all_gradle_and_manifests(tmp_importer_dir) subdir = common.get_gradle_subdir(tmp_importer_dir, paths) if paths: - versionName, versionCode, package = common.parse_androidmanifests(paths, app) - if not package: - raise FDroidException(_("Couldn't find package ID")) + versionName, versionCode, appid = common.parse_androidmanifests(paths, app) + if not appid: + raise FDroidException(_("Couldn't find Application ID")) if not versionName: logging.warning(_('Could not find latest version name')) if not versionCode: @@ -138,8 +138,8 @@ def main(): raise FDroidException(_("No gradle project could be found. Specify --subdir?")) # Make sure it's actually new... - if package in apps: - raise FDroidException("Package " + package + " already exists") + if appid in apps: + raise FDroidException(_('Package "{appid}" already exists').format(appid=appid)) # Create a build line... build.versionName = versionName or 'Unknown' @@ -205,17 +205,17 @@ def main(): # Keep the repo directory to save bandwidth... if not os.path.exists('build'): os.mkdir('build') - build_dir = os.path.join('build', package) + build_dir = os.path.join('build', appid) if os.path.exists(build_dir): logging.warning(_('{path} already exists, ignoring import results!') .format(path=build_dir)) sys.exit(1) elif tmp_importer_dir is not None: shutil.move(tmp_importer_dir, build_dir) - with open('build/.fdroidvcs-' + package, 'w') as f: + with open('build/.fdroidvcs-' + appid, 'w') as f: f.write(app.RepoType + ' ' + app.Repo) - metadatapath = os.path.join('metadata', package + '.yml') + metadatapath = os.path.join('metadata', appid + '.yml') metadata.write_metadata(metadatapath, app) logging.info("Wrote " + metadatapath) From a6c60a908aae94c146c3ab03c91751c58425b1f3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 23 Jul 2020 13:03:20 +0200 Subject: [PATCH 0397/2775] import: add support for kivy buildozer projects --- fdroidserver/import.py | 43 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/fdroidserver/import.py b/fdroidserver/import.py index c7286e08..48af3b9c 100644 --- a/fdroidserver/import.py +++ b/fdroidserver/import.py @@ -17,6 +17,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import configparser import git import json import os @@ -58,6 +59,44 @@ def clone_to_tmp_dir(app): return tmp_dir +def check_for_kivy_buildozer(tmp_importer_dir, app, build): + versionCode = None + buildozer_spec = os.path.join(tmp_importer_dir, 'buildozer.spec') + if os.path.exists(buildozer_spec): + config = configparser.ConfigParser() + config.read(buildozer_spec) + import pprint + pprint.pprint(sorted(config['app'].keys())) + app.id = config['app'].get('package.domain') + print(app.id) + app.AutoName = config['app'].get('package.name', app.AutoName) + app.License = config['app'].get('license', app.License) + app.Description = config['app'].get('description', app.Description) + build.versionName = config['app'].get('version') + build.output = 'bin/%s-$$VERSION$$-release-unsigned.apk' % app.AutoName + build.ndk = 'r17c' + build.srclibs = [ + 'buildozer@586152c', + 'python-for-android@ccb0f8e1', + ] + build.sudo = [ + 'apt-get update', + 'apt-get install -y build-essential libffi-dev libltdl-dev', + ] + build.prebuild = [ + 'sed -iE "/^[# ]*android\\.(ant|ndk|sdk)_path[ =]/d" buildozer.spec', + 'sed -iE "/^[# ]*android.accept_sdk_license[ =]+.*/d" buildozer.spec', + 'sed -iE "/^[# ]*android.skip_update[ =]+.*/d" buildozer.spec', + 'sed -iE "/^[# ]*p4a.source_dir[ =]+.*/d" buildozer.spec', + 'sed -i "s,\\[app\\],[app]\\n\\nandroid.sdk_path = $$SDK$$\\nandroid.ndk_path = $$NDK$$\\np4a.source_dir = $$python-for-android$$\\nandroid.accept_sdk_license = False\\nandroid.skip_update = True\\nandroid.ant_path = /usr/bin/ant\\n," buildozer.spec', + 'pip3 install --user --upgrade $$buildozer$$ Cython==0.28.6', + ] + build.build = [ + 'PATH="$HOME/.local/bin:$PATH" buildozer android release', + ] + return build.get('versionName'), versionCode, app.get('id') + + def main(): global config, options @@ -123,6 +162,8 @@ def main(): app.UpdateCheckMode = 'Tags' build.commit = common.get_head_commit_id(git_repo) + versionName, versionCode, appid = check_for_kivy_buildozer(tmp_importer_dir, app, build) + # Extract some information... paths = common.get_all_gradle_and_manifests(tmp_importer_dir) subdir = common.get_gradle_subdir(tmp_importer_dir, paths) @@ -134,7 +175,7 @@ def main(): logging.warning(_('Could not find latest version name')) if not versionCode: logging.warning(_('Could not find latest version code')) - else: + elif not appid: raise FDroidException(_("No gradle project could be found. Specify --subdir?")) # Make sure it's actually new... From 54257f8f6a5130333a589d31d41df840c155ec86 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 4 Aug 2020 17:20:55 +0200 Subject: [PATCH 0398/2775] init: generate opensc-fdroid.cfg rather than copying from examples This file is so simple, it is better to skip the complexity of trying to find the installed examples folder, especially when considering Windows and macOS, with their odd paths. --- fdroidserver/init.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/fdroidserver/init.py b/fdroidserver/init.py index 280a503a..c0c23207 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -211,12 +211,10 @@ def main(): opensc_so = '/usr/lib/opensc-pkcs11.so' logging.warning('No OpenSC PKCS#11 module found, ' + 'install OpenSC then edit "opensc-fdroid.cfg"!') - with open(os.path.join(examplesdir, 'opensc-fdroid.cfg'), 'r') as f: - opensc_fdroid = f.read() - opensc_fdroid = re.sub('^library.*', 'library = ' + opensc_so, opensc_fdroid, - flags=re.MULTILINE) with open('opensc-fdroid.cfg', 'w') as f: - f.write(opensc_fdroid) + f.write('name = OpenSC\nlibrary = ') + f.write(opensc_so) + f.write('\n') elif os.path.exists(keystore): to_set = ['keystorepass', 'keypass', 'repo_keyalias', 'keydname'] if repo_keyalias: From 7dcf4f56807d12322d36af728d4685f9d53eff76 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 4 Aug 2020 17:26:29 +0200 Subject: [PATCH 0399/2775] index: smartcardoptions is a list or tuple, but only lists can be added --- fdroidserver/index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index af5c3522..b115643b 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -610,7 +610,7 @@ def extract_pubkey(): '-alias', common.config['repo_keyalias'], '-keystore', common.config['keystore'], '-storepass:env', 'FDROID_KEY_STORE_PASS'] - + common.config['smartcardoptions'], + + list(common.config['smartcardoptions']), envs=env_vars, output=False, stderr_to_stdout=False) if p.returncode != 0 or len(p.output) < 20: msg = "Failed to get repo pubkey!" From d213c8b37c7cf496c3465c24716df7a5a440de46 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 4 Aug 2020 17:29:30 +0200 Subject: [PATCH 0400/2775] update: validate smartcardoptions when using a HSM for the keystore --- fdroidserver/common.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 374789b0..2118992a 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -317,9 +317,10 @@ def read_config(opts, config_file='config.py'): .format(field=k)) # smartcardoptions must be a list since its command line args for Popen - if 'smartcardoptions' in config: - config['smartcardoptions'] = config['smartcardoptions'].split(' ') - elif 'keystore' in config and config['keystore'] == 'NONE': + smartcardoptions = config.get('smartcardoptions') + if isinstance(smartcardoptions, str): + config['smartcardoptions'] = re.sub(r'\s+', r' ', config['smartcardoptions']).split(' ') + elif not smartcardoptions and 'keystore' in config and config['keystore'] == 'NONE': # keystore='NONE' means use smartcard, these are required defaults config['smartcardoptions'] = ['-storetype', 'PKCS11', '-providerName', 'SunPKCS11-OpenSC', '-providerClass', @@ -398,6 +399,10 @@ def assert_config_keystore(config): if 'keystore' not in config: nosigningkey = True logging.critical(_("'keystore' not found in config.py!")) + elif config['keystore'] == 'NONE': + if not config.get('smartcardoptions'): + nosigningkey = True + logging.critical(_("'keystore' is NONE and 'smartcardoptions' is blank!")) elif not os.path.exists(config['keystore']): nosigningkey = True logging.critical("'" + config['keystore'] + "' does not exist!") From f779ce276ab3b49422dde7d32b9d331712e384f4 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 6 Aug 2020 15:45:44 +0200 Subject: [PATCH 0401/2775] 'keypass' is not required in config if using a HSM --- fdroidserver/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 2118992a..1f3a483c 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -409,7 +409,7 @@ def assert_config_keystore(config): if 'keystorepass' not in config: nosigningkey = True logging.critical(_("'keystorepass' not found in config.py!")) - if 'keypass' not in config: + if 'keypass' not in config and config.get('keystore') != 'NONE': nosigningkey = True logging.critical(_("'keypass' not found in config.py!")) if nosigningkey: From 226f490c52f523e28a9a193910e8856b94155c11 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 6 Aug 2020 15:45:18 +0200 Subject: [PATCH 0402/2775] declare LICENSE file in setup.cfg --- setup.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.cfg b/setup.cfg index d4887223..81bcf8af 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,5 @@ +[metadata] +license_file = LICENSE # uploading here requires Python 3.5.3+ or setuptools 27+, # use instead: twine upload --sign dist/fdroidserver*.tar.gz From 7c44669501edab4a584b7d07ef48a2a4787cf1ab Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Sun, 9 Aug 2020 20:06:30 -0400 Subject: [PATCH 0403/2775] Add platform-29_r05 --- makebuildserver | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makebuildserver b/makebuildserver index 6ea403ca..ee8bc2ce 100755 --- a/makebuildserver +++ b/makebuildserver @@ -211,8 +211,8 @@ CACHE_FILES = [ '020c4c090bc82ce87ebaae5d1a922e21b39a1d03c78ffa43f0c3e42fc7d28169'), ('https://dl.google.com/android/repository/platform-28_r06.zip', '8452dbbf9668a428abb243c4f02a943b7aa83af3cca627629a15c4c09f28e7bd'), - ('https://dl.google.com/android/repository/platform-29_r04.zip', - 'c9eaf2ce4e8fa6f5a8036bd3c95363d003733bf0a1bd349718cadf802db44c69'), + ('https://dl.google.com/android/repository/platform-29_r05.zip', + '951da8bf175254da74626824f919bd28def64f8828f29dd3b124a535cf4049d8'), ('https://dl.google.com/android/repository/build-tools_r19.1-linux.zip', '3833b409f78c002a83244e220be380ea6fa44d604e0d47de4b7e5daefe7cd3f4'), ('https://dl.google.com/android/repository/build-tools_r20-linux.zip', From df7bc774654344f9c7eda2fb6a3ee8ed1fb1258e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Mon, 10 Aug 2020 10:53:23 +0000 Subject: [PATCH 0404/2775] Spelling: Deploy key, stripping, SSH --- fdroidserver/nightly.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index e1d599cc..d200d5a2 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -81,7 +81,7 @@ def _ssh_key_from_debug_keystore(keystore=KEYSTORE_FILE): with open(ssh_private_key_file + '.pub', 'w') as fp: fp.write(pub) - logging.info(_('\nSSH Public Key to be used as Deploy Key:') + '\n' + pub) + logging.info(_('\nSSH public key to be used as deploy key:') + '\n' + pub) return ssh_private_key_file @@ -263,7 +263,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, for f in files: if f.endswith('-debug.apk'): apkfilename = os.path.join(root, f) - logging.debug(_('Striping mystery signature from {apkfilename}') + logging.debug(_('Stripping mystery signature from {apkfilename}') .format(apkfilename=apkfilename)) destapk = os.path.join(repodir, os.path.basename(f)) os.chmod(apkfilename, 0o644) @@ -273,7 +273,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, common.sign_apk(apkfilename, destapk, KEY_ALIAS) if options.verbose: - logging.debug(_('attempting bare ssh connection to test deploy key:')) + logging.debug(_('attempting bare SSH connection to test deploy key:')) try: subprocess.check_call(['ssh', '-Tvi', ssh_private_key_file, '-oIdentitiesOnly=yes', '-oStrictHostKeyChecking=no', From d3e8766a3c96ab4b20fa49e68db4e70346f12d1d Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 11 Aug 2020 09:13:20 +0200 Subject: [PATCH 0405/2775] add gradle 6.6 --- gradlew-fdroid | 3 ++- makebuildserver | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index a0b02d24..95208e4b 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -139,6 +139,7 @@ get_sha() { '6.4.1') echo 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd' ;; '6.5') echo '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f' ;; '6.5.1') echo '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a' ;; + '6.5') echo 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025' ;; *) exit 1 esac } @@ -159,7 +160,7 @@ d_plugin_k=(4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 d_plugin_v=(6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.6 6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index ee8bc2ce..b0923498 100755 --- a/makebuildserver +++ b/makebuildserver @@ -393,6 +393,8 @@ CACHE_FILES = [ '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f'), ('https://services.gradle.org/distributions/gradle-6.5.1-bin.zip', '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a'), + ('https://services.gradle.org/distributions/gradle-6.6-bin.zip', + 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From c3c6a20b7c7f11502dc980344df90560ad582707 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 11 Aug 2020 19:04:19 +0200 Subject: [PATCH 0406/2775] gradlew-fdroid: fix typo 6.5 -> 6.6 --- gradlew-fdroid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 95208e4b..847302ad 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -139,7 +139,7 @@ get_sha() { '6.4.1') echo 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd' ;; '6.5') echo '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f' ;; '6.5.1') echo '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a' ;; - '6.5') echo 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025' ;; + '6.6') echo 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025' ;; *) exit 1 esac } From 6128f93d26f81157f8e4ba5dc6497d47b1e51105 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 14 Aug 2020 15:06:33 +0200 Subject: [PATCH 0407/2775] publish: keystore "NONE" is a special case and doesn't need to exist --- fdroidserver/publish.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index d69e3656..914afb1d 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -196,7 +196,7 @@ def main(): sys.exit(1) binaries_dir = os.path.join(unsigned_dir, 'binaries') - if not os.path.exists(config['keystore']): + if not config['keystore'] == "NONE" and not os.path.exists(config['keystore']): logging.error("Config error - missing '{0}'".format(config['keystore'])) sys.exit(1) From 066978cbcfc8bc388e8749ba5d1ef82a10cb576b Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Sat, 11 Apr 2020 23:04:43 +0200 Subject: [PATCH 0408/2775] publish: use common signing method This is currently still jarsigner based but will at least use sha256 when possible --- fdroidserver/common.py | 2 +- fdroidserver/publish.py | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 1f3a483c..26bb7e82 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3064,7 +3064,7 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir): One of the inputs is signed, the other is unsigned. The signature metadata is transferred from the signed to the unsigned apk, and then jarsigner is - used to verify that the signature from the signed apk is also varlid for + used to verify that the signature from the signed apk is also valid for the unsigned one. If the APK given as unsigned actually does have a signature, it will be stripped out and ignored. diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index 914afb1d..b1009dc7 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -319,7 +319,7 @@ def main(): # characters are significant, so we'll use the first 8 from # the MD5 of the app's ID and hope there are no collisions. # If a collision does occur later, we're going to have to - # come up with a new alogrithm, AND rename all existing keys + # come up with a new algorithm, AND rename all existing keys # in the keystore! if not skipsigning: if appid in config['keyaliases']: @@ -367,23 +367,12 @@ def main(): unsigned_dir, output_dir)) - # TODO replace below with common.sign_apk() once it has proven stable - # Sign the application... - p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'], - '-storepass:env', 'FDROID_KEY_STORE_PASS', - '-keypass:env', 'FDROID_KEY_PASS', '-sigalg', - 'SHA1withRSA', '-digestalg', 'SHA1', - apkfile, keyalias], envs=env_vars) - if p.returncode != 0: - raise BuildException(_("Failed to sign application"), p.output) + # Sign and zipalign the application... + common.sign_apk(apkfile, signed_apk_path, keyalias) if appid not in signed_apks: signed_apks[appid] = [] signed_apks[appid].append(apkfile) - # Zipalign it... - common._zipalign(apkfile, os.path.join(output_dir, apkfilename)) - os.remove(apkfile) - publish_source_tarball(apkfilename, unsigned_dir, output_dir) logging.info('Published ' + apkfilename) From 004d13a48a112c46e0f791aa93ddbbbac5346071 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 14 Aug 2020 15:44:34 +0200 Subject: [PATCH 0409/2775] make publish and update work with a smartcard HSM Followup to fdroid/fdroidserver!779. We need to add smartcardoptions to every call to keytool and jarsigner as well as handle when keypass not being required and not allowed for pkcs11 keystores. --- fdroidserver/common.py | 13 ++++++----- fdroidserver/publish.py | 46 +++++++++++++++++++++++---------------- fdroidserver/signindex.py | 2 +- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 26bb7e82..be426d1b 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3045,13 +3045,16 @@ def sign_apk(unsigned_path, signed_path, keyalias): else: signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256'] - p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'], - '-storepass:env', 'FDROID_KEY_STORE_PASS', - '-keypass:env', 'FDROID_KEY_PASS'] - + signature_algorithm + [unsigned_path, keyalias], + cmd = [config['jarsigner'], '-keystore', config['keystore'], + '-storepass:env', 'FDROID_KEY_STORE_PASS'] + if config['keystore'] == 'NONE': + cmd += config['smartcardoptions'] + else: + cmd += '-keypass:env', 'FDROID_KEY_PASS' + p = FDroidPopen(cmd + signature_algorithm + [unsigned_path, keyalias], envs={ 'FDROID_KEY_STORE_PASS': config['keystorepass'], - 'FDROID_KEY_PASS': config['keypass'], }) + 'FDROID_KEY_PASS': config.get('keypass', "")}) if p.returncode != 0: raise BuildException(_("Failed to sign application"), p.output) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index b1009dc7..425cba43 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -77,12 +77,13 @@ def read_fingerprints_from_keystore(): are managed by F-Droid, grouped by appid. """ env_vars = {'LC_ALL': 'C.UTF-8', - 'FDROID_KEY_STORE_PASS': config['keystorepass'], - 'FDROID_KEY_PASS': config['keypass']} - p = FDroidPopen([config['keytool'], '-list', - '-v', '-keystore', config['keystore'], - '-storepass:env', 'FDROID_KEY_STORE_PASS'], - envs=env_vars, output=False) + 'FDROID_KEY_STORE_PASS': config['keystorepass']} + cmd = [config['keytool'], '-list', + '-v', '-keystore', config['keystore'], + '-storepass:env', 'FDROID_KEY_STORE_PASS'] + if config['keystore'] == 'NONE': + cmd += config['smartcardoptions'] + p = FDroidPopen(cmd, envs=env_vars, output=False) if p.returncode != 0: raise FDroidException('could not read keystore {}'.format(config['keystore'])) @@ -115,7 +116,7 @@ def sign_sig_key_fingerprint_list(jar_file): else: # smardcards never use -keypass cmd += '-keypass:env', 'FDROID_KEY_PASS' env_vars = {'FDROID_KEY_STORE_PASS': config['keystorepass'], - 'FDROID_KEY_PASS': config['keypass']} + 'FDROID_KEY_PASS': config.get('keypass', "")} p = common.FDroidPopen(cmd, envs=env_vars) if p.returncode != 0: raise FDroidException("Failed to sign '{}'!".format(jar_file)) @@ -340,20 +341,27 @@ def main(): # if not generate one... env_vars = {'LC_ALL': 'C.UTF-8', 'FDROID_KEY_STORE_PASS': config['keystorepass'], - 'FDROID_KEY_PASS': config['keypass']} - p = FDroidPopen([config['keytool'], '-list', - '-alias', keyalias, '-keystore', config['keystore'], - '-storepass:env', 'FDROID_KEY_STORE_PASS'], envs=env_vars) + 'FDROID_KEY_PASS': config.get('keypass', "")} + cmd = [config['keytool'], '-list', + '-alias', keyalias, '-keystore', config['keystore'], + '-storepass:env', 'FDROID_KEY_STORE_PASS'] + if config['keystore'] == 'NONE': + cmd += config['smartcardoptions'] + p = FDroidPopen(cmd, envs=env_vars) if p.returncode != 0: logging.info("Key does not exist - generating...") - p = FDroidPopen([config['keytool'], '-genkey', - '-keystore', config['keystore'], - '-alias', keyalias, - '-keyalg', 'RSA', '-keysize', '2048', - '-validity', '10000', - '-storepass:env', 'FDROID_KEY_STORE_PASS', - '-keypass:env', 'FDROID_KEY_PASS', - '-dname', config['keydname']], envs=env_vars) + cmd = [config['keytool'], '-genkey', + '-keystore', config['keystore'], + '-alias', keyalias, + '-keyalg', 'RSA', '-keysize', '2048', + '-validity', '10000', + '-storepass:env', 'FDROID_KEY_STORE_PASS', + '-dname', config['keydname']] + if config['keystore'] == 'NONE': + cmd += config['smartcardoptions'] + else: + cmd += '-keypass:env', 'FDROID_KEY_PASS' + p = FDroidPopen(cmd, envs=env_vars) if p.returncode != 0: raise BuildException("Failed to generate key", p.output) if appid not in generated_keys: diff --git a/fdroidserver/signindex.py b/fdroidserver/signindex.py index 1f02d0f9..693b127e 100644 --- a/fdroidserver/signindex.py +++ b/fdroidserver/signindex.py @@ -52,7 +52,7 @@ def sign_jar(jar): args += ['-keypass:env', 'FDROID_KEY_PASS'] env_vars = { 'FDROID_KEY_STORE_PASS': config['keystorepass'], - 'FDROID_KEY_PASS': config['keypass'], + 'FDROID_KEY_PASS': config.get('keypass', ""), } p = common.FDroidPopen(args, envs=env_vars) if p.returncode != 0: From a8e9653b961d4904f2a96055c0c11621401ab72f Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 14 Aug 2020 17:27:08 +0200 Subject: [PATCH 0410/2775] update: make --create-key work with a HSM --- fdroidserver/common.py | 33 ++++++++++++++++++++------------- fdroidserver/init.py | 3 +++ fdroidserver/update.py | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index be426d1b..86097a27 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3345,26 +3345,33 @@ def genkeystore(localconfig): env_vars = {'LC_ALL': 'C.UTF-8', 'FDROID_KEY_STORE_PASS': localconfig['keystorepass'], - 'FDROID_KEY_PASS': localconfig['keypass']} - p = FDroidPopen([config['keytool'], '-genkey', - '-keystore', localconfig['keystore'], - '-alias', localconfig['repo_keyalias'], - '-keyalg', 'RSA', '-keysize', '4096', - '-sigalg', 'SHA256withRSA', - '-validity', '10000', - '-storepass:env', 'FDROID_KEY_STORE_PASS', - '-keypass:env', 'FDROID_KEY_PASS', - '-dname', localconfig['keydname'], - '-J-Duser.language=en'], envs=env_vars) + 'FDROID_KEY_PASS': localconfig.get('keypass', "")} + + cmd = [config['keytool'], '-genkey', + '-keystore', localconfig['keystore'], + '-alias', localconfig['repo_keyalias'], + '-keyalg', 'RSA', '-keysize', '4096', + '-sigalg', 'SHA256withRSA', + '-validity', '10000', + '-storepass:env', 'FDROID_KEY_STORE_PASS', + '-dname', localconfig['keydname'], + '-J-Duser.language=en'] + if localconfig['keystore'] == "NONE": + cmd += localconfig['smartcardoptions'] + else: + cmd += '-keypass:env', 'FDROID_KEY_PASS' + p = FDroidPopen(cmd, envs=env_vars) if p.returncode != 0: raise BuildException("Failed to generate key", p.output) - os.chmod(localconfig['keystore'], 0o0600) + if localconfig['keystore'] != "NONE": + os.chmod(localconfig['keystore'], 0o0600) if not options.quiet: # now show the lovely key that was just generated p = FDroidPopen([config['keytool'], '-list', '-v', '-keystore', localconfig['keystore'], '-alias', localconfig['repo_keyalias'], - '-storepass:env', 'FDROID_KEY_STORE_PASS', '-J-Duser.language=en'], envs=env_vars) + '-storepass:env', 'FDROID_KEY_STORE_PASS', '-J-Duser.language=en'] + + config['smartcardoptions'], envs=env_vars) logging.info(p.output.strip() + '\n\n') # get the public key p = FDroidPopenBytes([config['keytool'], '-exportcert', diff --git a/fdroidserver/init.py b/fdroidserver/init.py index c0c23207..ff2f7075 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -215,6 +215,9 @@ def main(): f.write('name = OpenSC\nlibrary = ') f.write(opensc_so) f.write('\n') + logging.info("Repo setup using a smartcard HSM. Please edit keystorepass and repo_keyalias in config.py.") + logging.info("If you want to generate a new repo signing key in the HSM you can do that with 'fdroid update " + "--create-key'.") elif os.path.exists(keystore): to_set = ['keystorepass', 'keypass', 'repo_keyalias', 'keydname'] if repo_keyalias: diff --git a/fdroidserver/update.py b/fdroidserver/update.py index babc3254..18ec1fe9 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -2323,7 +2323,7 @@ def main(): if 'keystorepass' not in config: config['keystorepass'] = password common.write_to_config(config, 'keystorepass', config['keystorepass']) - if 'keypass' not in config: + if 'keypass' not in config and not config['keystore'] == "NONE": config['keypass'] = password common.write_to_config(config, 'keypass', config['keypass']) common.genkeystore(config) From f8a1b45df5ec907c5490b11c1fd847ba27cb6082 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 19 Aug 2020 16:28:58 +0200 Subject: [PATCH 0411/2775] gradlew-fdroid: fix random failures due to empty $line, closes #815 --- gradlew-fdroid | 4 ++-- tests/test-gradlew-fdroid | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 847302ad..9b9899f8 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -168,7 +168,7 @@ v_all=${plugin_v[@]} for f in {.,..}/gradle/wrapper/gradle-wrapper.properties; do [[ -f $f ]] || continue while IFS='' read -r line || [ -n "$line" ]; do - line=$(printf $line | tr -d '\r') # strip Windows linefeeds + line=$(printf "$line" | tr -d '\r') # strip Windows linefeeds if [[ $line == 'distributionUrl='* ]]; then wrapper_ver=${line#*/gradle-} wrapper_ver=${wrapper_ver%-*.zip} @@ -187,7 +187,7 @@ fi for f in {.,..}/build.gradle{,.kts}; do [[ -f $f ]] || continue while IFS='' read -r line || [ -n "$line" ]; do - line=$(printf $line | tr -d '\r') # strip Windows linefeeds + line=$(printf "$line" | tr -d '\r') # strip Windows linefeeds if [[ -z "$plugin_pver" && $line == *'com.android.tools.build:gradle:'* ]]; then plugin_pver=${line#*[\'\"]com.android.tools.build:gradle:} plugin_pver=${plugin_pver%[\'\"]*} diff --git a/tests/test-gradlew-fdroid b/tests/test-gradlew-fdroid index 2a34f971..63f74e5e 100755 --- a/tests/test-gradlew-fdroid +++ b/tests/test-gradlew-fdroid @@ -4,7 +4,7 @@ run_test() { red='\033[0;31m' green='\033[0;32m' nocolor='\033[0m' - cd $basedir/tests/source-files/$1 + cd $source_files/$1 printf "\n${1}:\n" if ($basedir/gradlew-fdroid 2>/dev/null || true) | grep -Fo "$2"; then printf "${green}passed: $1\n" @@ -17,15 +17,26 @@ run_test() { exit_value=0 basedir=$(cd $(dirname $0)/..; pwd) +source_files=$basedir/tests/source-files export https_proxy=127.7.7.7:7 # fake proxy to block downloading -# force test file to have Windows linefeeds -sed -i -e $'s/\r$//' -e $'s/$/\r/' \ - $basedir/tests/source-files/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper.properties - run_test osmandapp/osmand 2.2.1 run_test com.integreight.onesheeld 3.3 run_test se.manyver/android 5.5 run_test yuriykulikov/AlarmClock 5.1.1 +printf "\n\nforce test files to have Windows linefeeds:\n" +tmpdir=`mktemp -d` +cp -a $source_files/osmandapp $source_files/yuriykulikov $tmpdir/ +awk 'sub("$", "\r")' \ + $source_files/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper.properties \ + > $tmpdir/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper.properties +awk 'sub("$", "\r")' \ + $source_files/osmandapp/osmand/build.gradle \ + > $tmpdir/osmandapp/osmand/build.gradle +source_files=$tmpdir + +run_test yuriykulikov/AlarmClock 5.1.1 +run_test osmandapp/osmand 2.2.1 + exit $exit_value From ba28b44ae7c50757434b45658e19a2383e0f293c Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 19 Aug 2020 18:06:27 +0200 Subject: [PATCH 0412/2775] common: use androguard to figure out minSDK version Closes: #816 --- fdroidserver/common.py | 21 +++++++-------- tests/common.TestCase | 61 ++++++++++++++++++------------------------ 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 86097a27..4a5ad875 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2502,20 +2502,19 @@ def get_native_code(apkfile): return sorted(list(archset)) -def get_minSdkVersion_aapt(apkfile): - """Extract the minimum supported Android SDK from an APK using aapt +def get_minSdkVersion(apkfile): + """Extract the minimum supported Android SDK from an APK using androguard :param apkfile: path to an APK file. :returns: the integer representing the SDK version """ - r = re.compile(r"^sdkVersion:'([0-9]+)'") - p = SdkToolsPopen(['aapt', 'dump', 'badging', apkfile], output=False) - for line in p.output.splitlines(): - m = r.match(line) - if m: - return int(m.group(1)) - raise FDroidException(_('Reading minSdkVersion failed: "{apkfilename}"') - .format(apkfilename=apkfile)) + + try: + apk = _get_androguard_APK(apkfile) + except FileNotFoundError: + raise FDroidException(_('Reading minSdkVersion failed: "{apkfilename}"') + .format(apkfilename=apkfile)) + return int(apk.get_min_sdk_version()) class PopenResult: @@ -3040,7 +3039,7 @@ def sign_apk(unsigned_path, signed_path, keyalias): """ - if get_minSdkVersion_aapt(unsigned_path) < 18: + if get_minSdkVersion(unsigned_path) < 18: signature_algorithm = ['-sigalg', 'SHA1withRSA', '-digestalg', 'SHA1'] else: signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256'] diff --git a/tests/common.TestCase b/tests/common.TestCase index 49e46af7..78ab8da3 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -674,7 +674,7 @@ class CommonTest(unittest.TestCase): self.assertTrue(fdroidserver.common.verify_apk_signature(signed)) try: fdroidserver.common.find_sdk_tools_cmd('aapt') - self.assertEqual(18, fdroidserver.common.get_minSdkVersion_aapt(signed)) + self.assertEqual(18, fdroidserver.common.get_minSdkVersion(signed)) except fdroidserver.exception.FDroidException: print('\n\nSKIPPING test_sign_apk min SDK check, aapt is not installed!\n') return @@ -775,63 +775,54 @@ class CommonTest(unittest.TestCase): nc = fdroidserver.common.get_native_code(apkfilename) self.assertEqual(native_code, nc) - def test_get_minSdkVersion_aapt(self): - config = dict() - fdroidserver.common.fill_config_defaults(config) - fdroidserver.common.config = config - self._set_build_tools() - try: # get_minSdkVersion_aapt requires aapt - config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') - except fdroidserver.exception.FDroidException: - print('\n\nSKIPPING test_sign_apk, aapt is not installed!\n') - return - - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('bad-unicode-πÇÇ现代通用字-български-عربي1.apk') + def test_get_minSdkVersion_androguard(self): + minSdkVersion = fdroidserver.common.get_minSdkVersion('bad-unicode-πÇÇ现代通用字-български-عربي1.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('org.bitbucket.tickytacky.mirrormirror_1.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_1.apk') self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('org.bitbucket.tickytacky.mirrormirror_2.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_2.apk') self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('org.bitbucket.tickytacky.mirrormirror_3.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_3.apk') self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('org.bitbucket.tickytacky.mirrormirror_4.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_4.apk') self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('org.dyndns.fules.ck_20.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('org.dyndns.fules.ck_20.apk') self.assertEqual(7, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('urzip.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('urzip-badcert.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip-badcert.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('urzip-badsig.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip-badsig.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('urzip-release.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip-release.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('urzip-release-unsigned.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip-release-unsigned.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/com.politedroid_3.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/com.politedroid_3.apk') self.assertEqual(3, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/com.politedroid_4.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/com.politedroid_4.apk') self.assertEqual(3, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/com.politedroid_5.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/com.politedroid_5.apk') self.assertEqual(3, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/com.politedroid_6.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/com.politedroid_6.apk') self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/obb.main.oldversion_1444412523.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.main.oldversion_1444412523.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/obb.mainpatch.current_1619_another-release-key.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.mainpatch.current_1619_another-release-key.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/obb.mainpatch.current_1619.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.mainpatch.current_1619.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/obb.main.twoversions_1101613.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.main.twoversions_1101613.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/obb.main.twoversions_1101615.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.main.twoversions_1101615.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/obb.main.twoversions_1101617.apk') + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.main.twoversions_1101617.apk') + self.assertEqual(4, minSdkVersion) + minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk') self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion_aapt('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk') with self.assertRaises(FDroidException): - fdroidserver.common.get_minSdkVersion_aapt('nope') + fdroidserver.common.get_minSdkVersion('nope') def test_apk_release_name(self): appid, vercode, sigfp = fdroidserver.common.apk_parse_release_filename('com.serwylo.lexica_905.apk') From bc1398f5942c2b1ea0eb64173fe261f06d04252b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 1 Jul 2020 14:49:46 +0200 Subject: [PATCH 0413/2775] remove json metadata support --- fdroidserver/metadata.py | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index ee58b1b4..5b4aa433 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -18,7 +18,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import json import os import re import glob @@ -867,10 +866,8 @@ def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): os.makedirs(basedir) metadatafiles = (glob.glob(os.path.join('metadata', '*.txt')) - + glob.glob(os.path.join('metadata', '*.json')) + glob.glob(os.path.join('metadata', '*.yml')) + glob.glob('.fdroid.txt') - + glob.glob('.fdroid.json') + glob.glob('.fdroid.yml')) if sort_by_time: @@ -884,7 +881,7 @@ def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): for metadatapath in metadatafiles: if metadatapath == '.fdroid.txt': - warn_or_exception(_('.fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json.')) + warn_or_exception(_('.fdroid.txt is not supported! Convert to .fdroid.yml')) appid, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath)) if appid != '.fdroid' and not fdroidserver.common.is_valid_package_name(appid): warn_or_exception(_("{appid} from {path} is not a valid Java Package Name!") @@ -1060,8 +1057,6 @@ def parse_metadata(metadatapath, check_vcs=False, refresh=True): with open(metadatapath, 'r') as mf: if ext == 'txt': parse_txt_metadata(mf, app) - elif ext == 'json': - parse_json_metadata(mf, app) elif ext == 'yml': parse_yaml_metadata(mf, app) else: @@ -1098,20 +1093,6 @@ def parse_metadata(metadatapath, check_vcs=False, refresh=True): return app -def parse_json_metadata(mf, app): - - # fdroid metadata is only strings and booleans, no floats or ints. - # TODO create schema using https://pypi.python.org/pypi/jsonschema - jsoninfo = json.load(mf, parse_int=lambda s: s, - parse_float=lambda s: s) - app.update(jsoninfo) - for f in ['Description', 'Maintainer Notes']: - v = app.get(f) - if v: - app[f] = '\n'.join(v) - return app - - def parse_yaml_metadata(mf, app): try: yamldata = yaml.load(mf, Loader=SafeLoader) From 2ec90bb490c047ce3aa10b84cb7c7b924cc17a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 2 Jul 2020 00:48:03 +0200 Subject: [PATCH 0414/2775] remove support for rewriting to txt --- fdroidserver/rewritemeta.py | 6 ++-- tests/rewritemeta.TestCase | 65 ++++++------------------------------- 2 files changed, 12 insertions(+), 59 deletions(-) diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 97d15852..82763c54 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # # rewritemeta.py - part of the FDroid server tools -# This cleans up the original .txt metadata file format. +# This cleans up the original .yml metadata file format. # Copyright (C) 2010-12, Ciaran Gultnieks, ciaran@ciarang.com # # This program is free software: you can redistribute it and/or modify @@ -30,7 +30,7 @@ config = None options = None -SUPPORTED_FORMATS = ['txt', 'yml'] +SUPPORTED_FORMATS = ['yml'] def proper_format(app): @@ -42,8 +42,6 @@ def proper_format(app): _ignored, extension = common.get_extension(app.metadatapath) if extension == 'yml': metadata.write_yaml(s, app) - elif extension == 'txt': - metadata.write_txt(s, app) content = s.getvalue() s.close() return content == cur_content diff --git a/tests/rewritemeta.TestCase b/tests/rewritemeta.TestCase index 664f3c78..8a7d41e4 100755 --- a/tests/rewritemeta.TestCase +++ b/tests/rewritemeta.TestCase @@ -49,48 +49,13 @@ class RewriteMetaTest(unittest.TestCase): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): os.mkdir('metadata') - with open('metadata/a.txt', 'w') as f: - f.write('Auto Name:a') + with open('metadata/a.yml', 'w') as f: + f.write('AutoName: a') with open('metadata/b.yml', 'w') as f: f.write('AutoName: b') rewritemeta.main() - with open('metadata/a.txt') as f: - self.assertEqual(f.read(), textwrap.dedent('''\ - Categories: - License:Unknown - Web Site: - Source Code: - Issue Tracker: - - Auto Name:a - - Auto Update Mode:None - Update Check Mode:None - ''')) - - with open('metadata/b.yml') as f: - self.assertEqual(f.read(), textwrap.dedent('''\ - License: Unknown - - AutoName: b - - AutoUpdateMode: None - UpdateCheckMode: None - ''')) - - def test_rewrite_scenario_txt_to_yml(self): - - sys.argv = ['rewritemeta', '--to', 'yml', 'a'] - - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - os.mkdir('metadata') - with open('metadata/a.txt', 'w') as f: - f.write('Auto Name:a') - - rewritemeta.main() - with open('metadata/a.yml') as f: self.assertEqual(f.read(), textwrap.dedent('''\ License: Unknown @@ -101,25 +66,15 @@ class RewriteMetaTest(unittest.TestCase): UpdateCheckMode: None ''')) - def test_rewrite_scenario_txt_to_yml_no_ruamel(self): - - sys.argv = ['rewritemeta', '--to', 'yml', 'a'] - - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - os.mkdir('metadata') - with open('metadata/a.txt', 'w') as f: - f.write('Auto Name:a') - - def boom(*args): - raise FDroidException(' '.join((str(x) for x in args))) - - with mock.patch('fdroidserver.metadata.write_yaml', boom): - with self.assertRaises(FDroidException): - rewritemeta.main() - - with open('metadata/a.txt') as f: + with open('metadata/b.yml') as f: self.assertEqual(f.read(), textwrap.dedent('''\ - Auto Name:a''')) + License: Unknown + + AutoName: b + + AutoUpdateMode: None + UpdateCheckMode: None + ''')) def test_rewrite_scenario_yml_no_ruamel(self): sys.argv = ['rewritemeta', 'a'] From c8f25c2652cea96f1ac1ab5e484858dae3816064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 1 Jul 2020 17:56:23 +0200 Subject: [PATCH 0415/2775] remove txt metadata support --- fdroidserver/metadata.py | 442 +-------------------------------------- 1 file changed, 11 insertions(+), 431 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 5b4aa433..72678434 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -58,54 +58,6 @@ def warn_or_exception(value, cause=None): logging.warning(value) -# To filter which ones should be written to the metadata files if -# present -app_fields = set([ - 'Disabled', - 'AntiFeatures', - 'Provides', # deprecated, txt only - 'Categories', - 'License', - 'Author Name', - 'Author Email', - 'Author Web Site', - 'Web Site', - 'Source Code', - 'Issue Tracker', - 'Translation', - 'Changelog', - 'Donate', - 'FlattrID', - 'Liberapay', - 'LiberapayID', - 'OpenCollective', - 'Bitcoin', - 'Litecoin', - 'Name', - 'Auto Name', - 'Summary', - 'Description', - 'Requires Root', - 'Repo Type', - 'Repo', - 'Binaries', - 'Maintainer Notes', - 'Archive Policy', - 'Auto Update Mode', - 'Update Check Mode', - 'Update Check Ignore', - 'Vercode Operation', - 'Update Check Name', - 'Update Check Data', - 'Current Version', - 'Current Version Code', - 'No Source Since', - 'Build', - - 'comments', # For formats that don't do inline comments - 'builds', # For formats that do builds as a list -]) - yaml_app_field_order = [ 'Disabled', 'AntiFeatures', @@ -265,7 +217,9 @@ def fieldtype(name): # In the order in which they are laid out on files -build_flags_order = [ +build_flags = [ + 'versionName', + 'versionCode', 'disable', 'commit', 'timeout', @@ -300,10 +254,6 @@ build_flags_order = [ 'antifeatures', ] -# old .txt format has version name/code inline in the 'Build:' line -# but YAML and JSON have a explicit key for them -build_flags = ['versionName', 'versionCode'] + build_flags_order - class Build(dict): @@ -690,16 +640,6 @@ class DescriptionFormatter: self.html.close() -# Parse multiple lines of description as written in a metadata file, returning -# a single string in text format and wrapped to 80 columns. -def description_txt(s): - ps = DescriptionFormatter(None) - for line in s.splitlines(): - ps.parseline(line) - ps.end() - return ps.text_txt - - # Parse multiple lines of description as written in a metadata file, returning # a single string in wiki format. Used for the Maintainer Notes field as well, # because it's the same format. @@ -846,11 +786,6 @@ def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): sorted based on creation time, newest first. Most of the time, the newer files are the most interesting. - If there are multiple metadata files for a single appid, then the first - file that is parsed wins over all the others, and the rest throw an - exception. So the original .txt format is parsed first, at least until - newer formats stabilize. - check_vcs is the list of appids to check for .fdroid.yml in source """ @@ -865,9 +800,7 @@ def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): if not os.path.exists(basedir): os.makedirs(basedir) - metadatafiles = (glob.glob(os.path.join('metadata', '*.txt')) - + glob.glob(os.path.join('metadata', '*.yml')) - + glob.glob('.fdroid.txt') + metadatafiles = (glob.glob(os.path.join('metadata', '*.yml')) + glob.glob('.fdroid.yml')) if sort_by_time: @@ -880,8 +813,6 @@ def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): metadatafiles = sorted(metadatafiles) for metadatapath in metadatafiles: - if metadatapath == '.fdroid.txt': - warn_or_exception(_('.fdroid.txt is not supported! Convert to .fdroid.yml')) appid, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath)) if appid != '.fdroid' and not fdroidserver.common.is_valid_package_name(appid): warn_or_exception(_("{appid} from {path} is not a valid Java Package Name!") @@ -1054,14 +985,12 @@ def parse_metadata(metadatapath, check_vcs=False, refresh=True): else: app.id = name - with open(metadatapath, 'r') as mf: - if ext == 'txt': - parse_txt_metadata(mf, app) - elif ext == 'yml': + if ext == 'yml': + with open(metadatapath, 'r') as mf: parse_yaml_metadata(mf, app) - else: - warn_or_exception(_('Unknown metadata format: {path}') - .format(path=metadatapath)) + else: + warn_or_exception(_('Unknown metadata format: {path}') + .format(path=metadatapath)) if check_vcs and app.Repo: build_dir = fdroidserver.common.get_build_dir(app) @@ -1235,7 +1164,7 @@ def write_yaml(mf, app): insert_newline = True else: if app.get(field) or field == 'Builds': - # .txt calls it 'builds' internally, everywhere else its 'Builds' + # .txt called it 'builds' internally, everywhere else its 'Builds' if field == 'Builds': if app.get('builds'): cm.update({field: _builds_to_yaml(app)}) @@ -1285,352 +1214,6 @@ build_line_sep = re.compile(r'(? Date: Thu, 2 Jul 2020 00:38:09 +0200 Subject: [PATCH 0416/2775] remove txt srclib support --- fdroidserver/metadata.py | 46 +-------------------- tests/metadata.TestCase | 88 ++-------------------------------------- 2 files changed, 4 insertions(+), 130 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 72678434..ffc5edf7 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -657,46 +657,6 @@ def description_html(s, linkres): return ps.text_html -def parse_txt_srclib(metadatapath): - - thisinfo = {} - - # Defaults for fields that come from metadata - thisinfo['RepoType'] = '' - thisinfo['Repo'] = '' - thisinfo['Subdir'] = None - thisinfo['Prepare'] = None - - if not os.path.exists(metadatapath): - return thisinfo - - metafile = open(metadatapath, "r") - - n = 0 - for line in metafile: - n += 1 - line = line.rstrip('\r\n') - if not line or line.startswith("#"): - continue - - try: - f, v = line.split(':', 1) - except ValueError: - warn_or_exception(_("Invalid metadata in %s:%d") % (line, n)) - - # collapse whitespaces in field names - f = f.replace(' ', '') - - if f == "Subdir": - thisinfo[f] = v.split(',') - else: - thisinfo[f] = v - - metafile.close() - - return thisinfo - - def parse_yaml_srclib(metadatapath): thisinfo = {'RepoType': '', @@ -752,7 +712,7 @@ def read_srclibs(): The information read will be accessible as metadata.srclibs, which is a dictionary, keyed on srclib name, with the values each being a dictionary - in the same format as that returned by the parse_txt_srclib function. + in the same format as that returned by the parse_yaml_srclib function. A MetaDataException is raised if there are any problems with the srclib metadata. @@ -769,10 +729,6 @@ def read_srclibs(): if not os.path.exists(srcdir): os.makedirs(srcdir) - for metadatapath in sorted(glob.glob(os.path.join(srcdir, '*.txt'))): - srclibname = os.path.basename(metadatapath[:-4]) - srclibs[srclibname] = parse_txt_srclib(metadatapath) - for metadatapath in sorted(glob.glob(os.path.join(srcdir, '*.yml'))): srclibname = os.path.basename(metadatapath[:-4]) srclibs[srclibname] = parse_yaml_srclib(metadatapath) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index f9ba731d..8ab502c4 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -637,88 +637,6 @@ class MetadataTest(unittest.TestCase): UpdateCheckMode: None """)) - def test_parse_txt_srclib(self): - fdroidserver.metadata.warnings_action = 'error' - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('JSoup.txt', 'w', encoding='utf-8') as f: - f.write(textwrap.dedent('''\ - # Source details (the only mandatory fields) - Repo Type:git - Repo:https://github.com/jhy/jsoup.git - - # Comma-separated list of subdirs to use. The first existing subdirectory - # found between those given will be used. If none is found or provided, the - # root of the repo directory will be used instead. - Subdir: - - # Any extra commands to prepare the source library - Prepare: - ''')) - srclib = fdroidserver.metadata.parse_txt_srclib('JSoup.txt') - self.assertDictEqual({'Repo': 'https://github.com/jhy/jsoup.git', - 'RepoType': 'git', - 'Subdir': [''], - 'Prepare': ''}, - srclib) - - def test_parse_txt_srclib_simple(self): - fdroidserver.metadata.warnings_action = 'error' - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('simple.txt', 'w', encoding='utf-8') as f: - f.write(textwrap.dedent('''\ - # this should be simple - Repo Type:git - Repo:https://git.host/repo.git - ''')) - srclib = fdroidserver.metadata.parse_txt_srclib('simple.txt') - self.assertDictEqual({'Repo': 'https://git.host/repo.git', - 'RepoType': 'git', - 'Subdir': None, - 'Prepare': None}, - srclib) - - def test_parse_txt_srclib_simple_blanks(self): - fdroidserver.metadata.warnings_action = 'error' - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('simple.txt', 'w', encoding='utf-8') as f: - f.write(textwrap.dedent('''\ - # this should be simple - - Repo Type:git - - Repo:https://git.host/repo.git - - Subdir: - - Prepare: - ''')) - srclib = fdroidserver.metadata.parse_txt_srclib('simple.txt') - self.assertDictEqual({'Repo': 'https://git.host/repo.git', - 'RepoType': 'git', - 'Subdir': [''], - 'Prepare': ''}, - srclib) - - def test_parse_txt_srclib_Changelog_cketti(self): - fdroidserver.metadata.warnings_action = 'error' - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - with open('Changelog-cketti.txt', 'w', encoding='utf-8') as f: - f.write(textwrap.dedent('''\ - Repo Type:git - Repo:https://github.com/cketti/ckChangeLog - - Subdir:library,ckChangeLog/src/main - Prepare:[ -f project.properties ] || echo 'source.dir=java' > ant.properties && echo -e 'android.library=true\\ntarget=android-19' > project.properties - ''')) - srclib = fdroidserver.metadata.parse_txt_srclib('Changelog-cketti.txt') - self.assertDictEqual({'Repo': 'https://github.com/cketti/ckChangeLog', - 'RepoType': 'git', - 'Subdir': ['library', 'ckChangeLog/src/main'], - 'Prepare': "[ -f project.properties ] || echo 'source.dir=java' > " - "ant.properties && echo -e " - "'android.library=true\\ntarget=android-19' > project.properties"}, - srclib) - def test_parse_yaml_srclib_unknown_key(self): fdroidserver.metadata.warnings_action = 'error' with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): @@ -885,11 +803,11 @@ class MetadataTest(unittest.TestCase): RepoType: git Repo: https://git.host/repo.git ''')) - with open('srclibs/simple-wb.txt', 'w', encoding='utf-8') as f: + with open('srclibs/simple-wb.yml', 'w', encoding='utf-8') as f: f.write(textwrap.dedent('''\ # this should be simple - Repo Type:git - Repo:https://git.host/repo.git + RepoType: git + Repo: https://git.host/repo.git Subdir: Prepare: From 681a27546c0b687617130b379f951eac7f561c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 2 Jul 2020 11:42:39 +0200 Subject: [PATCH 0417/2775] fix linking to yml metadata in wiki --- fdroidserver/update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 18ec1fe9..3ddf602c 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -237,7 +237,7 @@ def update_wiki(apps, apks): wikidata += "=Maintainer Notes=\n" if app.MaintainerNotes: wikidata += metadata.description_wiki(app.MaintainerNotes) + "\n" - wikidata += "\nMetadata: [https://gitlab.com/fdroid/fdroiddata/blob/master/metadata/{0}.txt current] [https://gitlab.com/fdroid/fdroiddata/commits/master/metadata/{0}.txt history]\n".format(appid) + wikidata += "\nMetadata: [https://gitlab.com/fdroid/fdroiddata/blob/master/metadata/{0}.yml current] [https://gitlab.com/fdroid/fdroiddata/commits/master/metadata/{0}.yml history]\n".format(appid) # Get a list of all packages for this application... apklist = [] From fd2cfb0c7dc6ce6e43c6bd199437ffa4ca0b009e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 2 Jul 2020 11:45:20 +0200 Subject: [PATCH 0418/2775] remove code for copying txt srclibs to buildserver --- fdroidserver/build.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index e8880c02..ecf466c2 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -206,14 +206,11 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): if os.path.isfile(os.path.join('srclibs', name + '.yml')): ftp.put(os.path.join('srclibs', name + '.yml'), name + '.yml') - elif os.path.isfile(os.path.join('srclibs', name + '.txt')): - ftp.put(os.path.join('srclibs', name + '.txt'), - name + '.txt') else: raise BuildException("can not find metadata file for " "'{name}', please make sure it is " "present in your 'srclibs' folder." - "(supported formats: txt, yml)" + "(supported format: yml)" .format(name=name)) # Copy the main app source code # (no need if it's a srclib) From 4dc503ed28b092bead7a97770c9c7fdb7ad72487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 2 Jul 2020 11:49:20 +0200 Subject: [PATCH 0419/2775] remove txt form accepted format list --- fdroidserver/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 4a5ad875..b2e9bcf5 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -119,7 +119,7 @@ default_config = { 'mvn3': "mvn", 'gradle': os.path.join(FDROID_PATH, 'gradlew-fdroid'), 'gradle_version_dir': os.path.join(os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), 'gradle'), - 'accepted_formats': ['txt', 'yml'], + 'accepted_formats': ['yml'], 'sync_from_local_copy_dir': False, 'allow_disabled_algorithms': False, 'per_app_repos': False, @@ -517,7 +517,7 @@ def get_local_metadata_files(): '''get any metadata files local to an app's source repo This tries to ignore anything that does not count as app metdata, - including emacs cruft ending in ~ and the .fdroid.key*pass.txt files. + including emacs cruft ending in ~ and the .fdroid.key*pass.yml files. ''' return glob.glob('.fdroid.[a-jl-z]*[a-rt-z]') From f8bc51399ecd9dfe1ba3d47197f38a6c498b5888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 2 Jul 2020 11:55:36 +0200 Subject: [PATCH 0420/2775] remove txt from nightly default supported metadata formats --- fdroidserver/nightly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index d200d5a2..f9a1f787 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -248,7 +248,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, config += "keypass = '%s'\n" % PASSWORD config += "keydname = '%s'\n" % DISTINGUISHED_NAME config += "make_current_version_link = False\n" - config += "accepted_formats = ('txt', 'yml')\n" + config += "accepted_formats = ['yml']\n" config += "update_stats = True\n" with open('config.py', 'w') as fp: fp.write(config) From 40cbbd3173a46e31a5d6b576a578e00bef3db361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Fri, 3 Jul 2020 22:29:56 +0200 Subject: [PATCH 0421/2775] update changelog: remove txt metadata support --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de4c33a4..3acb9b4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * build: deploying buildlogs with rsync ([!651](https://gitlab.com/fdroid/fdroidserver/merge_requests/651)) +### Removed +* removed support for txt and json metadata + ([!772](https://gitlab.com/fdroid/fdroidserver/-/merge_requests/772)) + ## [1.1.4] - 2019-08-15 ### Fixed * include bitcoin validation regex required by fdroiddata From f5a5fffb10223abec8195e6010e6e9d6b8c711ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 19 Aug 2020 15:51:49 +0200 Subject: [PATCH 0422/2775] purge accepted_formats from config --- fdroidserver/common.py | 1 - fdroidserver/lint.py | 10 +++------- fdroidserver/metadata.py | 8 -------- fdroidserver/nightly.py | 1 - 4 files changed, 3 insertions(+), 17 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index b2e9bcf5..022be563 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -119,7 +119,6 @@ default_config = { 'mvn3': "mvn", 'gradle': os.path.join(FDROID_PATH, 'gradlew-fdroid'), 'gradle_version_dir': os.path.join(os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), 'gradle'), - 'accepted_formats': ['yml'], 'sync_from_local_copy_dir': False, 'allow_disabled_algorithms': False, 'per_app_repos': False, diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index cf6a1119..8fafc7a0 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -515,16 +515,12 @@ def check_for_unsupported_metadata_files(basedir=""): global config return_value = False - formats = config['accepted_formats'] for f in glob.glob(basedir + 'metadata/*') + glob.glob(basedir + 'metadata/.*'): if os.path.isdir(f): - exists = False - for t in formats: - exists = exists or os.path.exists(f + '.' + t) - if not exists: + if not os.path.exists(f + '.yml'): print(_('"%s/" has no matching metadata file!') % f) return_value = True - elif os.path.splitext(f)[1][1:] in formats: + elif os.path.splitext(f)[1][1:] == "yml": packageName = os.path.splitext(os.path.basename(f))[0] if not common.is_valid_package_name(packageName): print('"' + packageName + '" is an invalid package name!\n' @@ -532,7 +528,7 @@ def check_for_unsupported_metadata_files(basedir=""): return_value = True else: print('"' + f.replace(basedir, '') - + '" is not a supported file format: (' + ','.join(formats) + ')') + + '" is not a supported file format (use: .yml)') return_value = True return return_value diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index ffc5edf7..2498bb32 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -928,10 +928,6 @@ def parse_metadata(metadatapath, check_vcs=False, refresh=True): '''parse metadata file, optionally checking the git repo for metadata first''' _ignored, ext = fdroidserver.common.get_extension(metadatapath) - accepted = fdroidserver.common.config['accepted_formats'] - if ext not in accepted: - warn_or_exception(_('"{path}" is not an accepted format, convert to: {formats}') - .format(path=metadatapath, formats=', '.join(accepted))) app = App() app.metadatapath = metadatapath @@ -1172,10 +1168,6 @@ build_cont = re.compile(r'^[ \t]') def write_metadata(metadatapath, app): _ignored, ext = fdroidserver.common.get_extension(metadatapath) - accepted = fdroidserver.common.config['accepted_formats'] - if ext not in accepted: - warn_or_exception(_('Cannot write "{path}", not an accepted format, use: {formats}') - .format(path=metadatapath, formats=', '.join(accepted))) if ext == 'yml': if importlib.util.find_spec('ruamel.yaml'): diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index f9a1f787..cedf29a4 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -248,7 +248,6 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, config += "keypass = '%s'\n" % PASSWORD config += "keydname = '%s'\n" % DISTINGUISHED_NAME config += "make_current_version_link = False\n" - config += "accepted_formats = ['yml']\n" config += "update_stats = True\n" with open('config.py', 'w') as fp: fp.write(config) From fac033314a91d21417fc74b03a190854c052da6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 19 Aug 2020 17:15:34 +0200 Subject: [PATCH 0423/2775] fix a comment and a warning --- fdroidserver/common.py | 2 +- fdroidserver/metadata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 022be563..5f057e40 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -516,7 +516,7 @@ def get_local_metadata_files(): '''get any metadata files local to an app's source repo This tries to ignore anything that does not count as app metdata, - including emacs cruft ending in ~ and the .fdroid.key*pass.yml files. + including emacs cruft ending in ~ ''' return glob.glob('.fdroid.[a-jl-z]*[a-rt-z]') diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 2498bb32..60762076 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -941,7 +941,7 @@ def parse_metadata(metadatapath, check_vcs=False, refresh=True): with open(metadatapath, 'r') as mf: parse_yaml_metadata(mf, app) else: - warn_or_exception(_('Unknown metadata format: {path}') + warn_or_exception(_('Unknown metadata format: {path} (use: .yml)') .format(path=metadatapath)) if check_vcs and app.Repo: From c45ef453fd99a6ff8bb9c82ede9ed42e457cf54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 19 Aug 2020 19:24:47 +0200 Subject: [PATCH 0424/2775] remove SUPPORTED_FORMATS list from rewritemeta --- fdroidserver/rewritemeta.py | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 82763c54..b4a3f63b 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -30,9 +30,6 @@ config = None options = None -SUPPORTED_FORMATS = ['yml'] - - def proper_format(app): s = io.StringIO() # TODO: currently reading entire file again, should reuse first @@ -56,8 +53,6 @@ def main(): common.setup_global_opts(parser) parser.add_argument("-l", "--list", action="store_true", default=False, help=_("List files that would be reformatted")) - parser.add_argument("-t", "--to", default=None, - help=_("Rewrite to a specific format: ") + ', '.join(SUPPORTED_FORMATS)) parser.add_argument("appid", nargs='*', help=_("applicationId in the form APPID")) metadata.add_metadata_arguments(parser) options = parser.parse_args() @@ -69,28 +64,15 @@ def main(): allapps = metadata.read_metadata(xref=True) apps = common.read_app_args(options.appid, allapps, False) - if options.list and options.to is not None: - parser.error(_("Cannot use --list and --to at the same time")) - - if options.to is not None and options.to not in SUPPORTED_FORMATS: - parser.error(_("Unsupported metadata format, use: --to [{supported}]") - .format(supported=' '.join(SUPPORTED_FORMATS))) - for appid, app in apps.items(): path = app.metadatapath base, ext = common.get_extension(path) - if not options.to and ext not in SUPPORTED_FORMATS: + if ext != "yml": logging.info(_("Ignoring {ext} file at '{path}'").format(ext=ext, path=path)) continue - elif options.to is not None: - logging.info(_("Rewriting '{appid}' to '{path}'").format(appid=appid, path=options.to)) else: logging.info(_("Rewriting '{appid}'").format(appid=appid)) - to_ext = ext - if options.to is not None: - to_ext = options.to - if options.list: if not proper_format(app): print(path) @@ -108,11 +90,7 @@ def main(): app.builds = newbuilds try: - metadata.write_metadata(base + '.' + to_ext, app) - # remove old format metadata if there was a format change - # and rewriting to the new format worked - if ext != to_ext: - os.remove(path) + metadata.write_metadata(path, app) finally: pass From 5c3db9a7cc49a98f9a5d935eb7dd099b2cb47448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 19 Aug 2020 23:13:23 +0200 Subject: [PATCH 0425/2775] rewritemeta: overwrite existing metadata only if no exception occurred --- fdroidserver/rewritemeta.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index b4a3f63b..72c10607 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -21,6 +21,8 @@ from argparse import ArgumentParser import os import logging import io +import tempfile +import shutil from . import _ from . import common @@ -89,10 +91,12 @@ def main(): newbuilds.append(new) app.builds = newbuilds - try: - metadata.write_metadata(path, app) - finally: - pass + # rewrite to temporary file before overwriting existsing + # file in case there's a bug in write_metadata + with tempfile.TemporaryDirectory() as tmpdir: + tmp_path = os.path.join(tmpdir, os.path.basename(path)) + metadata.write_metadata(tmp_path, app) + shutil.move(tmp_path, path) logging.debug(_("Finished")) From da31120b5ad361b9dda28e0a97bf066499f805e6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 24 Aug 2020 16:23:13 +0200 Subject: [PATCH 0426/2775] build: refactor missing srclibs error reporting for only .yml --- fdroidserver/build.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index ecf466c2..31ef0d0c 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -203,15 +203,12 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): send_dir(lib) # Copy the metadata file too... ftp.chdir(posixpath.join(homedir, 'srclibs')) - if os.path.isfile(os.path.join('srclibs', name + '.yml')): - ftp.put(os.path.join('srclibs', name + '.yml'), - name + '.yml') + srclibsfile = os.path.join('srclibs', name + '.yml') + if os.path.isfile(srclibsfile): + ftp.put(srclibsfile, os.path.basename(srclibsfile)) else: - raise BuildException("can not find metadata file for " - "'{name}', please make sure it is " - "present in your 'srclibs' folder." - "(supported format: yml)" - .format(name=name)) + raise BuildException(_('cannot find required srclibs: "{path}"') + .format(path=srclibsfile)) # Copy the main app source code # (no need if it's a srclib) if (not basesrclib) and os.path.exists(build_dir): From 0b92e60266bda6d9aab2c96a0beedc927fc43a13 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 24 Aug 2020 16:52:16 +0200 Subject: [PATCH 0427/2775] handle file type detection using Pythonic methods This ditches the custom common.get_extension() for straight core Python methods. This should make the code closer to Python conventions. For example, pathlib also includes the "." in the extension it returns. --- fdroidserver/lint.py | 6 +++--- fdroidserver/metadata.py | 12 ++++-------- fdroidserver/rewritemeta.py | 12 +++++------- fdroidserver/scanner.py | 26 +++++++++++++------------- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 8fafc7a0..f94d0e28 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -520,15 +520,15 @@ def check_for_unsupported_metadata_files(basedir=""): if not os.path.exists(f + '.yml'): print(_('"%s/" has no matching metadata file!') % f) return_value = True - elif os.path.splitext(f)[1][1:] == "yml": + elif f.endswith('.yml'): packageName = os.path.splitext(os.path.basename(f))[0] if not common.is_valid_package_name(packageName): print('"' + packageName + '" is an invalid package name!\n' + 'https://developer.android.com/studio/build/application-id') return_value = True else: - print('"' + f.replace(basedir, '') - + '" is not a supported file format (use: .yml)') + print(_('"{path}" is not a supported file format (use: metadata/*.yml)') + .format(path=f.replace(basedir, ''))) return_value = True return return_value diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 60762076..eb771646 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -927,8 +927,6 @@ def _decode_bool(s): def parse_metadata(metadatapath, check_vcs=False, refresh=True): '''parse metadata file, optionally checking the git repo for metadata first''' - _ignored, ext = fdroidserver.common.get_extension(metadatapath) - app = App() app.metadatapath = metadatapath name, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath)) @@ -937,11 +935,11 @@ def parse_metadata(metadatapath, check_vcs=False, refresh=True): else: app.id = name - if ext == 'yml': + if metadatapath.endswith('.yml'): with open(metadatapath, 'r') as mf: parse_yaml_metadata(mf, app) else: - warn_or_exception(_('Unknown metadata format: {path} (use: .yml)') + warn_or_exception(_('Unknown metadata format: {path} (use: *.yml)') .format(path=metadatapath)) if check_vcs and app.Repo: @@ -1167,14 +1165,12 @@ build_cont = re.compile(r'^[ \t]') def write_metadata(metadatapath, app): - _ignored, ext = fdroidserver.common.get_extension(metadatapath) - - if ext == 'yml': + if metadatapath.endswith('.yml'): if importlib.util.find_spec('ruamel.yaml'): with open(metadatapath, 'w') as mf: return write_yaml(mf, app) else: - raise FDroidException('ruamel.yaml not installed, can not write metadata.') + raise FDroidException(_('ruamel.yaml not installed, can not write metadata.')) warn_or_exception(_('Unknown metadata format: %s') % metadatapath) diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 72c10607..5b1c1927 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -38,8 +38,7 @@ def proper_format(app): # read in metadata.py with open(app.metadatapath, 'r') as f: cur_content = f.read() - _ignored, extension = common.get_extension(app.metadatapath) - if extension == 'yml': + if app.metadatapath.endswith('.yml'): metadata.write_yaml(s, app) content = s.getvalue() s.close() @@ -68,12 +67,11 @@ def main(): for appid, app in apps.items(): path = app.metadatapath - base, ext = common.get_extension(path) - if ext != "yml": - logging.info(_("Ignoring {ext} file at '{path}'").format(ext=ext, path=path)) - continue - else: + if path.endswith('.yml'): logging.info(_("Rewriting '{appid}'").format(appid=appid)) + else: + logging.warning(_('Cannot rewrite "{path}"').format(path=path)) + continue if options.list: if not proper_format(app): diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 47526105..7e589e45 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -265,33 +265,33 @@ def scan_source(build_dir, build=metadata.Build()): continue path_in_build_dir = os.path.relpath(filepath, build_dir) - _ignored, ext = common.get_extension(path_in_build_dir) + extension = os.path.splitext(path_in_build_dir)[1] if curfile in ('gradle-wrapper.jar', 'gradlew', 'gradlew.bat'): removeproblem(curfile, path_in_build_dir, filepath) - elif ext == 'apk': + elif extension == '.apk': removeproblem(_('Android APK file'), path_in_build_dir, filepath) - elif ext == 'a': + elif extension == '.a': count += handleproblem(_('static library'), path_in_build_dir, filepath) - elif ext == 'aar': + elif extension == '.aar': count += handleproblem(_('Android AAR library'), path_in_build_dir, filepath) - elif ext == 'class': + elif extension == '.class': count += handleproblem(_('Java compiled class'), path_in_build_dir, filepath) - elif ext == 'dex': + elif extension == '.dex': count += handleproblem(_('Android DEX code'), path_in_build_dir, filepath) - elif ext == 'gz': + elif extension == '.gz': count += handleproblem(_('gzip file archive'), path_in_build_dir, filepath) - elif ext == 'so': + elif extension == '.so': count += handleproblem(_('shared library'), path_in_build_dir, filepath) - elif ext == 'zip': + elif extension == '.zip': count += handleproblem(_('ZIP file archive'), path_in_build_dir, filepath) - elif ext == 'jar': + elif extension == '.jar': for name in suspects_found(curfile): count += handleproblem('usual suspect \'%s\'' % name, path_in_build_dir, filepath) count += handleproblem(_('Java JAR file'), path_in_build_dir, filepath) - elif ext == 'java': + elif extension == '.java': if not os.path.isfile(filepath): continue with open(filepath, 'r', errors='replace') as f: @@ -300,7 +300,7 @@ def scan_source(build_dir, build=metadata.Build()): count += handleproblem('DexClassLoader', path_in_build_dir, filepath) break - elif ext == 'gradle': + elif extension == '.gradle': if not os.path.isfile(filepath): continue with open(filepath, 'r', errors='replace') as f: @@ -316,7 +316,7 @@ def scan_source(build_dir, build=metadata.Build()): if not any(r.match(url) for r in allowed_repos): count += handleproblem('unknown maven repo \'%s\'' % url, path_in_build_dir, filepath) - elif ext in ['', 'bin', 'out', 'exe']: + elif extension in ['', '.bin', '.out', '.exe']: if is_binary(filepath): count += handleproblem('binary', path_in_build_dir, filepath) From ca86c18e3351863ec25bf0448b05d3ed078777d9 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 24 Aug 2020 14:49:22 +0200 Subject: [PATCH 0428/2775] publish: reformat --- fdroidserver/publish.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index 425cba43..b766f273 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -156,14 +156,14 @@ def status_update_json(newKeyAliases, generatedKeys, signedApks): def main(): - global config, options # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] " - "[APPID[:VERCODE] [APPID[:VERCODE] ...]]") + "[APPID[:VERCODE] [APPID[:VERCODE] ...]]") common.setup_global_opts(parser) - parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) + parser.add_argument("appid", nargs='*', + help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W From eaca3d5faac78b9946563fa6cc1cac1affeb5955 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 24 Aug 2020 16:33:53 +0200 Subject: [PATCH 0429/2775] publish: better json reporting * newKeyAliases wasn't providing any useful information * generatedKeys now contains the used keyalias as well * signedApks now also records the used keyalias for each apk --- fdroidserver/publish.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index b766f273..43a7fbaf 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -141,13 +141,11 @@ def store_stats_fdroid_signing_key_fingerprints(appids, indent=None): sign_sig_key_fingerprint_list(jar_file) -def status_update_json(newKeyAliases, generatedKeys, signedApks): +def status_update_json(generatedKeys, signedApks): """Output a JSON file with metadata about this run""" logging.debug(_('Outputting JSON')) output = common.setup_status_output(start_timestamp) - if newKeyAliases: - output['newKeyAliases'] = newKeyAliases if generatedKeys: output['generatedKeys'] = generatedKeys if signedApks: @@ -364,9 +362,7 @@ def main(): p = FDroidPopen(cmd, envs=env_vars) if p.returncode != 0: raise BuildException("Failed to generate key", p.output) - if appid not in generated_keys: - generated_keys[appid] = set() - generated_keys[appid].add(appid) + generated_keys[appid] = keyalias signed_apk_path = os.path.join(output_dir, apkfilename) if os.path.exists(signed_apk_path): @@ -379,13 +375,14 @@ def main(): common.sign_apk(apkfile, signed_apk_path, keyalias) if appid not in signed_apks: signed_apks[appid] = [] - signed_apks[appid].append(apkfile) + signed_apks[appid].append({"keyalias": keyalias, + "filename": apkfile}) publish_source_tarball(apkfilename, unsigned_dir, output_dir) logging.info('Published ' + apkfilename) store_stats_fdroid_signing_key_fingerprints(allapps.keys()) - status_update_json(new_key_aliases, generated_keys, signed_apks) + status_update_json(generated_keys, signed_apks) logging.info('published list signing-key fingerprints') From 7813a17cf8ad52dc856d19d3708dc93aaefa5cae Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 24 Aug 2020 16:35:50 +0200 Subject: [PATCH 0430/2775] publish: extract a few functions out of main publish is currently not reusable from other modules as everything is happening in main. It's also not testable from python unittests. There's already a function for getting the key_alias, so we can use that. Introduce tests for the split out functions. --- fdroidserver/publish.py | 67 ++++++++++++++++++----------------------- tests/publish.TestCase | 28 +++++++++++++++++ 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index 43a7fbaf..8a6a3e81 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -153,6 +153,33 @@ def status_update_json(generatedKeys, signedApks): common.write_status_json(output) +def check_for_key_collisions(allapps): + """ + Make sure there's no collision in keyaliases from apps. + It was suggested at + https://dev.guardianproject.info/projects/bazaar/wiki/FDroid_Audit + that a package could be crafted, such that it would use the same signing + key as an existing app. While it may be theoretically possible for such a + colliding package ID to be generated, it seems virtually impossible that + the colliding ID would be something that would be a) a valid package ID, + and b) a sane-looking ID that would make its way into the repo. + Nonetheless, to be sure, before publishing we check that there are no + collisions, and refuse to do any publishing if that's the case... + :param allapps a dict of all apps to process + :return: a list of all aliases corresponding to allapps + """ + allaliases = [] + for appid in allapps: + m = hashlib.md5() # nosec just used to generate a keyalias + m.update(appid.encode('utf-8')) + keyalias = m.hexdigest()[:8] + if keyalias in allaliases: + logging.error(_("There is a keyalias collision - publishing halted")) + sys.exit(1) + allaliases.append(keyalias) + return allaliases + + def main(): global config, options @@ -199,29 +226,11 @@ def main(): logging.error("Config error - missing '{0}'".format(config['keystore'])) sys.exit(1) - # It was suggested at - # https://dev.guardianproject.info/projects/bazaar/wiki/FDroid_Audit - # that a package could be crafted, such that it would use the same signing - # key as an existing app. While it may be theoretically possible for such a - # colliding package ID to be generated, it seems virtually impossible that - # the colliding ID would be something that would be a) a valid package ID, - # and b) a sane-looking ID that would make its way into the repo. - # Nonetheless, to be sure, before publishing we check that there are no - # collisions, and refuse to do any publishing if that's the case... allapps = metadata.read_metadata() vercodes = common.read_pkg_args(options.appid, True) signed_apks = dict() - new_key_aliases = [] generated_keys = dict() - allaliases = [] - for appid in allapps: - m = hashlib.md5() # nosec just used to generate a keyalias - m.update(appid.encode('utf-8')) - keyalias = m.hexdigest()[:8] - if keyalias in allaliases: - logging.error(_("There is a keyalias collision - publishing halted")) - sys.exit(1) - allaliases.append(keyalias) + allaliases = check_for_key_collisions(allapps) logging.info(ngettext('{0} app, {1} key aliases', '{0} apps, {1} key aliases', len(allapps)).format(len(allapps), len(allaliases))) @@ -313,26 +322,8 @@ def main(): skipsigning = True # Now we sign with the F-Droid key. - - # Figure out the key alias name we'll use. Only the first 8 - # characters are significant, so we'll use the first 8 from - # the MD5 of the app's ID and hope there are no collisions. - # If a collision does occur later, we're going to have to - # come up with a new algorithm, AND rename all existing keys - # in the keystore! if not skipsigning: - if appid in config['keyaliases']: - # For this particular app, the key alias is overridden... - keyalias = config['keyaliases'][appid] - if keyalias.startswith('@'): - m = hashlib.md5() # nosec just used to generate a keyalias - m.update(keyalias[1:].encode('utf-8')) - keyalias = m.hexdigest()[:8] - else: - m = hashlib.md5() # nosec just used to generate a keyalias - m.update(appid.encode('utf-8')) - keyalias = m.hexdigest()[:8] - new_key_aliases.append(keyalias) + keyalias = key_alias(appid) logging.info("Key alias: " + keyalias) # See if we already have a key for this application, and diff --git a/tests/publish.TestCase b/tests/publish.TestCase index 88cdc48a..41863482 100755 --- a/tests/publish.TestCase +++ b/tests/publish.TestCase @@ -50,6 +50,9 @@ class PublishTest(unittest.TestCase): self.assertEqual('dc3b169e', publish.key_alias('org.test.testy')) self.assertEqual('78688a0f', publish.key_alias('org.org.org')) + self.assertEqual('ee8807d2', publish.key_alias("org.schabi.newpipe")) + self.assertEqual('b53c7e11', publish.key_alias("de.grobox.liberario")) + publish.config = {'keyaliases': {'yep.app': '@org.org.org', 'com.example.app': '1a2b3c4d'}} self.assertEqual('78688a0f', publish.key_alias('yep.app')) @@ -162,6 +165,31 @@ class PublishTest(unittest.TestCase): with mock.patch.object(sys, 'argv', ['fdroid fakesubcommand']): publish.main() + def test_check_for_key_collisions(self): + from fdroidserver.metadata import App + common.config = {} + common.fill_config_defaults(common.config) + publish.config = common.config + + # We cannot really test the negative case here as there doesn't seem + # to be a md5 collision with text input around. + # So we just test we don't trigger an exception here and get back the same number + # of aliases as we put in apps. + randomappids = [ + "org.fdroid.fdroid", + "a.b.c", + "u.v.w.x.y.z", + "lpzpkgqwyevnmzvrlaazhgardbyiyoybyicpmifkyrxkobljoz", + "vuslsm.jlrevavz.qnbsenmizhur.lprwbjiujtu.ekiho", + "w.g.g.w.p.v.f.v.gvhyz", + "nlozuqer.ufiinmrbjqboogsjgmpfks.dywtpcpnyssjmqz", + ] + allapps = {} + for appid in randomappids: + allapps[appid] = App() + allaliases = publish.check_for_key_collisions(allapps) + self.assertEqual(len(randomappids), len(allaliases)) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From a114c73c2d4f7f0117407e9fca43a2d5b221dd70 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 24 Aug 2020 19:29:57 +0200 Subject: [PATCH 0431/2775] publish: factor out the signing key creation into a method --- fdroidserver/publish.py | 65 ++++++++++++++++++++++++----------------- tests/publish.TestCase | 27 +++++++++++++++++ 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index 8a6a3e81..50492fe2 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -180,6 +180,43 @@ def check_for_key_collisions(allapps): return allaliases +def create_key_if_not_existing(keyalias): + """ + Ensures a signing key with the given keyalias exists + :return: boolean, True if a new key was created, false otherwise + """ + # See if we already have a key for this application, and + # if not generate one... + env_vars = {'LC_ALL': 'C.UTF-8', + 'FDROID_KEY_STORE_PASS': config['keystorepass'], + 'FDROID_KEY_PASS': config.get('keypass', "")} + cmd = [config['keytool'], '-list', + '-alias', keyalias, '-keystore', config['keystore'], + '-storepass:env', 'FDROID_KEY_STORE_PASS'] + if config['keystore'] == 'NONE': + cmd += config['smartcardoptions'] + p = FDroidPopen(cmd, envs=env_vars) + if p.returncode != 0: + logging.info("Key does not exist - generating...") + cmd = [config['keytool'], '-genkey', + '-keystore', config['keystore'], + '-alias', keyalias, + '-keyalg', 'RSA', '-keysize', '2048', + '-validity', '10000', + '-storepass:env', 'FDROID_KEY_STORE_PASS', + '-dname', config['keydname']] + if config['keystore'] == 'NONE': + cmd += config['smartcardoptions'] + else: + cmd += '-keypass:env', 'FDROID_KEY_PASS' + p = FDroidPopen(cmd, envs=env_vars) + if p.returncode != 0: + raise BuildException("Failed to generate key", p.output) + return True + else: + return False + + def main(): global config, options @@ -326,33 +363,7 @@ def main(): keyalias = key_alias(appid) logging.info("Key alias: " + keyalias) - # See if we already have a key for this application, and - # if not generate one... - env_vars = {'LC_ALL': 'C.UTF-8', - 'FDROID_KEY_STORE_PASS': config['keystorepass'], - 'FDROID_KEY_PASS': config.get('keypass', "")} - cmd = [config['keytool'], '-list', - '-alias', keyalias, '-keystore', config['keystore'], - '-storepass:env', 'FDROID_KEY_STORE_PASS'] - if config['keystore'] == 'NONE': - cmd += config['smartcardoptions'] - p = FDroidPopen(cmd, envs=env_vars) - if p.returncode != 0: - logging.info("Key does not exist - generating...") - cmd = [config['keytool'], '-genkey', - '-keystore', config['keystore'], - '-alias', keyalias, - '-keyalg', 'RSA', '-keysize', '2048', - '-validity', '10000', - '-storepass:env', 'FDROID_KEY_STORE_PASS', - '-dname', config['keydname']] - if config['keystore'] == 'NONE': - cmd += config['smartcardoptions'] - else: - cmd += '-keypass:env', 'FDROID_KEY_PASS' - p = FDroidPopen(cmd, envs=env_vars) - if p.returncode != 0: - raise BuildException("Failed to generate key", p.output) + if create_key_if_not_existing(keyalias): generated_keys[appid] = keyalias signed_apk_path = os.path.join(output_dir, apkfilename) diff --git a/tests/publish.TestCase b/tests/publish.TestCase index 41863482..acd2996f 100755 --- a/tests/publish.TestCase +++ b/tests/publish.TestCase @@ -11,6 +11,7 @@ # import inspect +import jks, jks.util import logging import optparse import os @@ -190,6 +191,32 @@ class PublishTest(unittest.TestCase): allaliases = publish.check_for_key_collisions(allapps) self.assertEqual(len(randomappids), len(allaliases)) + def test_create_key_if_not_existing(self): + common.config = {} + common.fill_config_defaults(common.config) + publish.config = common.config + publish.config['keystorepass'] = '123456' + publish.config['keypass'] = '654321' + publish.config['keystore'] = "keystore.jks" + publish.config['keydname'] = 'CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US' + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + keystore = jks.KeyStore.new("jks", []) + keystore.save(publish.config['keystore'], publish.config['keystorepass']) + + self.assertTrue(publish.create_key_if_not_existing("newalias")) + # The second time we try that, a new key should not be created + self.assertFalse(publish.create_key_if_not_existing("newalias")) + self.assertTrue(publish.create_key_if_not_existing("anotheralias")) + + keystore = jks.KeyStore.load(publish.config['keystore'], publish.config['keystorepass']) + self.assertCountEqual(keystore.private_keys, ["newalias", "anotheralias"]) + for alias, pk in keystore.private_keys.items(): + self.assertFalse(pk.is_decrypted()) + pk.decrypt(publish.config['keypass']) + self.assertTrue(pk.is_decrypted()) + self.assertEqual(jks.util.RSA_ENCRYPTION_OID, pk.algorithm_oid) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From d9a6bfb0a9de7904ef1cf836cd09890e1e846a04 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 24 Aug 2020 19:56:08 +0200 Subject: [PATCH 0432/2775] CI: install pyjks as dependency for tests --- .gitlab-ci.yml | 2 +- setup.py | 4 +++- tests/publish.TestCase | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a6480604..0de8ffaf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,7 +6,7 @@ variables: test: image: registry.gitlab.com/fdroid/ci-images-server:latest script: - - $pip install -e . + - $pip install -e .[test] - cd tests - ./complete-ci-tests diff --git a/setup.py b/setup.py index bade76bb..04baa9eb 100755 --- a/setup.py +++ b/setup.py @@ -52,7 +52,6 @@ def get_data_files(): with open("README.md", "r") as fh: long_description = fh.read() - setup(name='fdroidserver', version='1.2a', description='F-Droid Server Tools', @@ -88,6 +87,9 @@ setup(name='fdroidserver', 'requests >= 2.5.2, != 2.11.0, != 2.12.2, != 2.18.0', 'yamllint', ], + extras_require={ + 'test': ['pyjks'], + }, classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', diff --git a/tests/publish.TestCase b/tests/publish.TestCase index acd2996f..300ca422 100755 --- a/tests/publish.TestCase +++ b/tests/publish.TestCase @@ -11,7 +11,6 @@ # import inspect -import jks, jks.util import logging import optparse import os @@ -192,6 +191,11 @@ class PublishTest(unittest.TestCase): self.assertEqual(len(randomappids), len(allaliases)) def test_create_key_if_not_existing(self): + try: + import jks + import jks.util + except ImportError: + self.skipTest("pyjks not installed") common.config = {} common.fill_config_defaults(common.config) publish.config = common.config From 882f8cfe19fe7660ec759c32bf46cbff1cf63551 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 24 Aug 2020 21:19:59 +0200 Subject: [PATCH 0433/2775] test_check_for_key_collisions: test with an actual collision Genrated with this script: https://gitlab.com/fdroid/fdroidserver/-/merge_requests/787#note_401275883 --- tests/publish.TestCase | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/publish.TestCase b/tests/publish.TestCase index 300ca422..38691f85 100755 --- a/tests/publish.TestCase +++ b/tests/publish.TestCase @@ -171,10 +171,6 @@ class PublishTest(unittest.TestCase): common.fill_config_defaults(common.config) publish.config = common.config - # We cannot really test the negative case here as there doesn't seem - # to be a md5 collision with text input around. - # So we just test we don't trigger an exception here and get back the same number - # of aliases as we put in apps. randomappids = [ "org.fdroid.fdroid", "a.b.c", @@ -190,6 +186,10 @@ class PublishTest(unittest.TestCase): allaliases = publish.check_for_key_collisions(allapps) self.assertEqual(len(randomappids), len(allaliases)) + allapps = {'tof.cv.mpp': App(), 'j6mX276h': App()} + self.assertEqual(publish.key_alias('tof.cv.mpp'), publish.key_alias('j6mX276h')) + self.assertRaises(SystemExit, publish.check_for_key_collisions, allapps) + def test_create_key_if_not_existing(self): try: import jks From f46e99a5c49789b7a56351c6f3c98f7b93cee289 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 30 Jun 2020 02:47:53 +0200 Subject: [PATCH 0434/2775] test for #796 The extlib test is in build because it tests the interaction between prepare_source with a later scan as it is run from build.py --- tests/build.TestCase | 35 +++++++++++++++++++++++++++++++++++ tests/scanner.TestCase | 1 + 2 files changed, 36 insertions(+) diff --git a/tests/build.TestCase b/tests/build.TestCase index 183f6661..875e83e6 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -23,6 +23,7 @@ if localmodule not in sys.path: import fdroidserver.build import fdroidserver.common import fdroidserver.metadata +import fdroidserver.scanner class BuildTest(unittest.TestCase): @@ -198,6 +199,40 @@ class BuildTest(unittest.TestCase): self.assertFalse(os.path.exists('gen')) self.assertFalse(os.path.exists('gradle-wrapper.jar')) + def test_scan_with_extlib(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + os.mkdir("build") + + config = dict() + config['sdk_path'] = os.getenv('ANDROID_HOME') + config['ndk_paths'] = {'r10d': os.getenv('ANDROID_NDK_HOME')} + config['build_tools'] = 'FAKE_BUILD_TOOLS_VERSION' + fdroidserver.common.config = config + app = fdroidserver.metadata.App() + app.id = 'com.gpl.rpg.AndorsTrail' + build = fdroidserver.metadata.Build() + build.commit = 'master' + build.androidupdate = ['no'] + build.extlibs = ['android/android-support-v4r11.jar'] + os.makedirs("extlib/android") + # write a fake binary jar file the scanner should definitely error on + with open('extlib/android/android-support-v4r11.jar', 'wb') as file: + file.write(b'PK\x03\x04\x14\x00\x08\x00\x08\x00-\x0eiA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x04\x00META-INF/\xfe\xca\x00\x00\x03\x00PK\x07\x08\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00') + + class FakeVcs(): + # no need to change to the correct commit here + def gotorevision(self, rev, refresh=True): + pass + + def getsrclib(self): + return None + + fdroidserver.common.prepare_source(FakeVcs(), app, build, + "build", "ignore", "extlib") + count = fdroidserver.scanner.scan_source("build", build) + self.assertEqual(0, count, "Shouldn't error on jar from extlib") + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 2dbfbbba..4636a4eb 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -271,6 +271,7 @@ class ScannerTest(unittest.TestCase): self.assertEqual(len(data), len(urls), 'each data example should produce a URL') + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 78491a0a5be89ec0ffff1365688bf84e7e4ff585 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 25 Jun 2020 01:14:40 +0200 Subject: [PATCH 0435/2775] add used extlibs to scanignore path fixes fdroid/fdroidserver#795 --- fdroidserver/common.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 5f057e40..d76b62e5 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2111,6 +2111,13 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= if not os.path.exists(libsrc): raise BuildException("Missing extlib file {0}".format(libsrc)) shutil.copyfile(libsrc, os.path.join(libsdir, libf)) + # Add extlibs to scanignore (this is relative to the build dir root, *sigh*) + if build.subdir: + scanignorepath = os.path.join(build.subdir, 'libs', libf) + else: + scanignorepath = os.path.join('libs', libf) + if scanignorepath not in build.scanignore: + build.scanignore.append(scanignorepath) # Run a pre-build command if one is required if build.prebuild: From 61736f3f50abbe3ebd402bec27997467c64cd815 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 30 Jun 2020 00:02:04 +0200 Subject: [PATCH 0436/2775] scanner: add test for #759 --- tests/scanner.TestCase | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/scanner.TestCase b/tests/scanner.TestCase index 4636a4eb..3c18becc 100755 --- a/tests/scanner.TestCase +++ b/tests/scanner.TestCase @@ -270,6 +270,26 @@ class ScannerTest(unittest.TestCase): self.assertTrue(found, 'this block should produce a URL:\n' + entry) self.assertEqual(len(data), len(urls), 'each data example should produce a URL') + def test_scan_gradle_file_with_multiple_problems(self): + """Check that the scanner can handle scandelete with gradle files with multiple problems""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + fdroidserver.scanner.config = None + fdroidserver.scanner.options = mock.Mock() + build = fdroidserver.metadata.Build() + build.scandelete = ['build.gradle'] + with open('build.gradle', 'w') as fp: + fp.write(textwrap.dedent(""" + maven { + url 'https://maven.fabric.io/public' + } + maven { + url 'https://evilcorp.com/maven' + } + """)) + count = fdroidserver.scanner.scan_source(testdir, build) + self.assertFalse(os.path.exists("build.gradle")) + self.assertEqual(0, count, 'there should be this many errors') if __name__ == "__main__": From 03e723b1af0f45b220c88992dff73a0f3aaaa033 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 26 Jun 2020 01:55:21 +0200 Subject: [PATCH 0437/2775] fix crash when scanner wants to remove the same file more than once A file can be flagged for multiple problems (i.e. multiple unknown maven repos in one build.gradle file that is included in a scandelete path). The scanner will try to delete it once for every problem detected, we don't really care, as long as the file is gone. fixes fdroid/fdroidserver#759 --- fdroidserver/scanner.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 7e589e45..7474e87a 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -188,7 +188,13 @@ def scan_source(build_dir, build=metadata.Build()): logging.info(msg) if json_per_build is not None: json_per_build['infos'].append([msg, path_in_build_dir]) - os.remove(filepath) + try: + os.remove(filepath) + except FileNotFoundError: + # File is already gone, nothing to do. + # This can happen if we find multiple problems in one file that is setup for scandelete + # I.e. build.gradle files containig multiple unknown maven repos. + pass return 0 def warnproblem(what, path_in_build_dir): From fce47216950565fb631ce20756c9b8aef4928b30 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 18 Aug 2020 22:31:44 +0200 Subject: [PATCH 0438/2775] add a vcs.TestCase --- tests/vcs.TestCase | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100755 tests/vcs.TestCase diff --git a/tests/vcs.TestCase b/tests/vcs.TestCase new file mode 100755 index 00000000..ffed7b89 --- /dev/null +++ b/tests/vcs.TestCase @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 + +import inspect +import logging +import optparse +import os +import sys +import tempfile +import unittest + +from git import Repo + +localmodule = os.path.realpath( + os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) +print('localmodule: ' + localmodule) +if localmodule not in sys.path: + sys.path.insert(0, localmodule) + +import fdroidserver.build +import fdroidserver.common +import fdroidserver.metadata +import fdroidserver.scanner + + +class VCSTest(unittest.TestCase): + """For some reason the VCS classes are in fdroidserver/common.py""" + + def setUp(self): + logging.basicConfig(level=logging.DEBUG) + self.basedir = os.path.join(localmodule, 'tests') + self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) + if not os.path.exists(self.tmpdir): + os.makedirs(self.tmpdir) + os.chdir(self.basedir) + + def test_remote_set_head_can_fail(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + # First create an upstream repo with one commit + upstream_repo = Repo.init("upstream_repo") + with open(upstream_repo.working_dir + "/file", 'w') as f: + f.write("Hello World!") + upstream_repo.index.add([upstream_repo.working_dir + "/file"]) + upstream_repo.index.commit("initial commit") + commitid = upstream_repo.head.commit.hexsha + + # Now clone it once manually, like gitlab runner gitlab-runner sets up a repo during CI + clone1 = Repo.init("clone1") + clone1.create_remote("upstream", "file://" + upstream_repo.working_dir) + clone1.remote("upstream").fetch() + clone1.head.reference = clone1.commit(commitid) + clone1.head.reset(index=True, working_tree=True) + self.assertTrue(clone1.head.is_detached) + + # and now we want to use this clone as a source repo for fdroid build + config = {} + os.mkdir("build") + config['sdk_path'] = os.getenv('ANDROID_HOME') + config['ndk_paths'] = {'r10d': os.getenv('ANDROID_NDK_HOME')} + config['build_tools'] = 'FAKE_BUILD_TOOLS_VERSION' + config['java_paths'] = {'fake': 'fake'} + fdroidserver.common.config = config + app = fdroidserver.metadata.App() + app.RepoType = 'git' + app.Repo = clone1.working_dir + app.id = 'com.gpl.rpg.AndorsTrail' + build = fdroidserver.metadata.Build() + build.commit = commitid + build.androidupdate = ['no'] + vcs, build_dir = fdroidserver.common.setup_vcs(app) + # force an init of the repo, the remote head error only occurs on the second gotorevision call + vcs.gotorevision(build.commit) + fdroidserver.common.prepare_source(vcs, app, build, + build_dir=build_dir, srclib_dir="ignore", extlib_dir="ignore") + self.assertTrue(os.path.isfile("build/com.gpl.rpg.AndorsTrail/file")) + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + + parser = optparse.OptionParser() + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="Spew out even more information than normal") + (fdroidserver.common.options, args) = parser.parse_args(['--verbose']) + + newSuite = unittest.TestSuite() + newSuite.addTest(unittest.makeSuite(VCSTest)) + unittest.main(failfast=False) From d5311fff09ebdfacd6620209c075d163854cc18a Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 29 Jun 2020 14:30:06 +0200 Subject: [PATCH 0439/2775] vcs: don't fail when git remote set-head fails There's valid use-cases for setups where set-head --auto fails. This happens when building an app from a gitlab CI checkout where no remote tracking branches are setup. This isn't really a fatal error. When a remote HEAD exists we'll continue setting it and if none exists and something requires this being set up later on (either a build script or fdroid checkupdates) then we'll fail later on with "origin/HEAD not being known to git". By not failing early we allow the majority of use-cases that don't need a remote HEAD to continue with just a warning. The setup in which this can be reproduced is as follows: (This is roughly what gitlab runner does when setting up a git checkout for CI) - mkdir test && cd test - git init - git remote add https://gitlab.com/Bubu/fdroidclassic.git - git fetch --all - git checkout db0d2a9a5d1d89101a344169013ac5d518185f31 - mkdir nested_repo && cd nested_repo - git clone .. . - git remote set-head origin --auto > error: Cannot determine remote HEAD --- fdroidserver/common.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index d76b62e5..dd259963 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -994,12 +994,14 @@ class vcs_git(vcs): if p.returncode != 0: lines = p.output.splitlines() if 'Multiple remote HEAD branches' not in lines[0]: - raise VCSException(_("Git remote set-head failed"), p.output) - branch = lines[1].split(' ')[-1] - p2 = FDroidPopen(['git', 'remote', 'set-head', 'origin', '--', branch], - cwd=self.local, output=False) - if p2.returncode != 0: - raise VCSException(_("Git remote set-head failed"), p.output + '\n' + p2.output) + logging.warning(_("Git remote set-head failed: \"%s\"") % p.output.strip()) + else: + branch = lines[1].split(' ')[-1] + p2 = FDroidPopen(['git', 'remote', 'set-head', 'origin', '--', branch], + cwd=self.local, output=False) + if p2.returncode != 0: + logging.warning(_("Git remote set-head failed: \"%s\"") + % p.output.strip() + '\n' + p2.output.strip()) self.refreshed = True # 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. From a301a1ba93cabc01f7d4ca7accefc87bd82ea678 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 29 Jun 2020 21:56:52 +0200 Subject: [PATCH 0440/2775] add test for correct `added` date for apps --- tests/run-tests | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/run-tests b/tests/run-tests index a5435351..551c5f55 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -607,6 +607,29 @@ grep -F 'info.guardianproject.urzip_100.apk' repo/index-v1.json repo/index.xml grep -F 'info.guardianproject.urzip_100_b4964fd.apk' repo/index-v1.json ! grep -F 'info.guardianproject.urzip_100_b4964fd.apk' repo/index.xml +#------------------------------------------------------------------------------# +echo_header "test for added date being set correctly for repo and archive" +REPOROOT=`create_test_dir` +cd $REPOROOT +fdroid_init_with_prebuilt_keystore +mkdir -p {repo,archive,metadata,stats} +cp $WORKSPACE/tests/repo/com.politedroid_5.apk archive +cp $WORKSPACE/tests/repo/com.politedroid_6.apk repo +cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata +#TODO: the timestamp of the oldest apk in the file should be used, even if that +# doesn't exist anymore +echo "com.politedroid_4.apk com.politedroid 2016-01-01" > stats/known_apks.txt +echo "com.politedroid_5.apk com.politedroid 2017-01-01" >> stats/known_apks.txt +echo "com.politedroid_6.apk com.politedroid 2018-01-01" >> stats/known_apks.txt +sed -i -e 's/ArchivePolicy:.*/ArchivePolicy: 1 versions/' metadata/com.politedroid.yml +# Get the java ms timestamp from UTC time +timestamp=$(date -u --date=2017-01-01 +%s)000 + +$fdroid update --pretty --nosign +grep -F "\"added\": $timestamp" repo/index-v1.json +# the archive will have the added timestamp for the app and for the apk, both need to be there +if [ $(grep -F "\"added\": $timestamp" archive/index-v1.json | wc -l) == 2 ]; then true; else false;fi + #------------------------------------------------------------------------------# echo_header "test whatsnew from fastlane without CVC set" REPOROOT=`create_test_dir` From a656be82ae259c38607105ccfabd7f89c78506d8 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 29 Jun 2020 21:45:22 +0200 Subject: [PATCH 0441/2775] update: calculate added date for an app over all apks This was accidentally changed in !756 because the functionality was hidden in `apply_info_from_latest_apk` which is a less than stellar name for something that also applies infos from app->apk and in this case did apply info from *oldest* apk->app. So instead move that into a separate step. Note: This restores the previous behaviour. There's discussion in #801 on further changes to make the added date also work for repos which don't keep an archive at all. --- fdroidserver/index.py | 2 +- fdroidserver/update.py | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index b115643b..7e76f299 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -134,7 +134,7 @@ def make_v1(apps, packages, repodir, repodict, requestsdict, fdroid_signing_key_ return sorted(list(obj)) if isinstance(obj, datetime): # Java prefers milliseconds - # we also need to accound for time zone/daylight saving time + # we also need to account for time zone/daylight saving time return int(calendar.timegm(obj.timetuple()) * 1000) if isinstance(obj, dict): d = collections.OrderedDict() diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 3ddf602c..eec7c2df 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1974,12 +1974,6 @@ def apply_info_from_latest_apk(apps, apks): if app.NoSourceSince: apk['antiFeatures'].add('NoSourceSince') - if 'added' in apk: - if not app.added or apk['added'] < app.added: - app.added = apk['added'] - if not app.lastUpdated or apk['added'] > app.lastUpdated: - app.lastUpdated = apk['added'] - if not app.added: logging.debug("Don't know when " + appid + " was added") if not app.lastUpdated: @@ -2166,6 +2160,27 @@ def create_metadata_from_template(apk): logging.info(_("Generated skeleton metadata for {appid}").format(appid=apk['packageName'])) +def read_added_date_from_all_apks(apps, apks): + """ + Added dates come from the stats/known_apks.txt file but are + read when scanning apks and thus need to be applied form apk + level to app level for _all_ apps and not only form non-archived + ones + + TODO: read the added dates directly from known_apks.txt instead of + going through apks that way it also works for for repos that + don't keep an archive of apks. + """ + for appid, app in apps.items(): + for apk in apks: + if apk['packageName'] == appid: + if 'added' in apk: + if not app.added or apk['added'] < app.added: + app.added = apk['added'] + if not app.lastUpdated or apk['added'] > app.lastUpdated: + app.lastUpdated = apk['added'] + + def read_names_from_apks(apps, apks): """This is a stripped down copy of apply_info_from_latest_apk that only parses app names""" for appid, app in apps.items(): @@ -2384,6 +2399,10 @@ def main(): # This will be done again (as part of apply_info_from_latest_apk) for repo and archive # separately later on, but it's fairly cheap anyway. read_names_from_apks(apps, apks + archapks) + # The added date currently comes from the oldest apk which might be in the archive. + # So we need this populated at app level before continuing with only processing /repo + # or /archive + read_added_date_from_all_apks(apps, apks + archapks) if len(repodirs) > 1: archive_old_apks(apps, apks, archapks, repodirs[0], repodirs[1], config['archive_older']) From d07b4123e979810ed22205e8ecd0fd409193aa0f Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 29 Jun 2020 22:46:03 +0200 Subject: [PATCH 0442/2775] scanner: docstrings for handleproblem functions --- fdroidserver/scanner.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 7474e87a..4b0c4be0 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -62,7 +62,7 @@ def scan_binary(apkfile): usual_suspects = { # The `apkanalyzer dex packages` output looks like this: # M d 1 1 93 - # The first column has P/C/M/F for package, class, methos or field + # The first column has P/C/M/F for package, class, method or field # The second column has x/k/r/d for removed, kept, referenced and defined. # We already filter for defined only in the apkanalyzer call. 'r' will be # for things referenced but not distributed in the apk. @@ -177,6 +177,11 @@ def scan_source(build_dir, build=metadata.Build()): return False def ignoreproblem(what, path_in_build_dir): + """ + :param what: string describing the problem, will be printed in log messages + :param path_in_build_dir: path to the file relative to `build`-dir + "returns: 0 as we explicitly ignore the file, so don't count an error + """ msg = ('Ignoring %s at %s' % (what, path_in_build_dir)) logging.info(msg) if json_per_build is not None: @@ -184,6 +189,12 @@ def scan_source(build_dir, build=metadata.Build()): return 0 def removeproblem(what, path_in_build_dir, filepath): + """ + :param what: string describing the problem, will be printed in log messages + :param path_in_build_dir: path to the file relative to `build`-dir + :param filepath: Path (relative to our current path) to the file + "returns: 0 as we deleted the offending file + """ msg = ('Removing %s at %s' % (what, path_in_build_dir)) logging.info(msg) if json_per_build is not None: @@ -198,6 +209,11 @@ def scan_source(build_dir, build=metadata.Build()): return 0 def warnproblem(what, path_in_build_dir): + """ + :param what: string describing the problem, will be printed in log messages + :param path_in_build_dir: path to the file relative to `build`-dir + :returns: 0, as warnings don't count as errors + """ if toignore(path_in_build_dir): return 0 logging.warning('Found %s at %s' % (what, path_in_build_dir)) @@ -206,6 +222,14 @@ def scan_source(build_dir, build=metadata.Build()): return 0 def handleproblem(what, path_in_build_dir, filepath): + """Dispatches to problem handlers (ignore, delete, warn) or returns 1 + for increasing the error count + + :param what: string describing the problem, will be printed in log messages + :param path_in_build_dir: path to the file relative to `build`-dir + :param filepath: Path (relative to our current path) to the file + :returns: 0 if the problem was ignored/deleted/is only a warning, 1 otherwise + """ if toignore(path_in_build_dir): return ignoreproblem(what, path_in_build_dir) if todelete(path_in_build_dir): From 059ebd4bc963d7c834a8f160ece4c4b6194d1327 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 18 Aug 2020 22:33:12 +0200 Subject: [PATCH 0443/2775] tests: add check that we trigger a scanner error without setting it as extlib --- tests/build.TestCase | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/build.TestCase b/tests/build.TestCase index 875e83e6..95863ac6 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -214,7 +214,6 @@ class BuildTest(unittest.TestCase): build = fdroidserver.metadata.Build() build.commit = 'master' build.androidupdate = ['no'] - build.extlibs = ['android/android-support-v4r11.jar'] os.makedirs("extlib/android") # write a fake binary jar file the scanner should definitely error on with open('extlib/android/android-support-v4r11.jar', 'wb') as file: @@ -228,12 +227,24 @@ class BuildTest(unittest.TestCase): def getsrclib(self): return None + # Test we trigger a scanner error without extlibs + build.extlibs = [] + os.makedirs('build/libs') + shutil.copy('extlib/android/android-support-v4r11.jar', 'build/libs') + fdroidserver.common.prepare_source(FakeVcs(), app, build, + "build", "ignore", "extlib") + count = fdroidserver.scanner.scan_source("build", build) + self.assertEqual(1, count, "Should produce a scanner error without extlib") + + # Now try again as an extlib + build.extlibs = ['android/android-support-v4r11.jar'] fdroidserver.common.prepare_source(FakeVcs(), app, build, "build", "ignore", "extlib") count = fdroidserver.scanner.scan_source("build", build) self.assertEqual(0, count, "Shouldn't error on jar from extlib") + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 34717fe88a2fc662e028c11b74c46d947e6419cf Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 18 Aug 2020 22:33:51 +0200 Subject: [PATCH 0444/2775] fix typoes --- fdroidserver/update.py | 2 +- tests/build.TestCase | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index eec7c2df..1ddbd8e8 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -2164,7 +2164,7 @@ def read_added_date_from_all_apks(apps, apks): """ Added dates come from the stats/known_apks.txt file but are read when scanning apks and thus need to be applied form apk - level to app level for _all_ apps and not only form non-archived + level to app level for _all_ apps and not only from non-archived ones TODO: read the added dates directly from known_apks.txt instead of diff --git a/tests/build.TestCase b/tests/build.TestCase index 95863ac6..25655229 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -244,7 +244,6 @@ class BuildTest(unittest.TestCase): self.assertEqual(0, count, "Shouldn't error on jar from extlib") - if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 394ad8f8630b9db1eec74f0410679c9d49c70926 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 25 Aug 2020 23:05:56 +0200 Subject: [PATCH 0445/2775] add gradle 6.6.1 --- gradlew-fdroid | 3 ++- makebuildserver | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 9b9899f8..1b32b4e1 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -140,6 +140,7 @@ get_sha() { '6.5') echo '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f' ;; '6.5.1') echo '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a' ;; '6.6') echo 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025' ;; + '6.6.1') echo '7873ed5287f47ca03549ab8dcb6dc877ac7f0e3d7b1eb12685161d10080910ac' ;; *) exit 1 esac } @@ -160,7 +161,7 @@ d_plugin_k=(4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 d_plugin_v=(6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.6 6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.6.1 6.6 6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index b0923498..00be7804 100755 --- a/makebuildserver +++ b/makebuildserver @@ -389,12 +389,10 @@ CACHE_FILES = [ '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768'), ('https://services.gradle.org/distributions/gradle-6.4.1-bin.zip', 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd'), - ('https://services.gradle.org/distributions/gradle-6.5-bin.zip', - '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f'), ('https://services.gradle.org/distributions/gradle-6.5.1-bin.zip', - '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a'), - ('https://services.gradle.org/distributions/gradle-6.6-bin.zip', 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025'), + ('https://services.gradle.org/distributions/gradle-6.6.1-bin.zip', + '7873ed5287f47ca03549ab8dcb6dc877ac7f0e3d7b1eb12685161d10080910ac'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From bc6fa986d1dbd060dc348310148c0e81e594d065 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 25 Aug 2020 23:09:28 +0200 Subject: [PATCH 0446/2775] fix vcs test It doesn't need a valid sdk_path, so just set it to something. The test was failing when ANDROID_HOME wasn't set in the env. --- tests/vcs.TestCase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vcs.TestCase b/tests/vcs.TestCase index ffed7b89..a94521fa 100755 --- a/tests/vcs.TestCase +++ b/tests/vcs.TestCase @@ -57,7 +57,7 @@ class VCSTest(unittest.TestCase): # and now we want to use this clone as a source repo for fdroid build config = {} os.mkdir("build") - config['sdk_path'] = os.getenv('ANDROID_HOME') + config['sdk_path'] = 'MOCKPATH' config['ndk_paths'] = {'r10d': os.getenv('ANDROID_NDK_HOME')} config['build_tools'] = 'FAKE_BUILD_TOOLS_VERSION' config['java_paths'] = {'fake': 'fake'} From eb57723096cf9ab7a359d730fa61c5a5d8e48788 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Tue, 25 Aug 2020 23:15:25 +0200 Subject: [PATCH 0447/2775] fix accidentally changed hash of gradle 6.5.1 This was changed in 394ad8f8630b9db1eec74f0410679c9d49c70926 when deleting 6.6 from makebuildserver but deleting one line up instead of down. --- makebuildserver | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makebuildserver b/makebuildserver index 00be7804..909d9301 100755 --- a/makebuildserver +++ b/makebuildserver @@ -390,7 +390,7 @@ CACHE_FILES = [ ('https://services.gradle.org/distributions/gradle-6.4.1-bin.zip', 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd'), ('https://services.gradle.org/distributions/gradle-6.5.1-bin.zip', - 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025'), + '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a'), ('https://services.gradle.org/distributions/gradle-6.6.1-bin.zip', '7873ed5287f47ca03549ab8dcb6dc877ac7f0e3d7b1eb12685161d10080910ac'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', From d59594861676e2517fa10d085135be852cd4f931 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 26 Aug 2020 10:40:03 +0200 Subject: [PATCH 0448/2775] jenkins-test: remove rewritemeta, it is well covered elsewhere The jenkins.debian.net tests are brittle enough as it is. [skip ci] - this doesn't run on gitlab-ci --- jenkins-test | 5 ----- 1 file changed, 5 deletions(-) diff --git a/jenkins-test b/jenkins-test index 945d5d37..de61859c 100755 --- a/jenkins-test +++ b/jenkins-test @@ -77,9 +77,4 @@ sed -i '/^repo_pubkey = /d' config.py # when everything is copied over to run on SIGN machine ../fdroid signindex --verbose -../fdroid rewritemeta --quiet -git --no-pager diff -git status -ls -lR cache || true - ../fdroid checkupdates --auto --autoonly --commit From 637c73a88224a00d601afe41d820fb666e851a20 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 28 Aug 2020 17:46:53 +0200 Subject: [PATCH 0449/2775] unpin pyasn1_modules It currently runs fine on archlinux with pyasn1-modules 0.2.8. And guix just reported packaging it with 0.2.2 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 04baa9eb..44cec5bd 100755 --- a/setup.py +++ b/setup.py @@ -78,8 +78,8 @@ setup(name='fdroidserver', 'paramiko', 'Pillow', 'apache-libcloud >= 0.14.1', - 'pyasn1 <0.5.0, >=0.4.1', - 'pyasn1-modules == 0.2.1', + 'pyasn1 >=0.4.1, < 0.5.0', + 'pyasn1-modules >= 0.2.1, < 0.3', 'python-vagrant', 'PyYAML', 'qrcode', From c90a72e14db2250f35e3f8ad4658426f02cb079e Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Sun, 30 Aug 2020 20:06:00 +0200 Subject: [PATCH 0450/2775] scanner: check for `test` in path relative to build dir This was degrading scanner errors to warnings whenever the path from the current running install of fdroidserver contained test, as has been happening in the CI image builder: https://gitlab.com/fdroid/ci-images-server/-/blob/master/test#L6 --- fdroidserver/scanner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 4b0c4be0..8b1a31cf 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -234,7 +234,7 @@ def scan_source(build_dir, build=metadata.Build()): return ignoreproblem(what, path_in_build_dir) if todelete(path_in_build_dir): return removeproblem(what, path_in_build_dir, filepath) - if 'src/test' in filepath or '/test/' in filepath: + if 'src/test' in filepath or '/test/' in path_in_build_dir: return warnproblem(what, path_in_build_dir) if options and 'json' in vars(options) and options.json: json_per_build['errors'].append([what, path_in_build_dir]) From 768a91370cbf2d79a495b5a2bc4ba6ab52ec0971 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 9 Sep 2020 12:06:21 +0200 Subject: [PATCH 0451/2775] publish: use apksigner for signing apks with targetSDK>=30 This makes apksigner a hard requirement of the signing procedure. We'll first try to find a globally installed version from PATH and if that's not available fall back to using a version from build-tools. Future TODO: always sign with apksigner, blocked on signature transplant support for apksigv2/v3 Closes fdroid/fdroidserver#634 Closes fdroid/fdroidserver#827 --- fdroidserver/common.py | 109 ++++++++++++-------- fdroidserver/nightly.py | 2 +- tests/common.TestCase | 127 ++++++++++++------------ tests/minimal_targetsdk_30_unsigned.apk | Bin 0 -> 2294 bytes 4 files changed, 130 insertions(+), 108 deletions(-) create mode 100644 tests/minimal_targetsdk_30_unsigned.apk diff --git a/fdroidserver/common.py b/fdroidserver/common.py index dd259963..0e744c69 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -69,9 +69,8 @@ from .asynchronousfilereader import AsynchronousFileReader # The path to this fdroidserver distribution FDROID_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) -# this is the build-tools version, aapt has a separate version that -# has to be manually set in test_aapt_version() -MINIMUM_AAPT_VERSION = '26.0.0' +# We need 26.0.0 for aapt but that doesn't ship with apksigner, so take the next higher version +MINIMUM_BUILD_TOOLS_VERSION = '26.0.1' VERCODE_OPERATION_RE = re.compile(r'^([ 0-9/*+-]|%c)+$') @@ -111,7 +110,7 @@ default_config = { 'r16b': None, }, 'cachedir': os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), - 'build_tools': MINIMUM_AAPT_VERSION, + 'build_tools': MINIMUM_BUILD_TOOLS_VERSION, 'force_build_tools': False, 'java_paths': None, 'scan_binary': False, @@ -466,13 +465,13 @@ def test_aapt_version(aapt): # the Debian package has the version string like "v0.2-23.0.2" too_old = False if '.' in bugfix: - if LooseVersion(bugfix) < LooseVersion(MINIMUM_AAPT_VERSION): + if LooseVersion(bugfix) < LooseVersion(MINIMUM_BUILD_TOOLS_VERSION): too_old = True elif LooseVersion('.'.join((major, minor, bugfix))) < LooseVersion('0.2.4062713'): too_old = True if too_old: logging.warning(_("'{aapt}' is too old, fdroid requires build-tools-{version} or newer!") - .format(aapt=aapt, version=MINIMUM_AAPT_VERSION)) + .format(aapt=aapt, version=MINIMUM_BUILD_TOOLS_VERSION)) else: logging.warning(_('Unknown version of aapt, might cause problems: ') + output) @@ -2333,7 +2332,7 @@ def _get_androguard_APK(apkfile): try: from androguard.core.bytecodes.apk import APK except ImportError: - raise FDroidException("androguard library is not installed and aapt not present") + raise FDroidException("androguard library is not installed") return APK(apkfile) @@ -2510,21 +2509,6 @@ def get_native_code(apkfile): return sorted(list(archset)) -def get_minSdkVersion(apkfile): - """Extract the minimum supported Android SDK from an APK using androguard - - :param apkfile: path to an APK file. - :returns: the integer representing the SDK version - """ - - try: - apk = _get_androguard_APK(apkfile) - except FileNotFoundError: - raise FDroidException(_('Reading minSdkVersion failed: "{apkfilename}"') - .format(apkfilename=apkfile)) - return int(apk.get_min_sdk_version()) - - class PopenResult: def __init__(self): self.returncode = None @@ -2954,7 +2938,7 @@ def metadata_find_developer_signing_files(appid, vercode): return None -def apk_strip_signatures(signed_apk, strip_manifest=False): +def apk_strip_v1_signatures(signed_apk, strip_manifest=False): """Removes signatures from APK. :param signed_apk: path to apk file. @@ -3037,36 +3021,73 @@ def apk_extract_signatures(apkpath, outdir, manifest=True): def sign_apk(unsigned_path, signed_path, keyalias): """Sign and zipalign an unsigned APK, then save to a new file, deleting the unsigned - android-18 (4.3) finally added support for reasonable hash - algorithms, like SHA-256, before then, the only options were MD5 - and SHA1 :-/ This aims to use SHA-256 when the APK does not target + Use apksigner for making v2 and v3 signature for apks with targetSDK >=30 as + otherwise they won't be installable on Android 11/R. + + Otherwise use jarsigner for v1 only signatures until we have apksig v2/v3 + signature transplantig support. + + When using jarsigner we need to manually select the hash algorithm, + apksigner does this automatically. Apksigner also does the zipalign for us. + + SHA-256 support was added in android-18 (4.3), before then, the only options were MD5 + and SHA1. This aims to use SHA-256 when the APK does not target older Android versions, and is therefore safe to do so. https://issuetracker.google.com/issues/36956587 https://android-review.googlesource.com/c/platform/libcore/+/44491 """ - - if get_minSdkVersion(unsigned_path) < 18: - signature_algorithm = ['-sigalg', 'SHA1withRSA', '-digestalg', 'SHA1'] + apk = _get_androguard_APK(unsigned_path) + if int(apk.get_target_sdk_version()) >= 30: + if config['keystore'] == 'NONE': + replacements = {'-storetype': '--ks-type', + '-providerName': '--ks-provider-name', + '-providerClass': '--ks-provider-class', + '-providerArg': '--ks-provider-arg'} + signing_args = [replacements.get(n, n) for n in config['smartcardoptions']] + else: + signing_args = ['--key-pass', 'env:FDROID_KEY_PASS'] + if not set_command_in_config('apksigner'): + config['apksigner'] = find_sdk_tools_cmd('apksigner') + cmd = [config['apksigner'], 'sign', + '--ks', config['keystore'], + '--ks-pass', 'env:FDROID_KEY_STORE_PASS'] + cmd += signing_args + cmd += ['--ks-key-alias', keyalias, + '--in', unsigned_path, + '--out', signed_path] + p = FDroidPopen(cmd, envs={ + 'FDROID_KEY_STORE_PASS': config['keystorepass'], + 'FDROID_KEY_PASS': config.get('keypass', "")}) + if p.returncode != 0: + raise BuildException(_("Failed to sign application"), p.output) + os.remove(unsigned_path) else: - signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256'] - cmd = [config['jarsigner'], '-keystore', config['keystore'], - '-storepass:env', 'FDROID_KEY_STORE_PASS'] - if config['keystore'] == 'NONE': - cmd += config['smartcardoptions'] - else: - cmd += '-keypass:env', 'FDROID_KEY_PASS' - p = FDroidPopen(cmd + signature_algorithm + [unsigned_path, keyalias], - envs={ - 'FDROID_KEY_STORE_PASS': config['keystorepass'], - 'FDROID_KEY_PASS': config.get('keypass', "")}) - if p.returncode != 0: - raise BuildException(_("Failed to sign application"), p.output) + if int(apk.get_min_sdk_version()) < 18: + signature_algorithm = ['-sigalg', 'SHA1withRSA', '-digestalg', 'SHA1'] + else: + signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256'] + if config['keystore'] == 'NONE': + signing_args = config['smartcardoptions'] + else: + signing_args = ['-keypass:env', 'FDROID_KEY_PASS'] - _zipalign(unsigned_path, signed_path) - os.remove(unsigned_path) + cmd = [config['jarsigner'], '-keystore', config['keystore'], + '-storepass:env', 'FDROID_KEY_STORE_PASS'] + cmd += signing_args + cmd += signature_algorithm + cmd += [unsigned_path, keyalias] + print(cmd) + p = FDroidPopen(cmd, envs={ + 'FDROID_KEY_STORE_PASS': config['keystorepass'], + 'FDROID_KEY_PASS': config.get('keypass', "")}) + if p.returncode != 0: + raise BuildException(_("Failed to sign application"), p.output) + + _zipalign(unsigned_path, signed_path) + os.remove(unsigned_path) def verify_apks(signed_apk, unsigned_apk, tmp_dir): diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index cedf29a4..daca2082 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -268,7 +268,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, os.chmod(apkfilename, 0o644) logging.debug(_('Resigning {apkfilename} with provided debug.keystore') .format(apkfilename=os.path.basename(apkfilename))) - common.apk_strip_signatures(apkfilename, strip_manifest=True) + common.apk_strip_v1_signatures(apkfilename, strip_manifest=True) common.sign_apk(apkfilename, destapk, KEY_ALIAS) if options.verbose: diff --git a/tests/common.TestCase b/tests/common.TestCase index 78ab8da3..eb67836c 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -633,15 +633,13 @@ class CommonTest(unittest.TestCase): fdroidserver.common.apk_signer_fingerprint_short(apkfile)) def test_sign_apk(self): - try: - fdroidserver.common.find_sdk_tools_cmd('aapt') - fdroidserver.common.find_sdk_tools_cmd('zipalign') - except fdroidserver.exception.FDroidException: - print('\n\nSKIPPING test_sign_apk, zipalign is not installed!\n') - return - fdroidserver.common.config = None config = fdroidserver.common.read_config(fdroidserver.common.options) + try: + fdroidserver.common.find_sdk_tools_cmd('zipalign') + except fdroidserver.exception.FDroidException: + self.skipTest('SKIPPING test_sign_apk, zipalign not installed!') + config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') config['keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' @@ -653,10 +651,10 @@ class CommonTest(unittest.TestCase): testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) unsigned = os.path.join(testdir, 'urzip-release-unsigned.apk') signed = os.path.join(testdir, 'urzip-release.apk') + shutil.copy(os.path.join(self.basedir, 'urzip-release-unsigned.apk'), testdir) self.assertFalse(fdroidserver.common.verify_apk_signature(unsigned)) - shutil.copy(os.path.join(self.basedir, 'urzip-release-unsigned.apk'), testdir) fdroidserver.common.sign_apk(unsigned, signed, config['keyalias']) self.assertTrue(os.path.isfile(signed)) self.assertFalse(os.path.isfile(unsigned)) @@ -667,20 +665,37 @@ class CommonTest(unittest.TestCase): signed = os.path.join(testdir, 'duplicate.permisssions_9999999.apk') shutil.copy(os.path.join(self.basedir, 'repo', 'duplicate.permisssions_9999999.apk'), os.path.join(unsigned)) - fdroidserver.common.apk_strip_signatures(unsigned, strip_manifest=True) + fdroidserver.common.apk_strip_v1_signatures(unsigned, strip_manifest=True) fdroidserver.common.sign_apk(unsigned, signed, config['keyalias']) self.assertTrue(os.path.isfile(signed)) self.assertFalse(os.path.isfile(unsigned)) self.assertTrue(fdroidserver.common.verify_apk_signature(signed)) - try: - fdroidserver.common.find_sdk_tools_cmd('aapt') - self.assertEqual(18, fdroidserver.common.get_minSdkVersion(signed)) - except fdroidserver.exception.FDroidException: - print('\n\nSKIPPING test_sign_apk min SDK check, aapt is not installed!\n') - return + self.assertEqual('18', fdroidserver.common._get_androguard_APK(signed).get_min_sdk_version()) + + def test_sign_apk_targetsdk_30(self): + fdroidserver.common.config = None + config = fdroidserver.common.read_config(fdroidserver.common.options) + config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') + config['keyalias'] = 'sova' + config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' + config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' + config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + + shutil.copy(os.path.join(self.basedir, 'minimal_targetsdk_30_unsigned.apk'), testdir) + unsigned = os.path.join(testdir, 'minimal_targetsdk_30_unsigned.apk') + signed = os.path.join(testdir, 'minimal_targetsdk_30.apk') + + self.assertFalse(fdroidserver.common.verify_apk_signature(unsigned)) + fdroidserver.common.sign_apk(unsigned, signed, config['keyalias']) + + self.assertTrue(os.path.isfile(signed)) + self.assertFalse(os.path.isfile(unsigned)) + self.assertTrue(fdroidserver.common.verify_apk_signature(signed)) + # verify it has a v2 signature + self.assertTrue(fdroidserver.common._get_androguard_APK(signed).is_signed_v2()) def test_get_apk_id(self): - config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -775,54 +790,40 @@ class CommonTest(unittest.TestCase): nc = fdroidserver.common.get_native_code(apkfilename) self.assertEqual(native_code, nc) - def test_get_minSdkVersion_androguard(self): - minSdkVersion = fdroidserver.common.get_minSdkVersion('bad-unicode-πÇÇ现代通用字-български-عربي1.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_1.apk') - self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_2.apk') - self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_3.apk') - self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_4.apk') - self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('org.dyndns.fules.ck_20.apk') - self.assertEqual(7, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip-badcert.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip-badsig.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip-release.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('urzip-release-unsigned.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/com.politedroid_3.apk') - self.assertEqual(3, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/com.politedroid_4.apk') - self.assertEqual(3, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/com.politedroid_5.apk') - self.assertEqual(3, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/com.politedroid_6.apk') - self.assertEqual(14, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.main.oldversion_1444412523.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.mainpatch.current_1619_another-release-key.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.mainpatch.current_1619.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.main.twoversions_1101613.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.main.twoversions_1101615.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/obb.main.twoversions_1101617.apk') - self.assertEqual(4, minSdkVersion) - minSdkVersion = fdroidserver.common.get_minSdkVersion('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk') - self.assertEqual(4, minSdkVersion) + def test_get_sdkversions_androguard(self): + """This is a sanity test that androguard isn't broken""" + def get_minSdkVersion(apkfile): + apk = fdroidserver.common._get_androguard_APK(apkfile) + return int(apk.get_min_sdk_version()) - with self.assertRaises(FDroidException): - fdroidserver.common.get_minSdkVersion('nope') + def get_targetSdkVersion(apkfile): + apk = fdroidserver.common._get_androguard_APK(apkfile) + return int(apk.get_target_sdk_version()) + + self.assertEqual(4, get_minSdkVersion('bad-unicode-πÇÇ现代通用字-български-عربي1.apk')) + self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_1.apk')) + self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_2.apk')) + self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_3.apk')) + self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_4.apk')) + self.assertEqual(7, get_minSdkVersion('org.dyndns.fules.ck_20.apk')) + self.assertEqual(4, get_minSdkVersion('urzip.apk')) + self.assertEqual(4, get_minSdkVersion('urzip-badcert.apk')) + self.assertEqual(4, get_minSdkVersion('urzip-badsig.apk')) + self.assertEqual(4, get_minSdkVersion('urzip-release.apk')) + self.assertEqual(4, get_minSdkVersion('urzip-release-unsigned.apk')) + self.assertEqual(3, get_minSdkVersion('repo/com.politedroid_3.apk')) + self.assertEqual(3, get_minSdkVersion('repo/com.politedroid_4.apk')) + self.assertEqual(3, get_minSdkVersion('repo/com.politedroid_5.apk')) + self.assertEqual(14, get_minSdkVersion('repo/com.politedroid_6.apk')) + self.assertEqual(4, get_minSdkVersion('repo/obb.main.oldversion_1444412523.apk')) + self.assertEqual(4, get_minSdkVersion('repo/obb.mainpatch.current_1619_another-release-key.apk')) + self.assertEqual(4, get_minSdkVersion('repo/obb.mainpatch.current_1619.apk')) + self.assertEqual(4, get_minSdkVersion('repo/obb.main.twoversions_1101613.apk')) + self.assertEqual(4, get_minSdkVersion('repo/obb.main.twoversions_1101615.apk')) + self.assertEqual(4, get_minSdkVersion('repo/obb.main.twoversions_1101617.apk')) + self.assertEqual(4, get_minSdkVersion('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk')) + + self.assertEqual(30, get_targetSdkVersion('minimal_targetsdk_30_unsigned.apk')) def test_apk_release_name(self): appid, vercode, sigfp = fdroidserver.common.apk_parse_release_filename('com.serwylo.lexica_905.apk') diff --git a/tests/minimal_targetsdk_30_unsigned.apk b/tests/minimal_targetsdk_30_unsigned.apk new file mode 100644 index 0000000000000000000000000000000000000000..c39aec6d18dc7410d8620b147a8a4f8e5006d86d GIT binary patch literal 2294 zcmWIWW@cdk0uB(tVE6Q8eHznsMyw4^(ep-`C9jLHZA4 zz2jZa*$+hiFg$-CzJuxf#k`C)`@WSP2#*S0G*RuB%lzcpHs7fS=N$0VoqNvkeFcBw zzq2(i#v6UyEeluazxkxPOIk`mb=IMtle+7ws`^(YEjk(d-{bbHm%M?!8ME^z-)UJj z<<`WXH=AaD>bc3^@p<<={n8_P>fghnZ6tpxmk6&iDtSJ&D)Er+W$S0NgJ$2X+n1cf zC0y1XHgWcM^=HBSd2z)l!Ty$p4qNl%y!>;L?B6b&>$7F``e$bgI<@~7r+s5j)-sy? z$@Ig#-(Sxjtx~LapPPMsPBq)E1g=YM#gY?VU$|(kAG(ElX|G`{bcnynm?{yI6So~V;TF~b6k60?OgGw_Tk3pPyTrf0l?T6 z0mdsNw#BEsgyWfsO#zHrtjH2e~ zCf7UHPEE^|TxwNpRc(7>_Qaq$Vs&3;@H-|31{+oe25z7ul5-M^i&KmBQc^2gr+DXI zb`WSt|Lbx4i=$N3q!l(zSB10YOludJ#g!qqpkqt#uScpOxo>k{UE8?WqPMBxlG4|v zE7IcsSnU}UTdE#5v{)3rn5g~8Az$I3#k~mvp@*(LpE-Bt-ML%S+|x_{|5&R1;o;|t zukY%wESHbpv;TvF#@@T~m%mk=tNm}O$~=W}!M++xjz25C8I&K~te)uHqHy=e$AvOZ zor)72H5Xk8ycTHbASuAmHqqFFXJ^+Pw`UVop9p^9s%)-t+NZ?wyiY;Ps4>PpZ35FL z0Zk>QC1**I&Z^@pH}Z33Vw9mW?bs-#mQ&xsiuydXn?6z|YsX3w|ra zS99#yEc8zOj^B@czP}avo69=8v?@Qo{dfPzouiHto*wtC=Kd>{=_z8)+*6@Gt z=cAXizCD}wfAepFLMK`F`%@AnuVxz<#A-Y#e);m~ojY&5^qBu$3DTP%8M!C?gpxqMn`c;?j&Yb&l@^0{reCh69azR4|{ zj~{uW(;d3w{~yDDl3`I#8F`$WD$DQh@LZczlULfDd9^;5`zqJF=`9oY#A+V9{-rDT zMd8_w?Wyxx3fhb7t~|WVW^L=KaQedbIdkI+{<~M{P0sC2Tb{nj;hnSoRg-5H=DtxS z3uaF{tu3Z&I6>-uT};4Nu@F<{U0P>St|UJAyp3h2+gV+<@@?CVJCApzO+VFk)1q=s z%4?sQAwO7BeIl3p`9!DRTDCc~Xv#^`EUO$JP06sHX}qaLNj@t#b~OhVUUMyt@l~0! zTtPsHvz)uBAgGI{{ZNyK(sIuo-es#5oo2m%*H@yjOH|3d<+=5xg)hQpbljS#(eBsk z^jt-VY0=`ZGsB(V#r|vyw0Bv5uYTbflkTbZt$l?Iv$o!zbatN7man24*KYT?@Jiok zOH~hlRBfA!?cKMgNh1I5aVx%B`~I7J=kXnu%-8Sk)^Oju_pY@jo6T?DE46pt-Sadr zJXHNa9+WqM=^qL>HgJ{c0J8-M^D(e76r~pDmlh=hGe%-jakA-6CI%J;CI%j`Jg~rK zU}TVC&;Zj=1Au}GP$r0CVoJ^gbD0zve*op`ft-AXB8GGZJ%%)f6d)^~ArnaJF(d=& zkpUDy0S5#DP#VMrg`)wO2Js+30mcB*Yz)N=CBV?iWXJ=C9Ynnjn1(6>nxz0`f+!A- z#DaqOyu{p8P#g$=%UO_hFe@3ELKrfje2`cK5IX=dr2taGgG+j5kXZrVjKGux0uUMW znjRttBeB%`AOj@8&W9L)UU|T@GBCUY`U6{4f^GtO$&WCh80b`_dH~^eh!WJifzZal a&;_hSP;*LvH!B-R1q%@V0MakmK|BC2q2Xcx literal 0 HcmV?d00001 From 74af61f255fc492fbdfe061e71084b86f58bcc28 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 9 Sep 2020 18:57:34 +0200 Subject: [PATCH 0452/2775] remove providerName from default smartcardoptions apksigner doesn't recognize the SunPKCS11-OpenSC set via providerName Neither jarsigner nor apksigner need this to work. --- examples/config.py | 2 +- fdroidserver/common.py | 45 +++++++++++++++++++++++++++++++----------- fdroidserver/init.py | 2 +- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/examples/config.py b/examples/config.py index f01a2548..5ece5631 100644 --- a/examples/config.py +++ b/examples/config.py @@ -135,7 +135,7 @@ The repository of older versions of applications from the main demo repository. # You should not need to change these at all, unless you have a very # customized setup for using smartcards in Java with keytool/jarsigner -# smartcardoptions = "-storetype PKCS11 -providerName SunPKCS11-OpenSC \ +# smartcardoptions = "-storetype PKCS11 \ # -providerClass sun.security.pkcs11.SunPKCS11 \ # -providerArg opensc-fdroid.cfg" diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 0e744c69..58f5f063 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -69,8 +69,10 @@ from .asynchronousfilereader import AsynchronousFileReader # The path to this fdroidserver distribution FDROID_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) -# We need 26.0.0 for aapt but that doesn't ship with apksigner, so take the next higher version -MINIMUM_BUILD_TOOLS_VERSION = '26.0.1' +# this is the build-tools version, aapt has a separate version that +# has to be manually set in test_aapt_version() +MINIMUM_AAPT_BUILD_TOOLS_VERSION = '26.0.0' +MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION = '26.0.1' VERCODE_OPERATION_RE = re.compile(r'^([ 0-9/*+-]|%c)+$') @@ -110,7 +112,7 @@ default_config = { 'r16b': None, }, 'cachedir': os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), - 'build_tools': MINIMUM_BUILD_TOOLS_VERSION, + 'build_tools': MINIMUM_AAPT_BUILD_TOOLS_VERSION, 'force_build_tools': False, 'java_paths': None, 'scan_binary': False, @@ -320,8 +322,7 @@ def read_config(opts, config_file='config.py'): config['smartcardoptions'] = re.sub(r'\s+', r' ', config['smartcardoptions']).split(' ') elif not smartcardoptions and 'keystore' in config and config['keystore'] == 'NONE': # keystore='NONE' means use smartcard, these are required defaults - config['smartcardoptions'] = ['-storetype', 'PKCS11', '-providerName', - 'SunPKCS11-OpenSC', '-providerClass', + config['smartcardoptions'] = ['-storetype', 'PKCS11', '-providerClass', 'sun.security.pkcs11.SunPKCS11', '-providerArg', 'opensc-fdroid.cfg'] @@ -415,6 +416,28 @@ def assert_config_keystore(config): + "you can create one using: fdroid update --create-key") +def find_apksigner(): + """ + Returns the best version of apksigner following this algorithm: + * use config['apksigner'] if set + * try to find apksigner in path + * find apksigner in build-tools starting from newest installed going down to MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION + :return: path to apksigner or None if no version is found + """ + if set_command_in_config('apksigner'): + return config['apksigner'] + build_tools_path = os.path.join(config['sdk_path'], 'build-tools') + for f in sorted(os.listdir(build_tools_path), reverse=True): + if LooseVersion(f) < LooseVersion(MINIMUM_AAPT_BUILD_TOOLS_VERSION): + return None + if os.path.exists(os.path.join(build_tools_path, f, 'apksigner')): + apksigner = os.path.join(build_tools_path, f, 'apksigner') + logging.info("Using %s " % apksigner) + # memoize result + config['apksigner'] = apksigner + return config['apksigner'] + + def find_sdk_tools_cmd(cmd): '''find a working path to a tool from the Android SDK''' @@ -465,13 +488,13 @@ def test_aapt_version(aapt): # the Debian package has the version string like "v0.2-23.0.2" too_old = False if '.' in bugfix: - if LooseVersion(bugfix) < LooseVersion(MINIMUM_BUILD_TOOLS_VERSION): + if LooseVersion(bugfix) < LooseVersion(MINIMUM_AAPT_BUILD_TOOLS_VERSION): too_old = True elif LooseVersion('.'.join((major, minor, bugfix))) < LooseVersion('0.2.4062713'): too_old = True if too_old: logging.warning(_("'{aapt}' is too old, fdroid requires build-tools-{version} or newer!") - .format(aapt=aapt, version=MINIMUM_BUILD_TOOLS_VERSION)) + .format(aapt=aapt, version=MINIMUM_AAPT_BUILD_TOOLS_VERSION)) else: logging.warning(_('Unknown version of aapt, might cause problems: ') + output) @@ -3042,15 +3065,14 @@ def sign_apk(unsigned_path, signed_path, keyalias): if int(apk.get_target_sdk_version()) >= 30: if config['keystore'] == 'NONE': replacements = {'-storetype': '--ks-type', - '-providerName': '--ks-provider-name', '-providerClass': '--ks-provider-class', '-providerArg': '--ks-provider-arg'} signing_args = [replacements.get(n, n) for n in config['smartcardoptions']] else: signing_args = ['--key-pass', 'env:FDROID_KEY_PASS'] - if not set_command_in_config('apksigner'): - config['apksigner'] = find_sdk_tools_cmd('apksigner') - cmd = [config['apksigner'], 'sign', + if not find_apksigner(): + raise BuildException(_("apksigner not found, it's required for signing!")) + cmd = [find_apksigner(), 'sign', '--ks', config['keystore'], '--ks-pass', 'env:FDROID_KEY_STORE_PASS'] cmd += signing_args @@ -3079,7 +3101,6 @@ def sign_apk(unsigned_path, signed_path, keyalias): cmd += signing_args cmd += signature_algorithm cmd += [unsigned_path, keyalias] - print(cmd) p = FDroidPopen(cmd, envs={ 'FDROID_KEY_STORE_PASS': config['keystorepass'], 'FDROID_KEY_PASS': config.get('keypass', "")}) diff --git a/fdroidserver/init.py b/fdroidserver/init.py index ff2f7075..20596130 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -194,7 +194,7 @@ def main(): common.write_to_config(test_config, 'repo_keyalias', '1') # seems to be the default disable_in_config('keypass', 'never used with smartcard') common.write_to_config(test_config, 'smartcardoptions', - ('-storetype PKCS11 -providerName SunPKCS11-OpenSC ' + ('-storetype PKCS11 ' + '-providerClass sun.security.pkcs11.SunPKCS11 ' + '-providerArg opensc-fdroid.cfg')) # find opensc-pkcs11.so From 145ba9db54a019cc9ef65a31925b923cec66d672 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 9 Sep 2020 22:51:08 +0200 Subject: [PATCH 0453/2775] fix apksigner smartcardoptions apksigner documents the options as --ks-provider-class and --ks-provider-arg those seem to be accepted but fail when actually making a signature with weird internal exceptions. The new options actually work. From: https://geoffreymetais.github.io/code/key-signing/#scripting --- fdroidserver/common.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 58f5f063..a589e8f8 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3064,9 +3064,14 @@ def sign_apk(unsigned_path, signed_path, keyalias): apk = _get_androguard_APK(unsigned_path) if int(apk.get_target_sdk_version()) >= 30: if config['keystore'] == 'NONE': + # NOTE: apksigner doesn't like -providerName/--provider-name at all, don't use + # apksigner documents the options as --ks-provider-class and --ks-provider-arg + # those seem to be accepted but fail when actually making a signature with + # weird internal exceptions. Those options actually work. + # From: https://geoffreymetais.github.io/code/key-signing/#scripting replacements = {'-storetype': '--ks-type', - '-providerClass': '--ks-provider-class', - '-providerArg': '--ks-provider-arg'} + '-providerClass': '--provider-class', + '-providerArg': '--provider-arg'} signing_args = [replacements.get(n, n) for n in config['smartcardoptions']] else: signing_args = ['--key-pass', 'env:FDROID_KEY_PASS'] From dfecdcc1bd25096672f6f77a83e894a8a8fcc9c0 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 13:19:13 +0200 Subject: [PATCH 0454/2775] set minimum apksigner version to 26.0.2 --- fdroidserver/common.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index a589e8f8..e6b10305 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -72,7 +72,9 @@ FDROID_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) # this is the build-tools version, aapt has a separate version that # has to be manually set in test_aapt_version() MINIMUM_AAPT_BUILD_TOOLS_VERSION = '26.0.0' -MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION = '26.0.1' +# 26.0.2 is the first version recognizing md5 based signatures as valid again +# (as does android, so we want that) +MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION = '26.0.2' VERCODE_OPERATION_RE = re.compile(r'^([ 0-9/*+-]|%c)+$') From 4cd96d4a9fa18a5446219e50bcb2252556a2e9f9 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 02:37:05 +0200 Subject: [PATCH 0455/2775] use yaml safeloader in tests Try to use CSafeLoader when possible because its significantly faster. Use the normal Safeloader otherwise. (This mirrors the non-test code behaviour) --- tests/metadata.TestCase | 9 +++++++-- tests/update.TestCase | 15 ++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 8ab502c4..418d3afe 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -18,6 +18,11 @@ import textwrap from collections import OrderedDict from unittest import mock +try: + from yaml import CSafeLoader as SafeLoader +except ImportError: + from yaml import SafeLoader + localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) print('localmodule: ' + localmodule) @@ -103,7 +108,7 @@ class MetadataTest(unittest.TestCase): def test_valid_funding_yml_regex(self): """Check the regex can find all the cases""" with open(os.path.join(self.basedir, 'funding-usernames.yaml')) as fp: - data = yaml.safe_load(fp) + data = yaml.load(fp, Loader=SafeLoader) for k, entries in data.items(): for entry in entries: @@ -135,7 +140,7 @@ class MetadataTest(unittest.TestCase): frommeta = dict(apps[appid]) self.assertTrue(appid in apps) with open(savepath, 'r') as f: - frompickle = yaml.load(f) + frompickle = yaml.load(f, Loader=SafeLoader) self.assertEqual(frommeta, frompickle) # comment above assert and uncomment below to update test # files when new metadata fields are added diff --git a/tests/update.TestCase b/tests/update.TestCase index eee01734..be9d2799 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -21,6 +21,11 @@ from binascii import unhexlify from distutils.version import LooseVersion from testcommon import TmpCwd +try: + from yaml import CSafeLoader as SafeLoader +except ImportError: + from yaml import SafeLoader + localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) print('localmodule: ' + localmodule) @@ -634,7 +639,7 @@ class UpdateTest(unittest.TestCase): # yaml.dump(apk, f, default_flow_style=False) with open(savepath, 'r') as f: - from_yaml = yaml.load(f) + from_yaml = yaml.load(f, Loader=SafeLoader) self.maxDiff = None self.assertEqual(apk, from_yaml) @@ -844,7 +849,7 @@ class UpdateTest(unittest.TestCase): self.assertEqual('Internet', app['Categories'][0]) break with open(testfile) as fp: - data = yaml.load(fp) + data = yaml.load(fp, Loader=SafeLoader) self.assertEqual('urzip', data['Name']) self.assertEqual('urzip', data['Summary']) @@ -943,7 +948,7 @@ class UpdateTest(unittest.TestCase): ''')) fdroidserver.update.create_metadata_from_template(apk) with open(os.path.join('metadata', 'rocks.janicerand.yml')) as f: - metadata_content = yaml.load(f) + metadata_content = yaml.load(f, Loader=SafeLoader) self.maxDiff = None self.assertDictEqual(metadata_content, {'ArchivePolicy': '', @@ -1050,7 +1055,7 @@ class UpdateTest(unittest.TestCase): apps = {app.id: app} with open(os.path.join('build', app.id, 'FUNDING.yml'), 'w') as fp: fp.write(line) - data = yaml.load(line) + data = yaml.load(line, Loader=SafeLoader) fdroidserver.update.insert_funding_yml_donation_links(apps) if 'liberapay' in data: self.assertEqual(data['liberapay'], app.get('Liberapay')) @@ -1080,7 +1085,7 @@ class UpdateTest(unittest.TestCase): def test_sanitize_funding_yml(self): with open(os.path.join(self.basedir, 'funding-usernames.yaml')) as fp: - data = yaml.safe_load(fp) + data = yaml.load(fp, Loader=SafeLoader) for k, entries in data.items(): for entry in entries: if k in 'custom': From 9bf0758f1939419cf1b801ecc633eef67660c004 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 02:37:30 +0200 Subject: [PATCH 0456/2775] make update.Testcase tests work standalone --- tests/update.TestCase | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/update.TestCase b/tests/update.TestCase index be9d2799..8f9da35e 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -212,6 +212,10 @@ class UpdateTest(unittest.TestCase): shutil.copytree(os.path.join(self.basedir, 'triple-t-2'), tmptestsdir) os.chdir(tmptestsdir) + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.update.config = config fdroidserver.update.options = fdroidserver.common.options apps = fdroidserver.metadata.read_metadata(xref=True) @@ -344,9 +348,10 @@ class UpdateTest(unittest.TestCase): def testScanApksAndObbs(self): os.chdir(os.path.join(localmodule, 'tests')) - if os.path.basename(os.getcwd()) != 'tests': - raise Exception('This test must be run in the "tests/" subdir') - + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') + shutil.copytree(os.path.join(self.basedir, 'metadata'), 'metadata') config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() @@ -401,9 +406,9 @@ class UpdateTest(unittest.TestCase): def test_apkcache_json(self): """test the migration from pickle to json""" os.chdir(os.path.join(localmodule, 'tests')) - if os.path.basename(os.getcwd()) != 'tests': - raise Exception('This test must be run in the "tests/" subdir') - + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + shutil.copytree(os.path.join(self.basedir,'repo'), 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() @@ -442,9 +447,6 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.config = config fdroidserver.update.config = config os.chdir(os.path.join(localmodule, 'tests')) - if os.path.basename(os.getcwd()) != 'tests': - raise Exception('This test must be run in the "tests/" subdir') - try: config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') except fdroidserver.exception.FDroidException: @@ -748,6 +750,7 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config fdroidserver.update.config = config + fdroidserver.update.options = fdroidserver.common.options fdroidserver.update.options.delete_unknown = False knownapks = fdroidserver.common.KnownApks() @@ -761,9 +764,10 @@ class UpdateTest(unittest.TestCase): def test_translate_per_build_anti_features(self): os.chdir(os.path.join(localmodule, 'tests')) - if os.path.basename(os.getcwd()) != 'tests': - raise Exception('This test must be run in the "tests/" subdir') - + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') + shutil.copytree(os.path.join(self.basedir, 'metadata'), 'metadata') config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() From e613b650984f1625d632828dff0d73bc1ea3230a Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 15:51:47 +0200 Subject: [PATCH 0457/2775] we need FullLoader for one test, we are dumping custom objects --- tests/update.TestCase | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/update.TestCase b/tests/update.TestCase index 8f9da35e..0f539296 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -26,6 +26,11 @@ try: except ImportError: from yaml import SafeLoader +try: + from yaml import CFullLoader as FullLoader +except ImportError: + from yaml import FullLoader + localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) print('localmodule: ' + localmodule) @@ -408,7 +413,7 @@ class UpdateTest(unittest.TestCase): os.chdir(os.path.join(localmodule, 'tests')) testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) os.chdir(testdir) - shutil.copytree(os.path.join(self.basedir,'repo'), 'repo') + shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() @@ -594,13 +599,10 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.update.config = config os.chdir(os.path.join(localmodule, 'tests')) - if os.path.basename(os.getcwd()) != 'tests': - raise Exception('This test must be run in the "tests/" subdir') config['ndk_paths'] = dict() fdroidserver.common.config = config fdroidserver.update.config = config - fdroidserver.update.options = type('', (), {})() fdroidserver.update.options.clean = True fdroidserver.update.options.rename_apks = False @@ -641,7 +643,7 @@ class UpdateTest(unittest.TestCase): # yaml.dump(apk, f, default_flow_style=False) with open(savepath, 'r') as f: - from_yaml = yaml.load(f, Loader=SafeLoader) + from_yaml = yaml.load(f, Loader=FullLoader) self.maxDiff = None self.assertEqual(apk, from_yaml) From 709f4c9b18a49f53b12f0250f120d42c9182fd1e Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 15:56:42 +0200 Subject: [PATCH 0458/2775] pickle -> yaml rename --- tests/metadata.TestCase | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 418d3afe..c48bdba2 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -140,8 +140,8 @@ class MetadataTest(unittest.TestCase): frommeta = dict(apps[appid]) self.assertTrue(appid in apps) with open(savepath, 'r') as f: - frompickle = yaml.load(f, Loader=SafeLoader) - self.assertEqual(frommeta, frompickle) + from_yaml = yaml.load(f, Loader=SafeLoader) + self.assertEqual(frommeta, from_yaml) # comment above assert and uncomment below to update test # files when new metadata fields are added # with open(savepath, 'w') as f: From 89f63b3e1c4d70afed5b5ec53390a9fe59873d92 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 17:10:43 +0200 Subject: [PATCH 0459/2775] tests: use yaml.Loader on older yaml versions --- tests/update.TestCase | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/update.TestCase b/tests/update.TestCase index 0f539296..25efe369 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -29,7 +29,13 @@ except ImportError: try: from yaml import CFullLoader as FullLoader except ImportError: - from yaml import FullLoader + try: + # FullLoader is available from PyYaml 5.1+, as we don't load user + # controlled data here, it's okay to fall back the unsafe older + # Loader + from yaml import FullLoader + except ImportError: + from yaml import Loader as FullLoader localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) From 2367461465d40647d6ffb24abcb33d1a494446bd Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 17:12:16 +0200 Subject: [PATCH 0460/2775] tests: debian: apksigner is required for the tests to run now We need to use a shell wrapper for apksigner though because docker and binfmt don't play well together --- .gitlab-ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0de8ffaf..ca0dca28 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -66,12 +66,17 @@ debian_testing: - apt-get install aapt androguard + apksigner fdroidserver git gnupg python3-defusedxml python3-setuptools zipalign + # Debian has apksigner depend on binfmt support which isn't very docker friendly + # We create a shell wrapper instead + - echo -e '#!/bin/sh\njava -jar /usr/lib/android-sdk/build-tools/debian/apksigner.jar "$@"' > /usr/local/bin/apksigner + - chmod +x /usr/local/bin/apksigner - python3 -c 'import fdroidserver' - python3 -c 'import androguard' - cd tests From f6b7572b10c7aae43e048e0b6fac8765cb3ee4b1 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 17:14:15 +0200 Subject: [PATCH 0461/2775] fix fedora test minimum build tools version is determined by apksigner now. --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ca0dca28..14807970 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -202,7 +202,7 @@ fedora_latest: - wget --no-verbose -O tools.zip https://dl.google.com/android/repository/tools_r25.2.5-linux.zip - unzip -q tools.zip - rm tools.zip - - export AAPT_VERSION=`sed -n "s,^MINIMUM_AAPT_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py` + - export BUILD_TOOLS_VERSION=`sed -n "s,^MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py` - export JAVA_HOME=/etc/alternatives/jre - export ANDROID_HOME=`pwd`/android-sdk - mkdir $ANDROID_HOME @@ -214,7 +214,7 @@ fedora_latest: - mkdir ~/.android - touch ~/.android/repositories.cfg - echo y | $ANDROID_HOME/tools/bin/sdkmanager "platform-tools" - - echo y | $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$AAPT_VERSION" + - echo y | $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$BUILD_TOOLS_VERSION" - chown -R testuser . - cd tests - su testuser --login --command From 7eb32feaa5876c9847ef3e87a8655e1cd387235a Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 17:26:50 +0200 Subject: [PATCH 0462/2775] skip new signing test when we can't find apksigner Also add some error handling to the find_apksigner() method. --- fdroidserver/common.py | 4 ++++ tests/common.TestCase | 2 ++ 2 files changed, 6 insertions(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index e6b10305..586867a6 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -429,7 +429,11 @@ def find_apksigner(): if set_command_in_config('apksigner'): return config['apksigner'] build_tools_path = os.path.join(config['sdk_path'], 'build-tools') + if not os.path.isdir(build_tools_path): + return None for f in sorted(os.listdir(build_tools_path), reverse=True): + if not os.path.isdir(os.path.join(build_tools_path, f)): + continue if LooseVersion(f) < LooseVersion(MINIMUM_AAPT_BUILD_TOOLS_VERSION): return None if os.path.exists(os.path.join(build_tools_path, f, 'apksigner')): diff --git a/tests/common.TestCase b/tests/common.TestCase index eb67836c..98815d5b 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -675,6 +675,8 @@ class CommonTest(unittest.TestCase): def test_sign_apk_targetsdk_30(self): fdroidserver.common.config = None config = fdroidserver.common.read_config(fdroidserver.common.options) + if not fdroidserver.common.find_apksigner(): + self.skipTest('SKIPPING as apksigner is not installed!') config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') config['keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' From b2f6483671cb4d115a90371d4a7129d2acbb2409 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Thu, 10 Sep 2020 18:38:06 +0200 Subject: [PATCH 0463/2775] use new find_apksigner in test_scan_apk --- tests/update.TestCase | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/update.TestCase b/tests/update.TestCase index 25efe369..4f9c3f3f 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -484,17 +484,16 @@ class UpdateTest(unittest.TestCase): print('USE_ANDROGUARD', use_androguard) - try: - apksigner = fdroidserver.common.find_sdk_tools_cmd('apksigner') - if use_androguard and apksigner: # v2 parsing needs both + apksigner = fdroidserver.common.find_apksigner() + if apksigner: + if use_androguard: # v2 parsing needs both config['apksigner'] = apksigner apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') self.assertIsNone(apk_info.get('maxSdkVersion')) self.assertEqual(apk_info.get('versionName'), 'v2-only') self.assertEqual(apk_info.get('versionCode'), 2) - except fdroidserver.exception.FDroidException: + else: print('WARNING: skipping v2-only test since apksigner cannot be found') - apk_info = fdroidserver.update.scan_apk('repo/v1.v2.sig_1020.apk') self.assertIsNone(apk_info.get('maxSdkVersion')) self.assertEqual(apk_info.get('versionName'), 'v1+2') From 7de601a5b511b91d28bdc9902aea000b3e812074 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 14 Sep 2020 11:05:14 +0200 Subject: [PATCH 0464/2775] fallback to minsdk when targetsdk isn't set Androguard already has a function always returning an int here, so let's use that. Also put in a guard against minsdk not being set. --- fdroidserver/common.py | 17 +++++++++-- tests/common.TestCase | 37 +++++++++++++++++++++-- tests/no_targetsdk_minsdk1_unsigned.apk | Bin 0 -> 2266 bytes tests/no_targetsdk_minsdk30_unsigned.apk | Bin 0 -> 2310 bytes 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 tests/no_targetsdk_minsdk1_unsigned.apk create mode 100644 tests/no_targetsdk_minsdk30_unsigned.apk diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 586867a6..2a59152a 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3047,6 +3047,19 @@ def apk_extract_signatures(apkpath, outdir, manifest=True): out_file.write(in_apk.read(f.filename)) +def get_min_sdk_version(apk): + """ + This wraps the androguard function to always return and int and fall back to 1 + if we can't get a valid minsdk version + :param apk: androguard apk object + :return: minsdk as int + """ + try: + return int(apk.get_min_sdk_version()) + except TypeError: + return 1 + + def sign_apk(unsigned_path, signed_path, keyalias): """Sign and zipalign an unsigned APK, then save to a new file, deleting the unsigned @@ -3068,7 +3081,7 @@ def sign_apk(unsigned_path, signed_path, keyalias): """ apk = _get_androguard_APK(unsigned_path) - if int(apk.get_target_sdk_version()) >= 30: + if apk.get_effective_target_sdk_version() >= 30: if config['keystore'] == 'NONE': # NOTE: apksigner doesn't like -providerName/--provider-name at all, don't use # apksigner documents the options as --ks-provider-class and --ks-provider-arg @@ -3098,7 +3111,7 @@ def sign_apk(unsigned_path, signed_path, keyalias): os.remove(unsigned_path) else: - if int(apk.get_min_sdk_version()) < 18: + if get_min_sdk_version(apk) < 18: signature_algorithm = ['-sigalg', 'SHA1withRSA', '-digestalg', 'SHA1'] else: signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256'] diff --git a/tests/common.TestCase b/tests/common.TestCase index 98815d5b..ca06de8b 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -697,6 +697,37 @@ class CommonTest(unittest.TestCase): # verify it has a v2 signature self.assertTrue(fdroidserver.common._get_androguard_APK(signed).is_signed_v2()) + def test_sign_no_targetsdk(self): + fdroidserver.common.config = None + config = fdroidserver.common.read_config(fdroidserver.common.options) + if not fdroidserver.common.find_apksigner(): + self.skipTest('SKIPPING as apksigner is not installed!') + config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') + config['keyalias'] = 'sova' + config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' + config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' + config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + + shutil.copy(os.path.join(self.basedir, 'no_targetsdk_minsdk30_unsigned.apk'), testdir) + unsigned = os.path.join(testdir, 'no_targetsdk_minsdk30_unsigned.apk') + signed = os.path.join(testdir, 'no_targetsdk_minsdk30_signed.apk') + + fdroidserver.common.sign_apk(unsigned, signed, config['keyalias']) + self.assertTrue(fdroidserver.common.verify_apk_signature(signed)) + self.assertTrue(fdroidserver.common._get_androguard_APK(signed).is_signed_v2()) + + shutil.copy(os.path.join(self.basedir, 'no_targetsdk_minsdk1_unsigned.apk'), testdir) + unsigned = os.path.join(testdir, 'no_targetsdk_minsdk1_unsigned.apk') + signed = os.path.join(testdir, 'no_targetsdk_minsdk1_signed.apk') + + self.assertFalse(fdroidserver.common.verify_apk_signature(unsigned)) + fdroidserver.common.sign_apk(unsigned, signed, config['keyalias']) + + self.assertTrue(os.path.isfile(signed)) + self.assertFalse(os.path.isfile(unsigned)) + self.assertTrue(fdroidserver.common.verify_apk_signature(signed)) + def test_get_apk_id(self): config = dict() fdroidserver.common.fill_config_defaults(config) @@ -796,11 +827,11 @@ class CommonTest(unittest.TestCase): """This is a sanity test that androguard isn't broken""" def get_minSdkVersion(apkfile): apk = fdroidserver.common._get_androguard_APK(apkfile) - return int(apk.get_min_sdk_version()) + return fdroidserver.common.get_min_sdk_version(apk) def get_targetSdkVersion(apkfile): apk = fdroidserver.common._get_androguard_APK(apkfile) - return int(apk.get_target_sdk_version()) + return apk.get_effective_target_sdk_version() self.assertEqual(4, get_minSdkVersion('bad-unicode-πÇÇ现代通用字-български-عربي1.apk')) self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_1.apk')) @@ -826,6 +857,8 @@ class CommonTest(unittest.TestCase): self.assertEqual(4, get_minSdkVersion('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk')) self.assertEqual(30, get_targetSdkVersion('minimal_targetsdk_30_unsigned.apk')) + self.assertEqual(1, get_targetSdkVersion('no_targetsdk_minsdk1_unsigned.apk')) + self.assertEqual(30, get_targetSdkVersion('no_targetsdk_minsdk30_unsigned.apk')) def test_apk_release_name(self): appid, vercode, sigfp = fdroidserver.common.apk_parse_release_filename('com.serwylo.lexica_905.apk') diff --git a/tests/no_targetsdk_minsdk1_unsigned.apk b/tests/no_targetsdk_minsdk1_unsigned.apk new file mode 100644 index 0000000000000000000000000000000000000000..225e52bca567fadcc3e4a32b3a7a57092bc27a87 GIT binary patch literal 2266 zcmWIWW@cdk0uB(tz{_Q@XCWg4g9%Vf7|3_bODW3FOz}<3%S=lxF43#V&6yfx?RVHg zWKQqr!hI@2tQ{PI${rmqjT(-NmN0ZmO-@KsEmOLE!Ku-L>G=bODk4hg6B^B;yB@Rf-&^Yk{Qnb_)h#eClh=*bf(y^lo+3x zl9Oky-}9?|)eE!yWw{I5`O0>jF1((sWB7dIsr0pnHReW!%niEwP*&{F&AGEBK8YA@ z@7J5(@KdogHjMR(uXgE{!|N_d8~$3ud&RPL@k$Y!c{!nit9JTD6uOF9FMg?UJ-F=4 z%B+oU`)+m>>D;}w>he*>bysuPxR-sJKkvtV!$?7m>9UjVDySdL}{hSA3Zh+OV~etuK7KoE``Ce zk!9zbhtEGZ@-R(La{d+g`5Je@Z-w}3jy;=&-l^a5`?1gWw?cn&S!b74<;S=G?*F)R z)KS9IXY>AV{w+}GB+Gt(N}}Y|Yy*Q>jVHw~ zUmm@4=Z%*h^S>)Wdh;VA_k^EtQrMb0qw3bSYdwp0IcAGI@iE(4!tKE~Wsl$4SsNvn zPfHEYyt-j+#kEU5w++`M-CEK&xn=Y5BTsa?LwEfDWB5-pEb1vEk8@LH`TZT9Ym;j7 zN}DsU*5`6x<$5>0W#XP#&12WUbmhJ%JlnB7bzVzBdvV>BhnLx`Z9NrEU)VlpZhXOi z_bR=~xxH!2(>FQ1bJo9V^31~AH>za8>}jX9#dHlPNZqfC3HT}&V#>Tr>rBd(#0Q_Z zvFvm^tIJltZM$*j@vgM#r`m2>RIW*R?K3mv2TQ6?uB9=)DpQs#2ncbOb2k+Pb@8+xYVuH8?zzLeY_+1(toQHw zN)&d9D!I2jx4yLSMc9mvTN5?f{aT%#s|YbITKsipxbwT%pKXEmF6-~rFFa$?J=MOo zuaIHZ*4vZL&Qsd*RdnOp?H(6i=^JgS>fw*7ZF8}``_?o`_`OSN!_RhO|p5}#zsvpRMvIQ{xLjlJIt}-29wg6#11~!JG)Z+Zo zqGVvkNGvK&HoeKjz{0@9zyp>C7Rn5a3^EKFU>a%wP*4HN1W`;($(dj-lLF%ppj;OGyu~e9t0@B7(kkhp_rir z7+RSOdBCuPsMi70P(?tq6rfBH#lewSP!OM&n41cU0|9V33$hMoB_mS^Lk5%&5{m$0 z2Oy>tKuUOUNzV*2E5Mr(n36yMB7^d xO+YXC5hjEKor+WsAlwd7f|@rF+87w}fRzYpP6_a4Wdo^T0m2_Z`V2dW2LRS`#+m>C literal 0 HcmV?d00001 diff --git a/tests/no_targetsdk_minsdk30_unsigned.apk b/tests/no_targetsdk_minsdk30_unsigned.apk new file mode 100644 index 0000000000000000000000000000000000000000..ae8e86b530d36c4fdfcdf6332f0dcf6a4c6eea9b GIT binary patch literal 2310 zcmWIWW@cdk0uB(tQ0cVu(pg3Zh7zEdFp%$vh$=LQPaJPqQ;yA|2IJm%5ixu3`BD)e3&QX6_HN ze;BmY?lM1r!2E+{Uz7KS-g56`*_RRPXDlsEmC9Q5{E6gC);B(uXC&ubxj0+(Swpq_ zv-2m6ZH)VKitNK3-+0(Q6VMD`{j2!dFuiHj@tr=wGYlv0f4=`O|Ef*PPQK?7dYkFq zA7L8t)^K~LZ@}3Le0vwm&d|I*qgFr6;(TTN@;6*b{##B@6}CTW?mYGJ?l)V6weOVf z7yQhV`|kJCo|V={+nsxGOJ{Nob>r!^>**e z_={8jTW+ps*X+8px`xB){L=DiSMU2fvSf+u&M?<<^CIoy-q)8T?thRwzw_&f*!6RH zU+1-Izpj<}Jnd`Vv8uH}>#y#a^yAOh;)CxeRBk;K-(A<+HD9bQ;`Z$Wrs8w{i=C1w zUBBeo?@hRsgZ*3~+9=KSU$gDb`lo)&4HJ)?QCbk&xi0{^q#x?Vb-z88I0T`4W$ zeE76T&x`f5#%C(=Gw~^V`{9y8fDAe1c(m?4KID z362kfay;y_?o~17y?>s~-&7uU=x@ty&imUl-#;(Bpq3gEa zzPw&o&?@cm_-HX_oKLH2=kn}Zv#bA|f9HH;V+B*qb>G`-?l$aO>7+Q{+h6zDv*%$& zk{|r_pMIJ-_2}GGk7zbm+VNC0+H`G}eD&V0LEvloNk-QJLr5_`3#MZtdUJ z8YTMO+fn6xi1({maiu=7SADkXeimu*v*?~4Yq$3Q5_Q%T$*O6akFtKVzw~)#PPU1; z>1@_d47*k?lU!GQdy%TRRp!!7NtZV<20gyr&3$Yy>*HCRvZ05KR%ADvzb*8{YU?(h z9osig_OuH#Ssr7!_SnhfRCn_!o~`}?Zc|HN9otgse7j`(sdYv>-E^-@gq~U^yI3@M zri_1&R_Wqbk7DMOna=A_pL{A&qwK%`DC>fY55{rtH zO>eR?fXi?u1|F~yU;)m+$RNX@0j8m500kAGOc2Gyl$;6XGAS_r0Ls+^Ir$7l4CxGd z3~3B0Kvq6OCXm)+NCwg)11Nw34hRCEG>8ofM*}bo;z57{i~*$C7>XH6fT5MikOvGq zh~4{TKlx(VndKf;7& qpi`0R0fgHjN>H;0LK_3abYLZdnppz8S=m4;Sb*>ckp96A;sF5CbK-#j literal 0 HcmV?d00001 From 36e5fec418ac823dd4ed6cc780c2a8f1570e4275 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 14 Sep 2020 16:22:09 +0200 Subject: [PATCH 0465/2775] remove unused latestapps.dat code latestapps.dat was being used for the old-website, it's not used anymore Fixes the following crash in production: ``` 2020-09-13 19:26:59,000 CRITICAL: Unknown exception found! Traceback (most recent call last): File "/home/fbuild/fdroidserver/fdroid", line 22, in fdroidserver.__main__.main() File "/home/fbuild/fdroidserver/fdroidserver/__main__.py", line 230, in main raise e File "/home/fbuild/fdroidserver/fdroidserver/__main__.py", line 211, in main mod.main() File "/home/fbuild/fdroidserver/fdroidserver/update.py", line 2451, in main app = apps[appid] KeyError: '45b464b398a7d9fac5a186bd3d3d8dc1e6a25f7f9cd48c7462619b1e5fba87c2' ``` --- fdroidserver/update.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 1ddbd8e8..5936e502 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -2438,21 +2438,6 @@ def main(): # Update known apks info... knownapks.writeifchanged() - # Generate latest apps data for widget - if os.path.exists(os.path.join('stats', 'latestapps.txt')): - data = '' - with open(os.path.join('stats', 'latestapps.txt'), 'r') as f: - for line in f: - appid = line.rstrip() - data += appid + "\t" - app = apps[appid] - data += app.Name + "\t" - if app.icon is not None: - data += app.icon + "\t" - data += app.License + "\n" - with open(os.path.join(repodirs[0], 'latestapps.dat'), 'w') as f: - f.write(data) - if cachechanged: write_cache(apkcache) From de9e0f4fc33dddb61782e03a99591abf415f4d06 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Wed, 16 Sep 2020 15:58:50 +0300 Subject: [PATCH 0466/2775] build-tools 30.0.2 --- makebuildserver | 2 ++ 1 file changed, 2 insertions(+) diff --git a/makebuildserver b/makebuildserver index 909d9301..56ea7b2e 100755 --- a/makebuildserver +++ b/makebuildserver @@ -275,6 +275,8 @@ CACHE_FILES = [ 'ed3b7f9b2d15e90a12c2e739adb749d7d834e2f953e677380206bd14db135c6c'), ('https://dl.google.com/android/repository/build-tools_r30.0.1-linux.zip', '560eace2cc6ca16011fbb97c92c39aa0441d54dbfc13837dfbdb4a6bdf9c9da8'), + ('https://dl.google.com/android/repository/build-tools_r30.0.2-linux.zip', + '565af786dc0cc1941002174fb945122eabd080b222cd4c7c3d9a2ae0fabf5dc4'), ('https://services.gradle.org/distributions/gradle-2.2.1-bin.zip', '420aa50738299327b611c10b8304b749e8d3a579407ee9e755b15921d95ff418'), ('https://services.gradle.org/distributions/gradle-2.3-bin.zip', From 301ca0a949d46db7ec4ba0750bd60580b82c1393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 16 Sep 2020 15:25:10 +0200 Subject: [PATCH 0467/2775] refactor metadata.warn_or_exception to private func --- fdroidserver/metadata.py | 82 ++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index eb771646..d93d8b91 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -45,7 +45,7 @@ warnings_action = None VALID_USERNAME_REGEX = re.compile(r'^[a-z\d](?:[a-z\d/._-]){0,38}$', re.IGNORECASE) -def warn_or_exception(value, cause=None): +def _warn_or_exception(value, cause=None): '''output warning or Exception depending on -W''' if warnings_action == 'ignore': pass @@ -396,8 +396,8 @@ class FieldValidator(): values = [v] for v in values: if not self.compiled.match(v): - warn_or_exception(_("'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}") - .format(value=v, field=self.name, appid=appid, pattern=self.matching)) + _warn_or_exception(_("'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}") + .format(value=v, field=self.name, appid=appid, pattern=self.matching)) # Generic value types @@ -562,7 +562,7 @@ class DescriptionFormatter: if txt.startswith("[["): index = txt.find("]]") if index == -1: - warn_or_exception(_("Unterminated ]]")) + _warn_or_exception(_("Unterminated ]]")) url = txt[2:index] if self.linkResolver: url, urltext = self.linkResolver.resolve_description_link(url) @@ -574,7 +574,7 @@ class DescriptionFormatter: else: index = txt.find("]") if index == -1: - warn_or_exception(_("Unterminated ]")) + _warn_or_exception(_("Unterminated ]")) url = txt[1:index] index2 = url.find(' ') if index2 == -1: @@ -583,7 +583,7 @@ class DescriptionFormatter: urltxt = url[index2 + 1:] url = url[:index2] if url == urltxt: - warn_or_exception(_("URL title is just the URL, use brackets: [URL]")) + _warn_or_exception(_("URL title is just the URL, use brackets: [URL]")) res_html += '' + html.escape(urltxt, quote=False) + '' res_plain += urltxt if urltxt != url: @@ -665,9 +665,9 @@ def parse_yaml_srclib(metadatapath): 'Prepare': None} if not os.path.exists(metadatapath): - warn_or_exception(_("Invalid scrlib metadata: '{file}' " - "does not exist" - .format(file=metadatapath))) + _warn_or_exception(_("Invalid scrlib metadata: '{file}' " + "does not exist" + .format(file=metadatapath))) return thisinfo with open(metadatapath, "r", encoding="utf-8") as f: @@ -677,19 +677,19 @@ def parse_yaml_srclib(metadatapath): raise yaml.error.YAMLError(_('{file} is blank or corrupt!') .format(file=metadatapath)) except yaml.error.YAMLError as e: - warn_or_exception(_("Invalid srclib metadata: could not " - "parse '{file}'") - .format(file=metadatapath) + '\n' - + fdroidserver.common.run_yamllint(metadatapath, - indent=4), - cause=e) + _warn_or_exception(_("Invalid srclib metadata: could not " + "parse '{file}'") + .format(file=metadatapath) + '\n' + + fdroidserver.common.run_yamllint(metadatapath, + indent=4), + cause=e) return thisinfo for key in data.keys(): if key not in thisinfo.keys(): - warn_or_exception(_("Invalid srclib metadata: unknown key " - "'{key}' in '{file}'") - .format(key=key, file=metadatapath)) + _warn_or_exception(_("Invalid srclib metadata: unknown key " + "'{key}' in '{file}'") + .format(key=key, file=metadatapath)) return thisinfo else: if key == 'Subdir': @@ -771,11 +771,11 @@ def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): for metadatapath in metadatafiles: appid, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath)) if appid != '.fdroid' and not fdroidserver.common.is_valid_package_name(appid): - warn_or_exception(_("{appid} from {path} is not a valid Java Package Name!") - .format(appid=appid, path=metadatapath)) + _warn_or_exception(_("{appid} from {path} is not a valid Java Package Name!") + .format(appid=appid, path=metadatapath)) if appid in apps: - warn_or_exception(_("Found multiple metadata files for {appid}") - .format(appid=appid)) + _warn_or_exception(_("Found multiple metadata files for {appid}") + .format(appid=appid)) app = parse_metadata(metadatapath, appid in check_vcs, refresh) check_metadata(app) apps[app.id] = app @@ -787,8 +787,8 @@ def read_metadata(xref=True, check_vcs=[], refresh=True, sort_by_time=False): try: description_html(app.Description, DummyDescriptionResolver(apps)) except MetaDataException as e: - warn_or_exception(_("Problem with description of {appid}: {error}") - .format(appid=appid, error=str(e))) + _warn_or_exception(_("Problem with description of {appid}: {error}") + .format(appid=appid, error=str(e))) return apps @@ -921,7 +921,7 @@ def _decode_bool(s): return True if bool_false.match(s): return False - warn_or_exception(_("Invalid boolean '%s'") % s) + _warn_or_exception(_("Invalid boolean '%s'") % s) def parse_metadata(metadatapath, check_vcs=False, refresh=True): @@ -939,8 +939,8 @@ def parse_metadata(metadatapath, check_vcs=False, refresh=True): with open(metadatapath, 'r') as mf: parse_yaml_metadata(mf, app) else: - warn_or_exception(_('Unknown metadata format: {path} (use: *.yml)') - .format(path=metadatapath)) + _warn_or_exception(_('Unknown metadata format: {path} (use: *.yml)') + .format(path=metadatapath)) if check_vcs and app.Repo: build_dir = fdroidserver.common.get_build_dir(app) @@ -976,11 +976,11 @@ def parse_yaml_metadata(mf, app): try: yamldata = yaml.load(mf, Loader=SafeLoader) except yaml.YAMLError as e: - warn_or_exception(_("could not parse '{path}'") - .format(path=mf.name) + '\n' - + fdroidserver.common.run_yamllint(mf.name, - indent=4), - cause=e) + _warn_or_exception(_("could not parse '{path}'") + .format(path=mf.name) + '\n' + + fdroidserver.common.run_yamllint(mf.name, + indent=4), + cause=e) deprecated_in_yaml = ['Provides'] @@ -988,10 +988,10 @@ def parse_yaml_metadata(mf, app): for field in yamldata: if field not in yaml_app_fields: if field not in deprecated_in_yaml: - warn_or_exception(_("Unrecognised app field " - "'{fieldname}' in '{path}'") - .format(fieldname=field, - path=mf.name)) + _warn_or_exception(_("Unrecognised app field " + "'{fieldname}' in '{path}'") + .format(fieldname=field, + path=mf.name)) for deprecated_field in deprecated_in_yaml: if deprecated_field in yamldata: @@ -1010,7 +1010,7 @@ def parse_yaml_metadata(mf, app): build_flag_set.add(build_flag) for build_flag in build_flag_set: if build_flag not in build_flags: - warn_or_exception( + _warn_or_exception( _("Unrecognised build flag '{build_flag}' " "in '{path}'").format(build_flag=build_flag, path=mf.name)) @@ -1036,8 +1036,8 @@ def post_parse_yaml_metadata(yamldata): elif _flagtype is TYPE_INT: # versionCode must be int if not isinstance(build[flag], int): - warn_or_exception(_('{build_flag} must be an integer, found: {value}') - .format(build_flag=flag, value=build[flag])) + _warn_or_exception(_('{build_flag} must be an integer, found: {value}') + .format(build_flag=flag, value=build[flag])) def write_yaml(mf, app): @@ -1172,7 +1172,7 @@ def write_metadata(metadatapath, app): else: raise FDroidException(_('ruamel.yaml not installed, can not write metadata.')) - warn_or_exception(_('Unknown metadata format: %s') % metadatapath) + _warn_or_exception(_('Unknown metadata format: %s') % metadatapath) def add_metadata_arguments(parser): @@ -1196,4 +1196,4 @@ class DummyDescriptionResolver(DescriptionResolver): def resolve_description_link(self, appid): if appid in self.apps: return "fdroid.app:" + appid, "Dummy name - don't know yet" - warn_or_exception(_("Cannot resolve app id {appid}").format(appid=appid)) + _warn_or_exception(_("Cannot resolve app id {appid}").format(appid=appid)) From 94cd2a960cb13936375bee89eb39f09a31f59bda Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 11 Sep 2020 13:28:43 +0200 Subject: [PATCH 0468/2775] add script used to rsync repo to primary mirrors --- examples/mirror-to-mirror.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 examples/mirror-to-mirror.sh diff --git a/examples/mirror-to-mirror.sh b/examples/mirror-to-mirror.sh new file mode 100644 index 00000000..de85d9ca --- /dev/null +++ b/examples/mirror-to-mirror.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +( +flock -n 200 +set -e +cd /home/fdroid +rsync --delay-updates --progress -a --delete /home/fdroid/public_html/archive/ fdroid@fdroid-mirror.at.or.at:/srv/fdroid-mirror.at.or.at/htdocs/fdroid/archive/ +rsync --delay-updates --progress -a --delete /home/fdroid/public_html/repo/ fdroid@fdroid-mirror.at.or.at:/srv/fdroid-mirror.at.or.at/htdocs/fdroid/repo/ +) 200>/var/lock/root_fdroidmirrortomirror From 8b406ace08df356bd5af798d5f575068d2941583 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 11 Sep 2020 13:47:13 +0200 Subject: [PATCH 0469/2775] mirror-to-mirror.sh: update script to handle multiple primary mirrors --- examples/mirror-to-mirror.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/examples/mirror-to-mirror.sh b/examples/mirror-to-mirror.sh index de85d9ca..fa7e88b5 100644 --- a/examples/mirror-to-mirror.sh +++ b/examples/mirror-to-mirror.sh @@ -1,9 +1,24 @@ #!/bin/bash +# +# This script syncs the entire repo to the primary mirrors. It is +# meant to run in a cronjob quite frequently, as often as there are +# files to send. +# +# This script expects the receiving side to have the following +# preceeding the ssh key entry in ~/.ssh/authorized_keys: +# command="rsync --server -logDtpre.iLsfx --log-format=X --delete --delay-updates . /path/to/htdocs/fdroid/",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty +# set -e ( flock -n 200 set -e cd /home/fdroid -rsync --delay-updates --progress -a --delete /home/fdroid/public_html/archive/ fdroid@fdroid-mirror.at.or.at:/srv/fdroid-mirror.at.or.at/htdocs/fdroid/archive/ -rsync --delay-updates --progress -a --delete /home/fdroid/public_html/repo/ fdroid@fdroid-mirror.at.or.at:/srv/fdroid-mirror.at.or.at/htdocs/fdroid/repo/ +for section in repo archive; do + for host in fdroid@mirror.f-droid.org; do + # be super careful with the trailing slashes here! if one is wrong, it'll delete the entire section! + rsync --archive --delay-updates --progress --delete \ + /home/fdroid/public_html/${section} \ + ${host}:/srv/fdroid-mirror.at.or.at/htdocs/fdroid/ + done +done ) 200>/var/lock/root_fdroidmirrortomirror From df6cf52009eeef257374423626ad076b7b971651 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 16 Sep 2020 15:55:21 +0200 Subject: [PATCH 0470/2775] remove last vestige of latestapps.dat --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index d0955dac..c192310b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ README.rst # files generated by tests tmp/ /tests/repo/icons* -/tests/repo/latestapps.dat /tests/repo/status # files used in manual testing From 08f724651e9707ef3d943379276adbd6fd4f5a73 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 16 Sep 2020 15:58:32 +0200 Subject: [PATCH 0471/2775] remove "force_build_tools" config option, closes #738 The `force_build_tools` config option was added a long time ago to brute force the _build-tools_ version by trying to replace the value in `build.gradle` files. This is never something that should be used in production, since the app's build metadata should specify this kind of thing. And now that we're moving towards _androguard_ for everything except fdroid build and fdroid publish, _build-tools_ will no longer even be used in the other commands. --- examples/config.py | 4 ---- fdroidserver/build.py | 5 ----- fdroidserver/common.py | 1 - tests/build.TestCase | 17 ----------------- tests/run-tests | 2 -- 5 files changed, 29 deletions(-) diff --git a/examples/config.py b/examples/config.py index 5ece5631..7b43976c 100644 --- a/examples/config.py +++ b/examples/config.py @@ -36,10 +36,6 @@ # Build tools version to be used # build_tools = "28.0.3" -# Force all build to use the above version of build -tools, good for testing -# builds without having all of the possible build-tools installed. -# force_build_tools = True - # Command or path to binary for running Ant # ant = "ant" diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 31ef0d0c..b3d4cd54 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -442,11 +442,6 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext gradletasks += ['assemble' + flavours_cmd + 'Release'] - if config['force_build_tools']: - force_gradle_build_tools(build_dir, config['build_tools']) - for name, number, libpath in srclibpaths: - force_gradle_build_tools(libpath, config['build_tools']) - cmd = [config['gradle']] if build.gradleprops: cmd += ['-P' + kv for kv in build.gradleprops] diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 2a59152a..daa652b9 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -115,7 +115,6 @@ default_config = { }, 'cachedir': os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), 'build_tools': MINIMUM_AAPT_BUILD_TOOLS_VERSION, - 'force_build_tools': False, 'java_paths': None, 'scan_binary': False, 'ant': "ant", diff --git a/tests/build.TestCase b/tests/build.TestCase index 25655229..decae7ab 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -6,7 +6,6 @@ import inspect import logging import optparse import os -import re import shutil import sys import tempfile @@ -59,22 +58,6 @@ class BuildTest(unittest.TestCase): os.makedirs(self.tmpdir) os.chdir(self.basedir) - def test_force_gradle_build_tools(self): - testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) - shutil.copytree(os.path.join('source-files'), - os.path.join(testdir, 'source-files')) - teststring = 'FAKE_VERSION_FOR_TESTING' - fdroidserver.build.force_gradle_build_tools(testdir, teststring) - pattern = re.compile(r"buildToolsVersion[\s=]+'%s'\s+" % teststring) - for p in ('source-files/fdroid/fdroidclient/build.gradle', - 'source-files/Zillode/syncthing-silk/build.gradle', - 'source-files/open-keychain/open-keychain/build.gradle', - 'source-files/osmandapp/osmand/build.gradle', - 'source-files/open-keychain/open-keychain/OpenKeychain/build.gradle'): - with open(os.path.join(testdir, p), 'r') as f: - filedata = f.read() - self.assertIsNotNone(pattern.search(filedata)) - def test_get_apk_metadata(self): config = dict() fdroidserver.common.fill_config_defaults(config) diff --git a/tests/run-tests b/tests/run-tests index 551c5f55..dc4e934f 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -212,8 +212,6 @@ git clean -fdx # stick with known working commit, in case future commits break things for this code git reset --hard fea54e1161d5eb9eb1a54e26253ef84d3ab63705 if [ -d $ANDROID_HOME/platforms/android-23 && -d $ANDROID_HOME/build-tools/23.0.3 ]; then - echo "build_tools = '`ls -1 $ANDROID_HOME/build-tools/ | sort -n | tail -1`'" > config.py - echo "force_build_tools = True" >> config.py $fdroid build --verbose org.fdroid.ci.test.app:300 else echo 'WARNING: Skipping "fdroid build" test since android-23 is missing!' From 75c4be2ea953192b06121b72cabe16936f286127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 16 Sep 2020 18:26:16 +0200 Subject: [PATCH 0472/2775] expose public api in fdroidserver module --- fdroidserver/__init__.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/fdroidserver/__init__.py b/fdroidserver/__init__.py index bad9cefa..3a395ea2 100644 --- a/fdroidserver/__init__.py +++ b/fdroidserver/__init__.py @@ -21,3 +21,36 @@ for rootpath in rootpaths: gettext.bindtextdomain('fdroidserver', localedir) gettext.textdomain('fdroidserver') _ = gettext.gettext + + +from fdroidserver.exception import (FDroidException, + MetaDataException, + VerificationException) # NOQA: E402 +FDroidException # NOQA: B101 +MetaDataException # NOQA: B101 +VerificationException # NOQA: B101 + +from fdroidserver.common import (verify_apk_signature, + genkeystore as generate_keystore) # NOQA: E402 +verify_apk_signature # NOQA: B101 +generate_keystore # NOQA: B101 +from fdroidserver.index import (download_repo_index, + get_mirror_service_urls, + make as make_index) # NOQA: E402 +download_repo_index # NOQA: B101 +get_mirror_service_urls # NOQA: B101 +make_index # NOQA: B101 +from fdroidserver.update import (process_apk, + process_apks, + scan_apk, + scan_repo_files) # NOQA: E402 +process_apk # NOQA: B101 +process_apks # NOQA: B101 +scan_apk # NOQA: B101 +scan_repo_files # NOQA: B101 +from fdroidserver.server import (update_awsbucket, + update_servergitmirrors, + update_serverwebroot) # NOQA: E402 +update_awsbucket # NOQA: B101 +update_servergitmirrors # NOQA: B101 +update_serverwebroot # NOQA: B101 From 59018a887bca889e53855973f9804b1c41fcad28 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 16 Sep 2020 18:18:06 +0200 Subject: [PATCH 0473/2775] gitlab-ci: ensure android-23 is present for `fdroid build` test This test builds https://gitlab.com/fdroid/ci-test-app, which uses android-23 --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 14807970..40b87667 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,6 +7,8 @@ test: image: registry.gitlab.com/fdroid/ci-images-server:latest script: - $pip install -e .[test] + # the `fdroid build` test in tests/run-tests needs android-23 + - echo y | $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-23" - cd tests - ./complete-ci-tests From af4a2ab7361371e02863672f57b7b1d88fa56b55 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 6 Aug 2020 15:44:37 +0200 Subject: [PATCH 0474/2775] gitlab-ci: speed up test runs that do not need git history GIT_DEPTH sets how many commits of history to clone in CI Jobs. gitlab.com defaults to 50 with a max of 1000. The metadata_v0 job is the only job that needs history, and it needs more than 50. So this sets the default to 1, then metadata_v0 to 1000. https://docs.gitlab.com/ee/ci/pipelines/settings.html#git-shallow-clone --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 40b87667..148885d2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,8 @@ variables: pip: pip3 --timeout 100 --retries 10 +# speed up git checkout phase + GIT_DEPTH: 1 test: @@ -22,6 +24,7 @@ test: metadata_v0: image: registry.gitlab.com/fdroid/ci-images-server:latest variables: + GIT_DEPTH: 1000 RELEASE_COMMIT_ID: 37f37ebd88e79ebe93239b72ed5503d5bde13f4b # 2.0a~ script: - git fetch https://gitlab.com/fdroid/fdroidserver.git $RELEASE_COMMIT_ID From ad6985cb4041de5192edcd8a14e4cdd7c084572b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 20 Aug 2020 14:38:42 +0200 Subject: [PATCH 0475/2775] update: allow --nosign to work with only repo_pubkey set repo_pubkey is required for `fdroid update --nosign`, but repo_keyalias is not. For regular signing, the opposite true. --- fdroidserver/index.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 7e76f299..6d247141 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -566,7 +566,8 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing with open(os.path.join(repodir, 'index.xml'), 'wb') as f: f.write(output) - if 'repo_keyalias' in common.config: + if 'repo_keyalias' in common.config \ + or (common.options.nosign and 'repo_pubkey' in common.config): if common.options.nosign: logging.info(_("Creating unsigned index in preparation for signing")) From 8c1cf724e1e4a550939a635e5a4bb70ddfbe7d5b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 9 Sep 2020 19:01:53 +0200 Subject: [PATCH 0476/2775] init: force keystore to PKCS12 format Java 8 supports PKCS12, Java 9+ uses PKCS12 by default, which should have a .p12 file extension. `fdroid init` has always just added .jks which is the old default format. * https://docs.oracle.com/en/java/javase/12/tools/keytool.html#GUID-5990A2E4-78E3-47B7-AE75-6D1826259549__GUID-A8B9E662-C1C2-4A0E-9307-A8464F0E95D4 * https://openjdk.java.net/jeps/229 --- fdroidserver/common.py | 3 ++- tests/publish.TestCase | 4 ++-- tests/rewritemeta.TestCase | 10 ---------- tests/run-tests | 20 ++++++++++---------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index daa652b9..9b8f59cf 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -134,7 +134,7 @@ default_config = { 'stats_to_carbon': False, 'repo_maxage': 0, 'build_server_always': False, - 'keystore': 'keystore.jks', + 'keystore': 'keystore.p12', 'smartcardoptions': [], 'char_limits': { 'author': 256, @@ -3425,6 +3425,7 @@ def genkeystore(localconfig): '-keyalg', 'RSA', '-keysize', '4096', '-sigalg', 'SHA256withRSA', '-validity', '10000', + '-storetype', 'pkcs12', '-storepass:env', 'FDROID_KEY_STORE_PASS', '-dname', localconfig['keydname'], '-J-Duser.language=en'] diff --git a/tests/publish.TestCase b/tests/publish.TestCase index 38691f85..d0d08376 100755 --- a/tests/publish.TestCase +++ b/tests/publish.TestCase @@ -3,10 +3,10 @@ # # command which created the keystore used in this test case: # -# $ for ALIAS in 'repokey a163ec9b d2d51ff2 dc3b169e 78688a0f'; \ +# $ for ALIAS in repokey a163ec9b d2d51ff2 dc3b169e 78688a0f; \ # do keytool -genkey -keystore dummy-keystore.jks \ # -alias $ALIAS -keyalg 'RSA' -keysize '2048' \ -# -validity '10000' -storepass 123456 \ +# -validity '10000' -storepass 123456 -storetype jks \ # -keypass 123456 -dname 'CN=test, OU=F-Droid'; done # diff --git a/tests/rewritemeta.TestCase b/tests/rewritemeta.TestCase index 8a7d41e4..c4b34867 100755 --- a/tests/rewritemeta.TestCase +++ b/tests/rewritemeta.TestCase @@ -1,15 +1,5 @@ #!/usr/bin/env python3 -# -# command which created the keystore used in this test case: -# -# $ for ALIAS in 'repokey a163ec9b d2d51ff2 dc3b169e 78688a0f'; \ -# do keytool -genkey -keystore dummy-keystore.jks \ -# -alias $ALIAS -keyalg 'RSA' -keysize '2048' \ -# -validity '10000' -storepass 123456 \ -# -keypass 123456 -dname 'CN=test, OU=F-Droid'; done -# - import inspect import logging import optparse diff --git a/tests/run-tests b/tests/run-tests index dc4e934f..77d2734d 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -778,7 +778,7 @@ $fdroid server update --local-copy-dir=$LOCALCOPYDIR # check that --android-home fails when dir does not exist or is not a dir REPOROOT=`create_test_dir` -KEYSTORE=$REPOROOT/keystore.jks +KEYSTORE=$REPOROOT/keystore.p12 cd $REPOROOT set +e $fdroid init --keystore $KEYSTORE --android-home /opt/fakeandroidhome @@ -805,7 +805,7 @@ echo_header "check that fake android home passes 'fdroid init'" REPOROOT=`create_test_dir` FAKE_ANDROID_HOME=`create_test_dir` create_fake_android_home $FAKE_ANDROID_HOME -KEYSTORE=$REPOROOT/keystore.jks +KEYSTORE=$REPOROOT/keystore.p12 cd $REPOROOT $fdroid init --keystore $KEYSTORE --android-home $FAKE_ANDROID_HOME @@ -820,7 +820,7 @@ else FAKE_ANDROID_HOME=`create_test_dir` create_fake_android_home $FAKE_ANDROID_HOME rm -f $FAKE_ANDROID_HOME/build-tools/*/aapt - KEYSTORE=$REPOROOT/keystore.jks + KEYSTORE=$REPOROOT/keystore.p12 cd $REPOROOT set +e $fdroid init --keystore $KEYSTORE --android-home $FAKE_ANDROID_HOME @@ -835,7 +835,7 @@ echo_header "check that --android-home overrides ANDROID_HOME" REPOROOT=`create_test_dir` FAKE_ANDROID_HOME=`create_test_dir` create_fake_android_home $FAKE_ANDROID_HOME -KEYSTORE=$REPOROOT/keystore.jks +KEYSTORE=$REPOROOT/keystore.p12 cd $REPOROOT $fdroid init --keystore $KEYSTORE --android-home $FAKE_ANDROID_HOME set +e @@ -859,7 +859,7 @@ else echo_header "setup a new repo from scratch with keystore and android-home set on cmd line" REPOROOT=`create_test_dir` - KEYSTORE=$REPOROOT/keystore.jks + KEYSTORE=$REPOROOT/keystore.p12 FAKE_ANDROID_HOME=`create_test_dir` create_fake_android_home $FAKE_ANDROID_HOME STORED_ANDROID_HOME=$ANDROID_HOME @@ -916,7 +916,7 @@ grep -F ' Date: Thu, 1 Oct 2020 11:00:33 +0200 Subject: [PATCH 0482/2775] Translated using Weblate: Portuguese (Brazil) (pt_BR) by Wellington Terumi Uemura Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Wellington Terumi Uemura Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translation: F-Droid/F-Droid Server --- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 59 +++++++++++------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 87db04f1..b4c33c41 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. -# FIRST AUTHOR , YEAR. -# +# Wellington Terumi Uemura , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2018-12-04 21:09+0000\n" -"Last-Translator: Lunovox Heavenfinder \n" +"PO-Revision-Date: 2020-04-03 03:55+0000\n" +"Last-Translator: Wellington Terumi Uemura \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\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 3.4-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -151,7 +150,7 @@ msgstr "'{apkfilename}' já está instalado no {dev}." #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" -msgstr "" +msgstr "O '{field}' em {linedesc} é obsoleto, veja a documentação para conhecer os campos atuais:" #: ../fdroidserver/common.py #, python-brace-format @@ -478,7 +477,7 @@ msgstr "Criando índice não assinado em preparação para assinatura" #: ../fdroidserver/lint.py #, python-brace-format msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" -msgstr "" +msgstr "O CurrentVersionCode {cv} é menor que a entrada da versão mais antiga {versionCode}" #: ../fdroidserver/nightly.py msgid "DEBUG_KEYSTORE is not set or the value is incomplete" @@ -929,7 +928,7 @@ msgstr "Listar arquivos que devem ser reformatados" #: ../fdroidserver/lint.py msgid "Locale included in f-droid.org URL" -msgstr "" +msgstr "A localização foi incluída na URL f-droid.org" #: ../fdroidserver/build.py msgid "Make the build stop on exceptions" @@ -1086,7 +1085,7 @@ msgstr "Opções" #: ../fdroidserver/verify.py msgid "Output JSON report to file named after APK." -msgstr "" +msgstr "Exporte a saída do relatório JSON para um nome de arquivo após APK." #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1313,8 +1312,8 @@ msgstr "O scanner encontrou {count} problemas em {appid}: {versionCode}:" #: ../fdroidserver/build.py msgid "Scanner found {} problem" msgid_plural "Scanner found {} problems" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "O Scanner encontrou {} problema" +msgstr[1] "O Scanner encontrou {} problemas" #: ../fdroidserver/common.py msgid "Set clock to that time using:" @@ -1533,20 +1532,18 @@ msgid "Unnecessary trailing space" msgstr "Espaço desnecessário ao fim" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Unrecognised field '{field}' in {linedesc}" +#, python-brace-format msgid "Unrecognised app field '{fieldname}' in '{path}'" -msgstr "Campo '{field}' não reconhecido em {linedesc}" +msgstr "O campo '{fieldname}' não foi reconhecido em '{path}'" #: ../fdroidserver/metadata.py msgid "Unrecognised app field: " msgstr "Campo da app não reconhecido: " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Unrecognised field '{field}' in {linedesc}" +#, python-brace-format msgid "Unrecognised build flag '{build_flag}' in '{path}'" -msgstr "Campo '{field}' não reconhecido em {linedesc}" +msgstr "O sinalizador de construção '{build_flag}' desconhecido em '{path}'" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1807,8 +1804,8 @@ msgstr "complexo" #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "opção conflitante na string: %s" +msgstr[1] "opções conflitantes nas strings: %s" #: ../fdroidserver/nightly.py #, python-brace-format @@ -1841,8 +1838,8 @@ msgstr "dest = é necessário para opções como %r" #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "foi previsto %s argumento" +msgstr[1] "foi previsto %s argumentos" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2153,8 +2150,8 @@ msgstr "usando o Apache libcloud para sincronizar com {url}" #, python-brace-format msgid "{0} app, {1} key aliases" msgid_plural "{0} apps, {1} key aliases" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "{0} apl, {1} codinome de chave" +msgstr[1] "{0} apls, {1} codinome de chaves" #: ../fdroidserver/update.py #, python-brace-format @@ -2179,12 +2176,12 @@ msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Android Package Name!" -msgstr "" +msgstr "O {appid} do {path} não é um Nome de Pacote Android válido!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" -msgstr "" +msgstr "O {appid} do {path} não é um Nome de Pacote Java válido!" #: ../fdroidserver/mirror.py #, python-brace-format @@ -2205,12 +2202,12 @@ msgstr "{appid}: nehnuma compilação especificada, em execução no estado de o #: ../fdroidserver/lint.py #, python-brace-format msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" -msgstr "" +msgstr "O {appid}: {field} deve ser um '{type}', porém é um '{fieldtype}!'" #: ../fdroidserver/lint.py #, python-brace-format msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" -msgstr "" +msgstr "O {appid}: {field} deve ser um '{type}', porém é um '{fieldtype}'!" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2245,14 +2242,14 @@ msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "{} compilação falhou" +msgstr[1] "{} compilações falharam" #: ../fdroidserver/build.py msgid "{} build succeeded" msgid_plural "{} builds succeeded" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "{} compilação foi bem sucedida" +msgstr[1] "{} compilações foram bem sucedidas" #~ msgid "Interactively ask about things that need updating." #~ msgstr "Perguntar interativamente sobre elementos que precisam de atualização." From 92f5a3106df5742256d32d47262773a6ce268247 Mon Sep 17 00:00:00 2001 From: Golubev Alexander Date: Thu, 1 Oct 2020 11:00:34 +0200 Subject: [PATCH 0483/2775] Translated using Weblate: Russian (ru) by Golubev Alexander Currently translated at 98.1% (468 of 477 strings) Co-authored-by: Golubev Alexander Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 8f41e1d2..0b966d0a 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# +# Golubev Alexander , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2018-09-26 12:37+0000\n" -"Last-Translator: mesnevi \n" +"PO-Revision-Date: 2020-04-03 12:43+0000\n" +"Last-Translator: Golubev Alexander \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 3.2-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -152,7 +151,7 @@ msgstr "'{apkfilename}' уже установлен на {dev}." #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" -msgstr "" +msgstr "Поле '{field}' в {linedesc} устарело, смотрите список полей достпных на данный момент в документации:" #: ../fdroidserver/common.py #, python-brace-format From 18380eeff89edbb7b5f7a85ca9a2d3a3ae01386e Mon Sep 17 00:00:00 2001 From: Mingun Date: Thu, 1 Oct 2020 11:00:34 +0200 Subject: [PATCH 0484/2775] Translated using Weblate: Russian (ru) by Mingun Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Mingun Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 29 +++++++++++++-------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 0b966d0a..94330c69 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -1,13 +1,14 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. # Golubev Alexander , 2020. +# Mingun , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-03 12:43+0000\n" -"Last-Translator: Golubev Alexander \n" +"PO-Revision-Date: 2020-04-05 15:56+0000\n" +"Last-Translator: Mingun \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -479,7 +480,7 @@ msgstr "Создание неподписанного индекса (подго #: ../fdroidserver/lint.py #, python-brace-format msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" -msgstr "" +msgstr "CurrentVersionCode {cv} меньше значения старейшей сборки {versionCode}" #: ../fdroidserver/nightly.py msgid "DEBUG_KEYSTORE is not set or the value is incomplete" @@ -928,7 +929,7 @@ msgstr "Отобразить список файлов, формат котор #: ../fdroidserver/lint.py msgid "Locale included in f-droid.org URL" -msgstr "" +msgstr "В URL f-droid.org включена локаль" #: ../fdroidserver/build.py msgid "Make the build stop on exceptions" @@ -1085,7 +1086,7 @@ msgstr "Параметры" #: ../fdroidserver/verify.py msgid "Output JSON report to file named after APK." -msgstr "" +msgstr "Вывод отчёта в формате JSON под именем файла APK." #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1533,20 +1534,18 @@ msgid "Unnecessary trailing space" msgstr "Лишний пробел в конце строки" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Unrecognised field '{field}' in {linedesc}" +#, python-brace-format msgid "Unrecognised app field '{fieldname}' in '{path}'" -msgstr "Неизвестное поле '{field}' в '{linedesc}'" +msgstr "Неизвестное поле приложения '{fieldname}' в '{path}'" #: ../fdroidserver/metadata.py msgid "Unrecognised app field: " msgstr "Неизвестное поле в файле метаданных приложения: " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Unrecognised field '{field}' in {linedesc}" +#, python-brace-format msgid "Unrecognised build flag '{build_flag}' in '{path}'" -msgstr "Неизвестное поле '{field}' в '{linedesc}'" +msgstr "Неизвестный флаг сборки '{build_flag}' в '{path}'" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2182,12 +2181,12 @@ msgstr "У {appid} нет имени! Будет использовано имя #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Android Package Name!" -msgstr "" +msgstr "{appid} из {path} не годится в качестве имени Android Package!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" -msgstr "" +msgstr "{appid} из {path} не годится в качестве имени пакета Java!" #: ../fdroidserver/mirror.py #, python-brace-format @@ -2208,12 +2207,12 @@ msgstr "{appid}: ревизия сборки не указана, сборка #: ../fdroidserver/lint.py #, python-brace-format msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" -msgstr "" +msgstr "{appid}: {field} должно быть '{type}', а не '{fieldtype}'!" #: ../fdroidserver/lint.py #, python-brace-format msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" -msgstr "" +msgstr "{appid}: {field} должно быть '{type}', а не '{fieldtype}'!" #: ../fdroidserver/metadata.py #, python-brace-format From abc3d740e918da0f250c2dae1c7ffcdaadc4d90c Mon Sep 17 00:00:00 2001 From: anonymous Date: Thu, 1 Oct 2020 11:00:34 +0200 Subject: [PATCH 0485/2775] Translated using Weblate: Russian (ru) by anonymous Currently translated at 100.0% (477 of 477 strings) Co-authored-by: anonymous Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 94330c69..9f305d21 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -2,13 +2,14 @@ # This file is put in the public domain. # Golubev Alexander , 2020. # Mingun , 2020. +# anonymous , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" "PO-Revision-Date: 2020-04-05 15:56+0000\n" -"Last-Translator: Mingun \n" +"Last-Translator: anonymous \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -235,7 +236,7 @@ msgstr "В установленной Android SDK '{path}' нет '{dirname}'!" #: ../fdroidserver/common.py msgid "Android SDK not found!" -msgstr "Android SDK не обнаружена!" +msgstr "Android SDK не обнаружен!" #: ../fdroidserver/common.py #, python-brace-format From d0dc5644236bf2ffbae8aadcfb2cde1e50cecb64 Mon Sep 17 00:00:00 2001 From: Golubev Alexander Date: Thu, 1 Oct 2020 11:00:35 +0200 Subject: [PATCH 0486/2775] Translated using Weblate: Russian (ru) by Golubev Alexander Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Golubev Alexander Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 9f305d21..d6d5f205 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-05 15:56+0000\n" -"Last-Translator: anonymous \n" +"PO-Revision-Date: 2020-04-06 07:19+0000\n" +"Last-Translator: Golubev Alexander \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -2182,7 +2182,7 @@ msgstr "У {appid} нет имени! Будет использовано имя #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Android Package Name!" -msgstr "{appid} из {path} не годится в качестве имени Android Package!" +msgstr "{appid} из {path} не годится в качестве имени пакета Android!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format From 8322126c9f6e494bcea8739961e4501d8e281e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Thu, 1 Oct 2020 11:00:35 +0200 Subject: [PATCH 0487/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Turki?= =?UTF-8?q?sh=20(tr)=20by=20O=C4=9Fuz=20Ersen=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (477 of 477 strings) Translated using Weblate: Turkish (tr) by Oğuz Ersen Currently translated at 100.0% (477 of 477 strings) Translated using Weblate: Turkish (tr) by Oğuz Ersen Currently translated at 100.0% (477 of 477 strings) Translated using Weblate: Turkish (tr) by Oğuz Ersen Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Oğuz Ersen Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/tr/ Translation: F-Droid/F-Droid Server --- locale/tr/LC_MESSAGES/fdroidserver.po | 37 +++++++++++++-------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index 89355a2b..84a6af0c 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. -# FIRST AUTHOR , YEAR. -# +# Oğuz Ersen , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2019-01-31 13:32+0000\n" -"Last-Translator: Mesut Akcan \n" +"PO-Revision-Date: 2020-07-20 20:29+0000\n" +"Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" "Language: tr\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 3.5-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -57,7 +56,7 @@ msgstr "\"{path}\" var ancak s3cmd kurulu değil!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" -msgstr "\"{path}\" kabul edilebilir bir tür değil, şuna dönüştürün: {formats}" +msgstr "\"{path}\" kabul edilebilir bir biçim değil, şuna dönüştürün: {formats}" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -204,7 +203,7 @@ msgstr "İmzalanmamış bir depoya, depo imzalama anahtarı ekleyin" #: ../fdroidserver/update.py msgid "Add skeleton metadata files for APKs that are missing them" -msgstr "İskelet meta veri dosyaları olmayan APKlar için onları yarat" +msgstr "İskelet üst veri dosyaları olmayan APK'lar için onları ekle" #: ../fdroidserver/update.py #, python-brace-format @@ -274,7 +273,7 @@ msgstr "Geçersiz imza ile {apkfilename} arşivleme!" #: ../fdroidserver/mirror.py msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" -msgstr "Yansıtılacak temel URL, sorgu dizesini kullanarak indeks imzalama anahtarını içerebilir: ?fingerprint=" +msgstr "Yansının temel URL'si, 'şu sorgu dizgisini kullanarak indeks imzalama anahtarını içerebilir: ?fingerprint=" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/lint.py @@ -600,7 +599,7 @@ msgid "" "Enter the path to the Android SDK (%s) here:\n" "> " msgstr "" -"Burada Android SDK (%s) konumunu girin:\n" +"Android SDK (%s) konumunu buraya girin:\n" "> " #: ../fdroidserver/server.py ../fdroidserver/checkupdates.py @@ -714,7 +713,7 @@ msgstr "Argümanda geçersiz appid'ler bulundu" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Found invalid versionCodes for some apps" -msgstr "Bazı uygulamalar için geçersiz versionCode'lar bulundu" +msgstr "Bazı uygulamalar için geçersiz versionCodes bulundu" #: ../fdroidserver/metadata.py #, python-brace-format @@ -856,7 +855,7 @@ msgstr "Geçersiz lisans etiketi \"%s\"! Yalnızca https://spdx.org/license-list #: ../fdroidserver/lint.py msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" -msgstr "Geçersiz bağlantı - [http://foo.bar Bağlantı başlığı] veya [http://foo.bar] kullanın" +msgstr "Geçersiz bağlantı - [http://foo.bar Bağlantı başlığı] veya [http://foo.bar] kullanın" #: ../fdroidserver/metadata.py #, python-format @@ -954,7 +953,7 @@ msgstr "Ad '%s' yalnızca kendiliğinden bir ad - kaldırın" #: ../fdroidserver/common.py msgid "No 'config.py' found, using defaults." -msgstr "Öntanımlı değerlerle 'config.py' bulunamadı." +msgstr "'config.py' bulunamadı, öntanımlılar kullanılıyor." #: ../fdroidserver/common.py msgid "No Android SDK found!" @@ -987,7 +986,7 @@ msgstr "Bilgi bulunamadı." #: ../fdroidserver/lint.py msgid "No need to specify that the app is Free Software" -msgstr "Uygulamanın Ücretsiz Yazılım olduğunu belirtmeye gerek yok" +msgstr "Uygulamanın Özgür Yazılım olduğunu belirtmeye gerek yok" #: ../fdroidserver/lint.py msgid "No need to specify that the app is for Android" @@ -1094,7 +1093,7 @@ msgstr "Projenin genel lisansı." #: ../fdroidserver/dscanner.py msgid "Override path for repo APKs (default: ./repo)" -msgstr "Depo APKları için konumu geçersiz kıl (öntanımlı: ./repo)" +msgstr "Depo APK'ları için konumu geçersiz kıl (öntanımlı olarak: ./repo)" #: ../fdroidserver/index.py #, python-brace-format @@ -1192,7 +1191,7 @@ msgstr "İkili şeffaflık günlüğü {url} konumuna gönderiliyor" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" -msgstr "{url} adresine itiliyor" +msgstr "{url} adresine itiliyor" #: ../fdroid msgid "Quickly start a new repository" @@ -1405,7 +1404,7 @@ msgstr "Olağandan daha da çok bilgi çıkart" #: ../fdroidserver/nightly.py #, python-brace-format msgid "Striping mystery signature from {apkfilename}" -msgstr "Gizemli imza {apkfilename} dosyasından soyuluyor" +msgstr "Gizemli imza {apkfilename} dosyasından kaldırılıyor" #: ../fdroidserver/lint.py #, python-format @@ -1434,7 +1433,7 @@ msgstr "OBB sürüm kodu \"{name}.\" adından sonra gelmelidir:" #: ../fdroidserver/btlog.py msgid "The base URL for the repo to log (default: https://f-droid.org)" -msgstr "Günlüklenecek depo için taban URLsi (öntanımlı: https://f-droid.org)" +msgstr "Günlüğe kaydedilecek depo için temel URL (öntanımlı olarak: https://f-droid.org)" #: ../fdroidserver/mirror.py msgid "The directory to write the mirror to" @@ -1982,7 +1981,7 @@ msgstr "%s argümanlarından biri gerekli" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "only accepts strings, lists, and tuples" -msgstr "yalnızca satırları, listeleri ve dizileri kabul eder" +msgstr "yalnızca dizgileri, listeleri ve demetleri (tuple) kabul eder" #: ../fdroidserver/install.py #, python-format @@ -2157,7 +2156,7 @@ msgstr[1] "{0} uygulama, {1} anahtar adı" #: ../fdroidserver/update.py #, python-brace-format msgid "{apkfilename} ({appid}) has no metadata!" -msgstr "{apkfilename}{appid} üst verisiz!" +msgstr "{apkfilename}{appid} üst verisi yok!" #: ../fdroidserver/update.py #, python-brace-format From 4921003ddd1494ba5deba174fe35ca0f60025cfe Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 11:00:36 +0200 Subject: [PATCH 0488/2775] Translated using Weblate: Ukrainian (uk) by Hans-Christoph Steiner Currently translated at 40.8% (195 of 477 strings) Co-authored-by: Hans-Christoph Steiner Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/uk/ Translation: F-Droid/F-Droid Server --- locale/uk/LC_MESSAGES/fdroidserver.po | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index ee80d76b..6135ec84 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. -# FIRST AUTHOR , YEAR. -# +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2018-08-26 12:47+0000\n" -"Last-Translator: AB \n" +"PO-Revision-Date: 2020-04-07 13:43+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 3.2-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -721,9 +720,9 @@ msgid "Found invalid versionCodes for some apps" msgstr "Знайдено недійсні версії коду для деяких застосунків" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found multiple metadata files for {appid}" -msgstr "Створення скелетів файлів метаданих, які відсутні" +msgstr "Знайдено кілька файлів метаданих для {appid}" #: ../fdroidserver/index.py msgid "Found multiple signing certificates for repository." @@ -744,9 +743,9 @@ msgid "Found non-file at %s" msgstr "Знайдено не файл у %s" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Generated skeleton metadata for {appid}" -msgstr "Створення скелетів файлів метаданих, які відсутні" +msgstr "Створено основні метадані для {appid}" #: ../fdroidserver/common.py #, python-format @@ -1199,7 +1198,7 @@ msgstr "Натисніть вхід цього віддаленого схови #: ../fdroidserver/server.py ../fdroidserver/upload.py #, fuzzy, python-brace-format msgid "Pushing binary transparency log to {url}" -msgstr "Оновити бінарний журнал прозорості для URL-адреси" +msgstr "Оновити бінарний журнал прозорості для {url}" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -1292,9 +1291,8 @@ msgid "Run on git repo that has uncommitted changes" msgstr "" #: ../fdroidserver/lint.py -#, fuzzy msgid "Run rewritemeta to fix formatting" -msgstr "Переписати в певний формат: " +msgstr "Запустити rewritemeta виправити форматування" #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" @@ -1528,9 +1526,9 @@ msgid "Unknown metadata format: %s" msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path}" -msgstr "Створення скелетів файлів метаданих, які відсутні" +msgstr "Створення скелетів файлів метаданих: {path}" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " From e45ccb9f24119cfd78a8c777ce72bc3129406cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Mesk=C3=B3?= Date: Thu, 1 Oct 2020 11:00:36 +0200 Subject: [PATCH 0489/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Hunga?= =?UTF-8?q?rian=20(hu)=20by=20Bal=C3=A1zs=20Mesk=C3=B3=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 16.3% (78 of 477 strings) Co-authored-by: Balázs Meskó Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/hu/ Translation: F-Droid/F-Droid Server --- locale/hu/LC_MESSAGES/fdroidserver.po | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/locale/hu/LC_MESSAGES/fdroidserver.po b/locale/hu/LC_MESSAGES/fdroidserver.po index 00815d5a..34a43b6b 100644 --- a/locale/hu/LC_MESSAGES/fdroidserver.po +++ b/locale/hu/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# +# Balázs Meskó , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2018-10-03 11:28+0000\n" -"Last-Translator: Balázs Meskó \n" +"PO-Revision-Date: 2020-04-07 13:43+0000\n" +"Last-Translator: Balázs Meskó \n" "Language-Team: Hungarian \n" "Language: hu\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 3.2-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -37,7 +36,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-format msgid "\"%s/\" has no matching metadata file!" -msgstr "A(z) „%s/” nem rendelkezik megfelelő metaadat-fájllal." +msgstr "A(z) „%s/” nem rendelkezik megfelelő metaadatfájllal." #: ../fdroidserver/update.py #, python-brace-format @@ -47,7 +46,7 @@ msgstr "A(z) „{path}” elavult {name} csomagot tartalmaz ({version})" #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains recent {name} ({version})" -msgstr "A(z) „{path}” friss {name} ({version}) csomagot tartalmaz" +msgstr "A(z) „{path}” friss {name} csomagot tartalmaz ({version})" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format From cf7c905cc1cae48c6eddfe7fbb64573390859f61 Mon Sep 17 00:00:00 2001 From: Julien Gontier Date: Thu, 1 Oct 2020 11:00:37 +0200 Subject: [PATCH 0490/2775] Translated using Weblate: French (fr) by Julien Gontier Currently translated at 52.4% (250 of 477 strings) Co-authored-by: Julien Gontier Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 59c5eb44..54bc8658 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. -# FIRST AUTHOR , YEAR. -# +# Julien Gontier , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2019-01-29 07:59+0000\n" -"Last-Translator: Ldm Public \n" +"PO-Revision-Date: 2020-04-07 18:05+0000\n" +"Last-Translator: Julien Gontier \n" "Language-Team: French \n" "Language: fr\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 3.5-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -151,7 +150,7 @@ msgstr "'{apkfilename}' est déjà installé sur '{dev}'." #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" -msgstr "" +msgstr "'{field}' dans {linedesc} est obselète, regarder la documentation pour ces champs:" #: ../fdroidserver/common.py #, python-brace-format @@ -478,7 +477,7 @@ msgstr "Création d'un index non signé pour préparer la signature" #: ../fdroidserver/lint.py #, python-brace-format msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" -msgstr "" +msgstr "Le code de la version actuel {cv] est moins récent que la dernier build {versionCode}" #: ../fdroidserver/nightly.py msgid "DEBUG_KEYSTORE is not set or the value is incomplete" @@ -630,7 +629,7 @@ msgstr "Erreur de lecture {path} : {error}" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed resizing {path}: {error}" -msgstr "" +msgstr "Échec au redimensionement de {path}: {error}" #: ../fdroidserver/publish.py msgid "Failed to align application" @@ -643,7 +642,7 @@ msgstr "" #: ../fdroidserver/common.py msgid "Failed to get APK manifest information" -msgstr "" +msgstr "Échoument lors de la récupération de l'information manifest de l'APK" #: ../fdroidserver/update.py #, python-brace-format @@ -1929,15 +1928,15 @@ msgstr "" #: ../fdroidserver/server.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" -msgstr "" +msgstr "local_copy_dir ne semble pas se terminer avec \"fdroid\", peut être voulez-vous dire : \"{path}\"" #: ../fdroidserver/server.py msgid "local_copy_dir must be an absolute path!" -msgstr "" +msgstr "local_copy_dir doir être un chemin absolut !" #: ../fdroidserver/server.py msgid "local_copy_dir must be directory, not a file!" -msgstr "" +msgstr "local_copy_dir doit être absolument un dossier, pas un fichier !" #: ../fdroidserver/index.py #, python-format @@ -2145,7 +2144,7 @@ msgstr "utilisation : fdroid [-h|--help|--version] []" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" -msgstr "" +msgstr "utilisation de Apache libcloud pour syncronizer avec {url}" #: ../fdroidserver/publish.py #, python-brace-format From 41ea5eba152089c24a8b48e05d62bcb526ddeb77 Mon Sep 17 00:00:00 2001 From: anonymous Date: Thu, 1 Oct 2020 11:00:37 +0200 Subject: [PATCH 0491/2775] Translated using Weblate: French (fr) by anonymous Currently translated at 52.4% (250 of 477 strings) Co-authored-by: anonymous Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 54bc8658..78013da5 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -1,13 +1,14 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # Julien Gontier , 2020. +# anonymous , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" "PO-Revision-Date: 2020-04-07 18:05+0000\n" -"Last-Translator: Julien Gontier \n" +"Last-Translator: anonymous \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -591,7 +592,7 @@ msgstr "ERREUR : type de CI non supporté, les corrections sont bienvenues !" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Empty build flag at {linedesc}" -msgstr "" +msgstr "Drapeau de construction vide à {linedesc}" #: ../fdroidserver/init.py #, python-format @@ -638,7 +639,7 @@ msgstr "Impossible d'aligner les applications" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" -msgstr "" +msgstr "La création du S3 Bucket a échoué: {url}" #: ../fdroidserver/common.py msgid "Failed to get APK manifest information" @@ -647,7 +648,7 @@ msgstr "Échoument lors de la récupération de l'information manifest de l'APK" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed to get apk information, deleting {path}" -msgstr "" +msgstr "Impossible d'obtenir les informations de l'APK, suppression {path}" #: ../fdroidserver/update.py #, python-brace-format From 8d29dbd819f349f1150e5eab11928ce87f40e3c3 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 1 Oct 2020 11:00:37 +0200 Subject: [PATCH 0492/2775] Translated using Weblate: Russian (ru) by Andrey Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Andrey Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index d6d5f205..5761d4c4 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -3,13 +3,14 @@ # Golubev Alexander , 2020. # Mingun , 2020. # anonymous , 2020. +# Andrey , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-06 07:19+0000\n" -"Last-Translator: Golubev Alexander \n" +"PO-Revision-Date: 2020-04-08 02:03+0000\n" +"Last-Translator: Andrey \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -891,7 +892,7 @@ msgstr "Неверно указан versionCode: \"{versionCode}\". Это до #: ../fdroidserver/common.py #, python-brace-format msgid "JAR signature failed to verify: {path}" -msgstr "Не удаётся проверить подпись JAR: {path}" +msgstr "Не удается проверить подпись JAR: {path}" #: ../fdroidserver/common.py #, python-brace-format @@ -901,7 +902,7 @@ msgstr "Подпись JAR прошла проверку: {path}" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" -msgstr "Не обнаружена Java JDK! Установите её по стандартному пути или настройте переменную java_paths!" +msgstr "Не обнаружена Java JDK! Установите ее по стандартному пути или настройте переменную java_paths!" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1087,7 +1088,7 @@ msgstr "Параметры" #: ../fdroidserver/verify.py msgid "Output JSON report to file named after APK." -msgstr "Вывод отчёта в формате JSON под именем файла APK." +msgstr "Вывод отчета в формате JSON под именем файла APK." #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1422,11 +1423,11 @@ msgstr "Короткое описание приложения ({length} зна #: ../fdroidserver/common.py #, python-brace-format msgid "System clock is older than date in {path}!" -msgstr "Системное время отстаёт от date в {path}!" +msgstr "Системное время отстает от date в {path}!" #: ../fdroidserver/build.py msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." -msgstr "Тестовый режим. Всё собранное попадает во временную директорию; сборка запускается снова в любом случае." +msgstr "Тестовый режим. Все собранное попадает во временную директорию; сборка запускается снова в любом случае." #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -1456,7 +1457,7 @@ msgstr "Идентификационная метка (fingerprint) репози #: ../fdroidserver/common.py msgid "The repository's index could not be verified." -msgstr "Индекс репозитория не прошёл проверку." +msgstr "Индекс репозитория не прошел проверку." #: ../fdroidserver/server.py #, python-brace-format From 2f255fc999285187960c523da8318181c7bd5a2c Mon Sep 17 00:00:00 2001 From: Julien Gontier Date: Thu, 1 Oct 2020 11:00:38 +0200 Subject: [PATCH 0493/2775] Translated using Weblate: French (fr) by Julien Gontier Currently translated at 60.5% (289 of 477 strings) Co-authored-by: Julien Gontier Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 80 +++++++++++++-------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 78013da5..6519da41 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-07 18:05+0000\n" -"Last-Translator: anonymous \n" +"PO-Revision-Date: 2020-04-08 02:31+0000\n" +"Last-Translator: Julien Gontier \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -653,7 +653,7 @@ msgstr "Impossible d'obtenir les informations de l'APK, suppression {path}" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed to get apk information, skipping {path}" -msgstr "" +msgstr "Échoument lors de la récupération des informations de l'APK, saut de {path}" #: ../fdroidserver/install.py #, python-brace-format @@ -671,12 +671,12 @@ msgstr "Impossible d'optimiser avec zipalign cette application" #: ../fdroidserver/build.py #, python-brace-format msgid "Fetched buildserverid from VM: {buildserverid}" -msgstr "" +msgstr "Récupération de l'ID du serveur de construction depuis la VM: {buildserverid}" #: ../fdroidserver/signatures.py #, python-brace-format msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" -msgstr "" +msgstr "Récupération de la signature pour '{apkfilename}' -> '{sigdir}'" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -687,7 +687,7 @@ msgstr "Terminé" #: ../fdroidserver/lint.py msgid "Flattr donation methods belong in the FlattrID flag" -msgstr "" +msgstr "La méthode de donnation Flattr reviens au flag FlatttrID" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" @@ -695,26 +695,26 @@ msgstr "Balises HTML interdites" #: ../fdroidserver/build.py msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." -msgstr "" +msgstr "Forcer la construction des application désactiver, et opérateur indépendament au scan des problèmes. Seulement autoriser en mode de test." #: ../fdroidserver/build.py #, python-brace-format msgid "Force halting build after {0} sec timeout!" -msgstr "" +msgstr "Arrêt forcer de la construction apès {0} secondes de timeout!" #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" -msgstr "" +msgstr "\"{path}\" graphique trouvée sans metadonnées pour l'application \"{name}\"!" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" -msgstr "" +msgstr "Appids invalide trouvée dans l'argument" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Found invalid versionCodes for some apps" -msgstr "" +msgstr "Code de version invalide trouvée pour certaines application" #: ../fdroidserver/metadata.py #, python-brace-format @@ -728,16 +728,16 @@ msgstr "Plusieurs certificats de signature ont étés trouvés pour le référen #: ../fdroidserver/update.py #, python-brace-format msgid "Found multiple signing certificates in {path}" -msgstr "" +msgstr "Plusieurs certificats signées trouvée dans {path}" #: ../fdroidserver/index.py msgid "Found no signing certificates for repository." -msgstr "" +msgstr "Aucun certificat signée trouvée dans le dépot." #: ../fdroidserver/lint.py #, python-format msgid "Found non-file at %s" -msgstr "" +msgstr "Aucun fichier trouvée a %s" #: ../fdroidserver/update.py #, python-brace-format @@ -747,19 +747,19 @@ msgstr "Créer les métadonnées de base manquantes pour {appid}" #: ../fdroidserver/common.py #, python-format msgid "Git checkout of '%s' failed" -msgstr "" +msgstr "Vérification échouée du Git a '%s'" #: ../fdroidserver/common.py msgid "Git clean failed" -msgstr "" +msgstr "Nettoyage du Git échoué" #: ../fdroidserver/common.py msgid "Git fetch failed" -msgstr "" +msgstr "Recherche du Git échouée" #: ../fdroidserver/common.py msgid "Git remote set-head failed" -msgstr "" +msgstr "Set-head distant du Git à échouer" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -908,40 +908,40 @@ msgstr "" #: ../fdroidserver/lint.py msgid "Javascript in HTML src attributes" -msgstr "" +msgstr "Attributs Javascript trouvée dans HTML src" #: ../fdroidserver/init.py msgid "Keystore for signing key:\t" -msgstr "" +msgstr "Stockage des clés signée :\t" #: ../fdroidserver/lint.py #, python-brace-format msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" -msgstr "" +msgstr "Le dernier archivage utiliser '{commit}' ressemble a une balise, mais le Mode De Vérification Des Mise A Jour est '{ucm}'" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" -msgstr "" +msgstr "La méthode de donnation Liberapay appartien dans le flag LiberapayID" #: ../fdroidserver/rewritemeta.py msgid "List files that would be reformatted" -msgstr "" +msgstr "Lister les fichiers qui seront reformater" #: ../fdroidserver/lint.py msgid "Locale included in f-droid.org URL" -msgstr "" +msgstr "Les paramètres de lieu sont inclus dans f-droid.org URL" #: ../fdroidserver/build.py msgid "Make the build stop on exceptions" -msgstr "" +msgstr "Faire la construction s'arrèter si exceptions" #: ../fdroidserver/index.py msgid "Malformed repository mirrors." -msgstr "" +msgstr "Mirroirs de dépot malformée." #: ../fdroidserver/server.py msgid "Malformed serverwebroot line:" -msgstr "" +msgstr "serverwebroot malformer en ligne :" #: ../fdroidserver/gpgsign.py msgid "Missing output directory" @@ -950,19 +950,19 @@ msgstr "Répertoire de destination manquant" #: ../fdroidserver/lint.py #, python-format msgid "Name '%s' is just the auto name - remove it" -msgstr "" +msgstr "Le nom '%s' est just un nom générer - retirer le" #: ../fdroidserver/common.py msgid "No 'config.py' found, using defaults." -msgstr "" +msgstr "Aucun 'config.py' trouvée, utilisation des originales." #: ../fdroidserver/common.py msgid "No Android SDK found!" -msgstr "" +msgstr "Aucun SDK Android trouvée !" #: ../fdroidserver/import.py msgid "No android or kivy project could be found. Specify --subdir?" -msgstr "" +msgstr "Aucun projet android ou kivy n'a pu être trouver. Spécifiier --subdir ?" #: ../fdroidserver/install.py msgid "No attached devices found" @@ -971,7 +971,7 @@ msgstr "Aucun périphérique connecté trouvé" #: ../fdroidserver/metadata.py #, python-brace-format msgid "No commit specified for {versionName} in {linedesc}" -msgstr "" +msgstr "Aucun archivage spécifier pour {versionName} dans {linedesc}" #: ../fdroidserver/index.py msgid "No fingerprint in URL." @@ -995,40 +995,40 @@ msgstr "Pas besoin de spécifier que l'application est pour Android" #: ../fdroidserver/server.py msgid "No option set! Edit your config.py to set at least one of these:" -msgstr "" +msgstr "Aucune option configurer ! Éditer votre config.py pour le mettre au moins a l'un d'eux :" #: ../fdroidserver/common.py msgid "No packages specified" -msgstr "" +msgstr "Aucun packet spécifier" #: ../fdroidserver/install.py #, python-format msgid "No signed apk available for %s" -msgstr "" +msgstr "Aucun apk signée dispognible pour %s" #: ../fdroidserver/install.py msgid "No signed output directory - nothing to do" -msgstr "" +msgstr "Aucun dossier de sortie signée - rien n'est a faire" #: ../fdroidserver/update.py #, python-brace-format msgid "No signing certificates found in {path}" -msgstr "" +msgstr "Aucun certificat signée trouvée dans {path}" #: ../fdroidserver/common.py #, python-format msgid "No such package: %s" -msgstr "" +msgstr "Aucun packet comme sa : %s" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py #, python-brace-format msgid "No such versionCode {versionCode} for app {appid}" -msgstr "" +msgstr "Aucun code de version {versionCode} pour l'application {appid}" #: ../fdroidserver/verify.py ../fdroidserver/publish.py msgid "No unsigned directory - nothing to do" -msgstr "" +msgstr "Aucun dossier signée - rien n'est a faire" #: ../fdroidserver/signindex.py msgid "Nothing to do" From ddb10b3400365ba6a36d5355497c9921190d9ba2 Mon Sep 17 00:00:00 2001 From: anonymous Date: Thu, 1 Oct 2020 11:00:38 +0200 Subject: [PATCH 0494/2775] Translated using Weblate: French (fr) by anonymous Currently translated at 60.5% (289 of 477 strings) Co-authored-by: anonymous Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 6519da41..a176db9e 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgstr "" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" "PO-Revision-Date: 2020-04-08 02:31+0000\n" -"Last-Translator: Julien Gontier \n" +"Last-Translator: anonymous \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -658,7 +658,7 @@ msgstr "Échoument lors de la récupération des informations de l'APK, saut de #: ../fdroidserver/install.py #, python-brace-format msgid "Failed to install '{apkfilename}' on {dev}: {error}" -msgstr "" +msgstr "Impossible d'installer '{apkfilename}' sur {dev}: {error}" #: ../fdroidserver/publish.py ../fdroidserver/common.py msgid "Failed to sign application" From ce14b7a4a20fc8c5bb3b3edc4eda9d66e0e50f23 Mon Sep 17 00:00:00 2001 From: Golubev Alexander Date: Thu, 1 Oct 2020 11:00:39 +0200 Subject: [PATCH 0495/2775] Translated using Weblate: Russian (ru) by Golubev Alexander Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Golubev Alexander Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 5761d4c4..4a795b7f 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-08 02:03+0000\n" -"Last-Translator: Andrey \n" +"PO-Revision-Date: 2020-04-08 02:31+0000\n" +"Last-Translator: Golubev Alexander \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -892,7 +892,7 @@ msgstr "Неверно указан versionCode: \"{versionCode}\". Это до #: ../fdroidserver/common.py #, python-brace-format msgid "JAR signature failed to verify: {path}" -msgstr "Не удается проверить подпись JAR: {path}" +msgstr "Не удаётся проверить подпись JAR: {path}" #: ../fdroidserver/common.py #, python-brace-format @@ -902,7 +902,7 @@ msgstr "Подпись JAR прошла проверку: {path}" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" -msgstr "Не обнаружена Java JDK! Установите ее по стандартному пути или настройте переменную java_paths!" +msgstr "Не обнаружена Java JDK! Установите её по стандартному пути или настройте переменную java_paths!" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1088,7 +1088,7 @@ msgstr "Параметры" #: ../fdroidserver/verify.py msgid "Output JSON report to file named after APK." -msgstr "Вывод отчета в формате JSON под именем файла APK." +msgstr "Вывод отчёта в формате JSON под именем файла APK." #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1423,11 +1423,11 @@ msgstr "Короткое описание приложения ({length} зна #: ../fdroidserver/common.py #, python-brace-format msgid "System clock is older than date in {path}!" -msgstr "Системное время отстает от date в {path}!" +msgstr "Системное время отстаёт от date в {path}!" #: ../fdroidserver/build.py msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." -msgstr "Тестовый режим. Все собранное попадает во временную директорию; сборка запускается снова в любом случае." +msgstr "Тестовый режим. Всё собранное попадает во временную директорию; сборка запускается снова в любом случае." #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -1457,7 +1457,7 @@ msgstr "Идентификационная метка (fingerprint) репози #: ../fdroidserver/common.py msgid "The repository's index could not be verified." -msgstr "Индекс репозитория не прошел проверку." +msgstr "Индекс репозитория не прошёл проверку." #: ../fdroidserver/server.py #, python-brace-format From 6b2b088665b1556fdd10ed398ec1713e64ceeeeb Mon Sep 17 00:00:00 2001 From: random r Date: Thu, 1 Oct 2020 11:00:39 +0200 Subject: [PATCH 0496/2775] Translated using Weblate: Italian (it) by random r Currently translated at 35.4% (169 of 477 strings) Co-authored-by: random r Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/it/ Translation: F-Droid/F-Droid Server --- locale/it/LC_MESSAGES/fdroidserver.po | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index da3f654e..b862ad56 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -1,22 +1,21 @@ # 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 , YEAR. -# +# random r , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2018-12-31 23:09+0000\n" -"Last-Translator: Matteo Fumagalli \n" +"PO-Revision-Date: 2020-04-11 13:36+0000\n" +"Last-Translator: random r \n" "Language-Team: Italian \n" "Language: it\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 3.4-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -152,7 +151,7 @@ msgstr "\"{apkfilename}\" è già installato su {dev}." #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" -msgstr "" +msgstr "'{field}' in {linedesc} è obsoleto, leggi la documentazione per i campi attuali:" #: ../fdroidserver/common.py #, python-brace-format @@ -1244,9 +1243,9 @@ msgid "Reset and create a brand new build server, even if the existing one appea msgstr "" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" -msgstr "Archiviando {apkfilename} con il debug.keystore fornito" +msgstr "Firmando di nuovo {apkfilename} con il debug.keystore fornito" #: ../fdroidserver/update.py msgid "Resize all the icons exceeding the max pixel size and exit" From ad6f2b255d7784985832aca93d0f4bd590673a9f Mon Sep 17 00:00:00 2001 From: Julien Gontier Date: Thu, 1 Oct 2020 11:00:39 +0200 Subject: [PATCH 0497/2775] Translated using Weblate: French (fr) by Julien Gontier Currently translated at 68.3% (326 of 477 strings) Co-authored-by: Julien Gontier Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 78 +++++++++++++-------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index a176db9e..d2f80b49 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-08 02:31+0000\n" -"Last-Translator: anonymous \n" +"PO-Revision-Date: 2020-04-11 13:36+0000\n" +"Last-Translator: Julien Gontier \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -763,41 +763,41 @@ msgstr "Set-head distant du Git à échouer" #: ../fdroidserver/common.py msgid "Git reset failed" -msgstr "" +msgstr "Reset de Git échouée" #: ../fdroidserver/common.py msgid "Git submodule sync failed" -msgstr "" +msgstr "Synchronisation du submodule Git échoué" #: ../fdroidserver/common.py msgid "Git submodule update failed" -msgstr "" +msgstr "Échec de la mise à jour du sous-module Git" #: ../fdroidserver/common.py msgid "HTTPS must be used with Subversion URLs!" -msgstr "" +msgstr "HTTPS doit être utilisé avec les URL de Subversion !" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " -msgstr "" +msgstr "Ignorer le package sans métadonnées : " #: ../fdroidserver/update.py #, python-brace-format msgid "Ignoring stale cache data for {apkfilename}" -msgstr "" +msgstr "Ignorer les données de cache périmées pour {apkfilename}" #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Ignoring {ext} file at '{path}'" -msgstr "" +msgstr "Ignorer le fichier {ext} à '{path}'" #: ../fdroidserver/update.py msgid "Include APKs that are signed with disabled algorithms like MD5" -msgstr "" +msgstr "Inclure des fichiers APK signés avec algorithmes désactivés comme MD5" #: ../fdroidserver/common.py msgid "Initialising submodules" -msgstr "" +msgstr "Initialisation des sous-modules" #: ../fdroidserver/install.py msgid "Install all signed applications available" @@ -815,7 +815,7 @@ msgstr "Installation de %s …" #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" -msgstr "" +msgstr "Installation de '{apkfilename}' sur {dev}…" #: ../fdroid msgid "Interact with the repo HTTP server" @@ -828,83 +828,83 @@ msgstr "APK invalide" #: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py #, python-brace-format msgid "Invalid VercodeOperation: {field}" -msgstr "" +msgstr "VercodeOperation non valide : {champ}" #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" -msgstr "" +msgstr "Booléen '%s' non valide" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid build flag at {line} in {linedesc}" -msgstr "" +msgstr "Indicateur de build non valide à {line} dans {linedesc}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid build format: {value} in {name}" -msgstr "" +msgstr "Format de construction non valide : {value} dans {name}" #: ../fdroidserver/lint.py msgid "Invalid bulleted list" -msgstr "" +msgstr "Liste à puces non valide" #: ../fdroidserver/lint.py #, python-format msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" -msgstr "" +msgstr "Balise de licence non valide \"%s\" ! Utilisez uniquement des balises de https ://spdx.org/license-list" #: ../fdroidserver/lint.py msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" -msgstr "" +msgstr "Lien non valide - utilisez [http://foo.bar Link title] ou [http://foo.bar]" #: ../fdroidserver/metadata.py #, python-format msgid "Invalid metadata in %s:%d" -msgstr "" +msgstr "Métadonnées non valides dans %s:%d" #: ../fdroidserver/metadata.py msgid "Invalid metadata in: " -msgstr "" +msgstr "Métadonnées non valides dans : " #: ../fdroidserver/common.py #, python-format msgid "Invalid name for published file: %s" -msgstr "" +msgstr "Nom non valide pour le fichier publié :%s" #: ../fdroidserver/common.py #, python-brace-format msgid "Invalid package name {0}" -msgstr "" +msgstr "Nom de package non valide {0}" #: ../fdroidserver/common.py #, python-brace-format msgid "Invalid redirect to non-HTTPS: {before} -> {after} " -msgstr "" +msgstr "Redirection non valide vers non-HTTPS : {before} -> {after} " #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" -msgstr "" +msgstr "VersionCode non valide : \"{versionCode}\" n'est pas un entier !" #: ../fdroidserver/common.py #, python-brace-format msgid "JAR signature failed to verify: {path}" -msgstr "" +msgstr "La signature JAR n'a pas pu vérifier:{path}" #: ../fdroidserver/common.py #, python-brace-format msgid "JAR signature verified: {path}" -msgstr "" +msgstr "Signature JAR vérifiée : {path}" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" -msgstr "" +msgstr "Java JDK introuvable ! Installez dans un emplacement standard ou définissez java_paths !" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" -msgstr "" +msgstr "Java jarsigner introuvable ! Installez dans un emplacement standard ou définissez java_paths !" #: ../fdroidserver/lint.py msgid "Javascript in HTML src attributes" @@ -1041,35 +1041,35 @@ msgstr "Rien à faire pour {appid}." #: ../fdroidserver/init.py msgid "Now set these in config.py:" -msgstr "" +msgstr "Maintenant, définissez-les dans config.py :" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py #, python-brace-format msgid "OBB file has newer versionCode({integer}) than any APK:" -msgstr "" +msgstr "Le fichier OBB a un code de version plus récent ({integer}) que n'importe quel APK :" #: ../fdroidserver/update.py msgid "OBB filename must start with \"main.\" or \"patch.\":" -msgstr "" +msgstr "Le nom de fichier OBB doit commencer par «principal». ou \"patch\" :" #: ../fdroidserver/update.py msgid "OBB's packagename does not match a supported APK:" -msgstr "" +msgstr "Le nom de paquet d'OBB ne correspond pas à un fichier APK pris en charge :" #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" -msgstr "" +msgstr "L'ancienne signature APK n'a pas pu être vérifiée : {path}" #: ../fdroid msgid "Old, deprecated name for fdroid deploy" -msgstr "" +msgstr "Ancien nom obsolète pour fdroid deploy" #: ../fdroidserver/update.py #, python-brace-format msgid "Only PNG and JPEG are supported for graphics, found: {path}" -msgstr "" +msgstr "Seuls les formats PNG et JPEG sont pris en charge pour les graphiques, trouvés : {path}" #: ../fdroidserver/checkupdates.py msgid "Only print differences with the Play Store" @@ -1086,7 +1086,7 @@ msgstr "Options" #: ../fdroidserver/verify.py msgid "Output JSON report to file named after APK." -msgstr "" +msgstr "Générez un rapport JSON dans un fichier nommé d'après l'APK." #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1094,12 +1094,12 @@ msgstr "Licence globale du projet." #: ../fdroidserver/dscanner.py msgid "Override path for repo APKs (default: ./repo)" -msgstr "" +msgstr "Remplacer le chemin pour les fichiers APK de dépôt (par défaut : ./repo)" #: ../fdroidserver/index.py #, python-brace-format msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" -msgstr "" +msgstr "Substitution du nom de version vide dans {apkfilename} des métadonnées : {version}" #: ../fdroidserver/common.py #, python-brace-format From 08b44c50098de4f1cf0ca02c4d9caac0757f914b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 11:00:40 +0200 Subject: [PATCH 0498/2775] Translated using Weblate: French (fr) by Hans-Christoph Steiner Currently translated at 68.3% (326 of 477 strings) Co-authored-by: Hans-Christoph Steiner Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index d2f80b49..5a124399 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -2,13 +2,14 @@ # Copyright (C) YEAR Free Software Foundation, Inc. # Julien Gontier , 2020. # anonymous , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-11 13:36+0000\n" -"Last-Translator: Julien Gontier \n" +"PO-Revision-Date: 2020-04-15 12:27+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -478,7 +479,7 @@ msgstr "Création d'un index non signé pour préparer la signature" #: ../fdroidserver/lint.py #, python-brace-format msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" -msgstr "Le code de la version actuel {cv] est moins récent que la dernier build {versionCode}" +msgstr "Le code de la version actuel {cv} est moins récent que la dernier build {versionCode}" #: ../fdroidserver/nightly.py msgid "DEBUG_KEYSTORE is not set or the value is incomplete" @@ -828,7 +829,7 @@ msgstr "APK invalide" #: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py #, python-brace-format msgid "Invalid VercodeOperation: {field}" -msgstr "VercodeOperation non valide : {champ}" +msgstr "VercodeOperation non valide : {field}" #: ../fdroidserver/metadata.py #, python-format From d359ee3ad2211610dc7a19752bc3361cf547c068 Mon Sep 17 00:00:00 2001 From: ERDwaYbR Date: Thu, 1 Oct 2020 11:00:40 +0200 Subject: [PATCH 0499/2775] Translated using Weblate: Chinese (Simplified) (zh_Hans) by ERDwaYbR Currently translated at 20.7% (99 of 477 strings) Co-authored-by: ERDwaYbR Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hans/ Translation: F-Droid/F-Droid Server --- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 25 +++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index fba8134a..0ad2d463 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -1,22 +1,21 @@ # 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 , YEAR. -# +# ERDwaYbR , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2018-10-22 05:24+0000\n" -"Last-Translator: kak mi \n" +"PO-Revision-Date: 2020-04-18 02:37+0000\n" +"Last-Translator: ERDwaYbR \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.3-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -81,9 +80,8 @@ msgstr "" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py -#, fuzzy msgid "%prog [options]" -msgstr "100%prog [options]" +msgstr "100%prog [选项]" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -1738,13 +1736,13 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" -msgstr "" +msgstr "模糊选项:%(option)s 可以相配 %(matches)s" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format msgid "ambiguous option: %s (%s?)" -msgstr "" +msgstr "不明确的选项:%s(%s?)" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #, fuzzy @@ -1778,7 +1776,7 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" -msgstr "" +msgstr "无法打开 '%s': %s" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -1939,15 +1937,16 @@ msgstr "" #: ../fdroidserver/server.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" -msgstr "" +msgstr "local_copy_dir未以“ fdroid”结尾,也许你指的是:“ {path}”" #: ../fdroidserver/server.py msgid "local_copy_dir must be an absolute path!" -msgstr "" +msgstr "local_copy_dir必须为绝对路径!" #: ../fdroidserver/server.py +#, fuzzy msgid "local_copy_dir must be directory, not a file!" -msgstr "" +msgstr "local_copy_dir为目录,不是档案!" #: ../fdroidserver/index.py #, python-format From e203cad567eb4e67ce1e3171957b46b92795cfb6 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Thu, 1 Oct 2020 11:00:41 +0200 Subject: [PATCH 0500/2775] Translated using Weblate: Albanian (sq) by Besnik Bleta Currently translated at 97.0% (463 of 477 strings) Translation: F-Droid/F-Droid Server Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/sq/ Added translation using Weblate: Albanian (sq) by Besnik Bleta Co-authored-by: Besnik Bleta --- locale/sq/LC_MESSAGES/fdroidserver.po | 2252 +++++++++++++++++++++++++ 1 file changed, 2252 insertions(+) create mode 100644 locale/sq/LC_MESSAGES/fdroidserver.po diff --git a/locale/sq/LC_MESSAGES/fdroidserver.po b/locale/sq/LC_MESSAGES/fdroidserver.po new file mode 100644 index 00000000..2d3ce666 --- /dev/null +++ b/locale/sq/LC_MESSAGES/fdroidserver.po @@ -0,0 +1,2252 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# Besnik Bleta , 2020. +msgid "" +msgstr "" +"Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" +"Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" +"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"PO-Revision-Date: 2020-04-26 19:11+0000\n" +"Last-Translator: Besnik Bleta \n" +"Language-Team: Albanian \n" +"Language: sq\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 4.0.2-dev\n" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH Public Key to be used as Deploy Key:" +msgstr "" +"\n" +"Kyç SSH Publik për t’u përdorur si Kyç Sendërtimesh:" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "" +"\n" +"{path} encoded for the DEBUG_KEYSTORE secret variable:" +msgstr "" +"\n" +"{path} i koduar për ndryshoren e fshehtë DEBUG_KEYSTORE:" + +#: ../fdroidserver/lint.py +#, python-format +msgid "\"%s/\" has no matching metadata file!" +msgstr "\"%s/\" s’ka kartel tejtëdhënash me përputhje!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains outdated {name} ({version})" +msgstr "\"{path}\" përmban {name} të vjetruar ({version})" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains recent {name} ({version})" +msgstr "\"{path}\" përmban {name} të freskët ({version})" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "\"{path}\" exists but s3cmd is not installed!" +msgstr "\"{path}\" ekziston, por s3cmd s’është e instaluar!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "\"{path}\" is not an accepted format, convert to: {formats}" +msgstr "\"{path}\" s’është në një format të pranuar, shndërrojeni në: {formats}" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%(option)s option requires %(number)d argument" +msgid_plural "%(option)s option requires %(number)d arguments" +msgstr[0] "Mundësi %(option)s lyp %(number)d argument" +msgstr[1] "Mundësi %(option)s lyp %(number)d argumente" + +#: ../fdroidserver/mirror.py +#, python-format +msgid "%(prog)s [options] url" +msgstr "%(prog)s [mundësi] url" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%(prog)s: error: %(message)s\n" +msgstr "%(prog)s: gabim: %(message)s\n" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "%d problems found" +msgstr "U gjetën %d probleme" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "%prog [options]" +msgstr "%prog [mundësi]" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%r is not callable" +msgstr "%r s’mund të thirret" + +#: ../fdroidserver/lint.py +#, python-format +msgid "%s is not an accepted build field" +msgstr "%s s’është fushë e pranuar montimi" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%s option does not take a value" +msgstr "Mundësia %s s’merr ndonjë vlerë" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keypass' not found in config.py!" +msgstr "S’u gjet 'keypass' në config.py!" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystore' not found in config.py!" +msgstr "S’u gjet 'keystore' në config.py!" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystorepass' not found in config.py!" +msgstr "S’u gjet 'keystorepass' te config.py!" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'repo_keyalias' not found in config.py!" +msgstr "S’u gjet 'repo_keyalias' te config.py!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "'required' is an invalid argument for positionals" +msgstr "'required' është argument i pavlefshëm për pozicionalë" + +#: ../fdroidserver/common.py +msgid "'sdk_path' not set in 'config.py'!" +msgstr "'sdk_path' te 'config.py' s’është ujdisur!" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" +msgstr "'{aapt}' është shumë i vjetër, fdroid lyp build-tools-23.0.0 ose më të ri!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" +msgstr "'{aapt}' është shumë i vjetër, fdroid lyp build-tools-{version} ose më të ri!" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "'{apkfilename}' is already installed on {dev}." +msgstr "'{apkfilename}' është tashmë e instaluar në {dev}." + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" +msgstr "'{field}' te {linedesc} është e vjetruar, për fushat në përdorim, shihni dokumentimin:" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" +msgstr "'{field}' do të jetë sipas një rendi kuturu! Nëse rendi është i rëndësishëm, përdorni kllapa () ose []!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{path}' failed to execute!" +msgstr "S’u arrit të përmbushet '{path}'!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" +msgstr "'{value}' s’është një {field} e vlefshme te {appid}. Rregullsi shprehjeje të rregullt: {pattern}" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "...checkupdate failed for {appid} : {error}" +msgstr "…checkupdate dështoi për {appid} : {error}" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid ".__call__() not defined" +msgstr ".__call__() e pacaktuar" + +#: ../fdroidserver/metadata.py +msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." +msgstr ".fdroid.txt nuk mbulohet! Shndërrojeni në .fdroid.yml ose .fdroid.json." + +#: ../fdroidserver/lint.py +msgid "/issues is missing" +msgstr "/issues mungon" + +#: ../fdroidserver/mirror.py +msgid "A URL is required as an argument!" +msgstr "Lypset një URL si argument!" + +#: ../fdroid +msgid "Add PGP signatures using GnuPG for packages in repo" +msgstr "Shtoni për paketa në depo nënshkrime PGP duke përdorur GnuPG-në" + +#: ../fdroid +msgid "Add a new application from its source code" +msgstr "Shtoni një aplikacion të ri që prej kodit të tij burim" + +#: ../fdroidserver/update.py +msgid "Add a repo signing key to an unsigned repo" +msgstr "Shtoni te një depo e panënshkruar një kyç nënshkrimi depoje" + +#: ../fdroidserver/update.py +msgid "Add skeleton metadata files for APKs that are missing them" +msgstr "Shtoni kartela tejtëdhënash skeleton për APK ku mungojnë të tilla" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Adding new repo for only {name}" +msgstr "Po shtohet depo e re për vetëm {name}" + +#: ../fdroidserver/init.py +msgid "Alias of the repo signing key in the keystore" +msgstr "Alias i kyçit të nënshkrimeve të depos te depo kyçesh" + +#: ../fdroidserver/import.py +msgid "Allows a different revision (or git branch) to be specified for the initial import" +msgstr "Lejon të specifikohet një rishikim tjetër (ose kryeni “git branch”) për importimin fillestar" + +#: ../fdroidserver/mirror.py +msgid "Also mirror the full archive section" +msgstr "Pasqyro gjithashtu pjesën e arkivit të plotë" + +#: ../fdroidserver/lint.py +msgid "Also warn about formatting issues, like rewritemeta -l" +msgstr "Sinjalizo gjithashtu mbi probleme formatimi, bie fjala, rewritemeta -l" + +#: ../fdroidserver/common.py ../fdroidserver/build.py +#, python-brace-format +msgid "Android SDK '{path}' does not have '{dirname}' installed!" +msgstr "Android SDK '{path}' s’ka '{dirname}' të instaluar!" + +#: ../fdroidserver/common.py +msgid "Android SDK not found!" +msgstr "S’u gjet SDK Android-i!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' does not exist!" +msgstr "Shtegu Android SDK '{path}' s’ekziston!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' is not a directory!" +msgstr "Shtegu Android SDK '{path}' s’është drejtori!" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android build-tools path '{path}' does not exist!" +msgstr "Shtegu për build-tools Android '{path}' s’ekziston!" + +#: ../fdroidserver/update.py +msgid "AndroidManifest.xml has no date" +msgstr "AndroidManifest.xml s’ka datë" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "App is in '{repo}' but has a link to {url}" +msgstr "Aplikacioni gjendet në '{repo}' por ka një lidhje te {url}" + +#: ../fdroidserver/lint.py +msgid "Appending .git is not necessary" +msgstr "S’është i nevojshëm shtimi i .git nga pas" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Archiving {apkfilename} with invalid signature!" +msgstr "Po arkivohet {apkfilename} me nënshkrim të pavlefshëm!" + +#: ../fdroidserver/mirror.py +msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" +msgstr "URL bazë për t’u pasqyruar, mund të përfshijë kyçin e nënshkrimit të treguesit që përdor vargun e kërkimi: ?fingerprint=" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in srclib '{srclib}'" +msgstr "" + +#: ../fdroid +msgid "Build a package from source" +msgstr "Montoni një paketë nga burimi" + +#: ../fdroidserver/build.py +msgid "Build all applications available" +msgstr "Monto krejt aplikacionet e mundshme" + +#: ../fdroidserver/lint.py +msgid "Build generated by `fdroid import` - remove disable line once ready" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Build metadata git repo has uncommited changes!" +msgstr "Depoja git e tejtëdhënave të montimit ka ndryshime të paparashtruara!" + +#: ../fdroidserver/build.py +msgid "Build only the latest version of each package" +msgstr "Monto vetëm versionin më të ri të çdo pakete" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" +msgstr "Montimi duhet të ketë versionName dhe versionCode ndarë me presje, jo \"{value}\", te {linedesc}" + +#: ../fdroidserver/init.py +#, python-format +msgid "Built repo based in \"%s\" with this config:" +msgstr "Depo montimesh e bazua në \"%s\" me këtë formësim:" + +#: ../fdroidserver/build.py +msgid "Can't build due to {} error while scanning" +msgid_plural "Can't build due to {} errors while scanning" +msgstr[0] "S’montohet dot, për shkak të {} gabimi teksa skanohej" +msgstr[1] "S’montohet dot, për shkak të {} gabimeve teksa skanohej" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find a packageName for {path}!" +msgstr "S’gjendet dot një packageName për {path}!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find an appid for {path}!" +msgstr "S’gjendet dot një appid për {path}!" + +#: ../fdroidserver/vmtools.py +#, python-brace-format +msgid "Cannot read \"{path}\"!" +msgstr "S’lexohet dot \"${path}\"!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot resolve app id {appid}" +msgstr "S’ftillohet dot ID aplikacioni {appid}" + +#: ../fdroidserver/rewritemeta.py +msgid "Cannot use --list and --to at the same time" +msgstr "S’mund të përdoret --list dhe --to në të njëjtën kohë" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" +msgstr "S’shkruhet dot \"{path}\", s’është format i pranuar, përdorni: {formats}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Categories '%s' is not valid" +msgstr "Kategoritë '%s' s’janë të vlefshme" + +#: ../fdroidserver/lint.py +msgid "Categories are not set" +msgstr "S’janë ujdisur kategori" + +#: ../fdroid +msgid "Check for updates to applications" +msgstr "Kontrollo për përditësime aplikacionesh" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" +msgstr "Po kontrollohet arkivimi përr {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" + +#: ../fdroidserver/dscanner.py +msgid "Clean after all scans have finished" +msgstr "Pastroje, pasi të kenë përfunduar krejt skanimet" + +#: ../fdroidserver/dscanner.py +msgid "Clean before the scans start and rebuild the container" +msgstr "Pastrojeni përpara se të fillojnë skanimet dhe të rimontohet kontejneri" + +#: ../fdroidserver/dscanner.py +msgid "Clean up all containers and then exit" +msgstr "Pastroji krejt kontejnerët dhe mandej dil" + +#: ../fdroidserver/update.py +msgid "Clean update - don't uses caches, reprocess all APKs" +msgstr "Përditësim na e para - nuk përdor fshehtina, ripërpuno krejt APK-të" + +#: ../fdroidserver/import.py +msgid "Comma separated list of categories." +msgstr "Listë kategorish ndarë me presje." + +#: ../fdroid +#, c-format, python-format +msgid "Command '%s' not recognised.\n" +msgstr "Urdhër '%s' jo i pranuar.\n" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes" +msgstr "Depozito ndryshimet" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not find '{command}' on your system" +msgstr "Në sistemin tuaj s’u gjet '{command}'" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not find {path} to remove it" +msgstr "S’u gjet dot {path} për ta hequr" + +#: ../fdroidserver/update.py +msgid "Could not open apk file for analysis" +msgstr "S’u hap dot kartela apk për analizim" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/import.py +msgid "Couldn't find latest version code" +msgstr "S’ u gjet dot kod i versionit më të ri" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/import.py +msgid "Couldn't find latest version name" +msgstr "S’ u gjet dot emër versioni më të ri" + +#: ../fdroidserver/import.py +msgid "Couldn't find package ID" +msgstr "S’u gjet dot ID pakete" + +#: ../fdroidserver/update.py +msgid "Cowardily refusing to overwrite existing signing key setup!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create a repo signing key in a keystore" +msgstr "Krijoni një kyç nënshkrimi depoje në një depo kyçesh" + +#: ../fdroidserver/update.py +msgid "Create skeleton metadata files that are missing" +msgstr "Krijoni kartela tejtëdhënash skeleton që mungojnë" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Created new container \"{name}\"" +msgstr "U krijua kontejner i ri \"{name}\"" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating \"{path}\" for configuring s3cmd." +msgstr "Po krijohet \"{path}\" për formësim të s3cmd." + +#: ../fdroidserver/publish.py +msgid "Creating log directory" +msgstr "Po krijohet drejtori regjistrash" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating new S3 bucket: {url}" +msgstr "Po krijohet S3 bucket i ri: {url}" + +#: ../fdroidserver/publish.py +msgid "Creating output directory" +msgstr "Po krijohet drejtori përfundimesh" + +#: ../fdroidserver/index.py +msgid "Creating signed index with this key (SHA256):" +msgstr "Po krijohet tregues i nënshkruar me këtë kyç (SHA256):" + +#: ../fdroidserver/import.py ../fdroidserver/verify.py +#: ../fdroidserver/publish.py +msgid "Creating temporary directory" +msgstr "Po krijohet drejtori e përkohshme" + +#: ../fdroidserver/index.py +msgid "Creating unsigned index in preparation for signing" +msgstr "Po krijohet tregues i panënshkruar, si përgatitje për nënshkrim" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" +msgstr "CurrentVersionCode {cv} është më i vogël sesa zëri {versionCode} i montimit më të vjetër" + +#: ../fdroidserver/nightly.py +msgid "DEBUG_KEYSTORE is not set or the value is incomplete" +msgstr "DEBUG_KEYSTORE s’është ujdisur ose vlera është e paplotë" + +#: ../fdroidserver/update.py +msgid "Delete APKs and/or OBBs without metadata from the repo" +msgstr "Fshi APK-ra dhe/ose OBB-ra pa tejtëdhëna prej depos" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Deleting unknown file: {path}" +msgstr "Po fshihet kartelë e panjohur: {path}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description '%s' is just the app's summary" +msgstr "Përmbledhja '%s' është thjesht përmbledhja e aplikacionit" + +#: ../fdroidserver/lint.py +msgid "Description has a duplicate line" +msgstr "Përshkrimi ka një rresht të përsëdytur" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description has a list (%s) but it isn't bulleted (*) nor numbered (#)" +msgstr "Përshkrimi ka një listë (%s), por kjo s’është as me toptha (*), as e numërtuar (#)" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Description of length {length} is over the {limit} char limit" +msgstr "Përshkrimi me gjatësi {length} është mbi kufirin prej {limit} shenjash" + +#: ../fdroidserver/nightly.py +msgid "Do not deploy the new files to the repo" +msgstr "Mos i vendos kartelat e reja te depoja" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Do not include \"{path}\" in URL!" +msgstr "Mos përfshi \"{path}\" në URL!" + +#: ../fdroidserver/init.py +msgid "Do not prompt for Android SDK path, just fail" +msgstr "Mos kërko shteg SDK-je Android, thjesht dështo" + +#: ../fdroidserver/nightly.py +msgid "Do not remove the private keys generated from the keystore" +msgstr "Mos i hiq kyçet private të prodhuar nga depo kyçesh" + +#: ../fdroidserver/build.py +msgid "Don't create a source tarball, useful when testing a build" +msgstr "Mos krijo një paketë tar burimi, e dobishme kur testohet një montim" + +#: ../fdroidserver/stats.py +msgid "Don't do anything logs-related" +msgstr "Mos bëj gjë që lidhet me regjistrat" + +#: ../fdroidserver/build.py +msgid "Don't refresh the repository, useful when testing a build with no internet connection" +msgstr "Mos rifresko depon, e dobishme kur testohet një montim pa lidhje internet" + +#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/upload.py +msgid "Don't use rsync checksums" +msgstr "Mos përdorni checksum-e rsync-u" + +#: ../fdroid +msgid "Download complete mirrors of small repos" +msgstr "Shkarko pasqyra të plota deposh të vogla" + +#: ../fdroidserver/stats.py +msgid "Download logs we don't have" +msgstr "Shkarkoni regjistra që s’i kemi" + +#: ../fdroidserver/common.py +msgid "Downloading the repository already failed once, not trying again." +msgstr "Shkarkimi i depos dështoi një herë, nuk po riprovohet." + +#: ../fdroidserver/verify.py +#, python-brace-format +msgid "Downloading {url} failed. {error}" +msgstr "Shkarkimi i {url} dështoi. {error}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Duplicate build recipe found for versionCode {versionCode} in {linedesc}" +msgstr "U gjet përsëdytje recete montimi për versionCode {versionCode} te {linedesc}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Duplicate link in '{field}': {url}" +msgstr "Lidhje e përsëdytur te '{field}': {url}" + +#: ../fdroid +msgid "Dynamically scan APKs post build" +msgstr "Skano dinamikisht APK-ra pas montimi" + +#: ../fdroidserver/mirror.py +msgid "" +"ERROR: this command should never be used to mirror f-droid.org!\n" +"A full mirror of f-droid.org requires more than 200GB." +msgstr "" +"GABIM: ky urdhër s’duhet përdorur kurrë për krijimin e një pasqyre të f-droid.org!\n" +"Një pasqyrë e plotë e f-droid.org lyp më tepër se 200GB." + +#: ../fdroidserver/nightly.py +msgid "ERROR: unsupported CI type, patches welcome!" +msgstr "GABIM: lloj CI i pambuluar, arnimet janë të mirëpritura!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Empty build flag at {linedesc}" +msgstr "Flamurkë e zbrazët montimi te {linedesc}" + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"Enter the path to the Android SDK (%s) here:\n" +"> " +msgstr "" +"Jepni shtegun për te Android SDK (%s) këtu:\n" +"> " + +#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/upload.py +#, python-format +msgid "Error while attempting to publish log: %s" +msgstr "Gabim gjatë përpjekjes për botim regjistri: %s" + +#: ../fdroidserver/import.py +msgid "Error while getting repo address" +msgstr "Gabim teksa merrej adresë depoje" + +#: ../fdroid +msgid "Extract signatures from APKs" +msgstr "Përfto nënshkrime prej APK-sh" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Failed fetching signatures for '{apkfilename}': {error}" +msgstr "S’u arrit të sillen nënshkrime për '{apkfilename}': {error}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed reading {path}: {error}" +msgstr "S’u arrit të lexohej {path}: {error}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed resizing {path}: {error}" +msgstr "S’u arrit të ripërmasohej {path}: {error}" + +#: ../fdroidserver/publish.py +msgid "Failed to align application" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Failed to create S3 bucket: {url}" +msgstr "S’u arrit të krijohej bucket S3: {url}" + +#: ../fdroidserver/common.py +msgid "Failed to get APK manifest information" +msgstr "S’u arrit të merren të dhëna manifesti APK-je" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, deleting {path}" +msgstr "S’u arrit të merren të dhëna apk-je, po fshihet {path}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, skipping {path}" +msgstr "S’u arrit të merren të dhëna apk-je, po anashkalohet {path}" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Failed to install '{apkfilename}' on {dev}: {error}" +msgstr "S’u arrit të instalohej '{apkfilename}' në {dev}: {error}" + +#: ../fdroidserver/publish.py ../fdroidserver/common.py +msgid "Failed to sign application" +msgstr "S’u arrit të nënshkruhej aplikacioni" + +#: ../fdroidserver/common.py +msgid "Failed to zipalign application" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Fetched buildserverid from VM: {buildserverid}" +msgstr "U soll buildserverid prej VM-je: {buildserverid}" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" +msgstr "U sollën nënshkrime për '{apkfilename}' -> '{sigdir}'" + +#: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py +#: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "Finished" +msgstr "Përfundoi" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID flag" +msgstr "Metodat e dhurimit përmes Flattr-i i takojnë flamurkës FlattrID" + +#: ../fdroidserver/lint.py +msgid "Forbidden HTML tags" +msgstr "Etiketa HTML të ndaluara" + +#: ../fdroidserver/build.py +msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." +msgstr "Detyro montim aplikacionesh të çaktivizuara, dhe vazhdon pavarësisht problemesh skanimi. E lejuar vetëm nën mënyrën testim." + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Force halting build after {0} sec timeout!" +msgstr "Detyro ndaljen e montimit pas {0} sek. mbarimi kohe!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" +msgstr "U gjet grafik \"{path}\" pa tejtëdhëna për aplikacionin \"{name}\"!" + +#: ../fdroidserver/common.py +msgid "Found invalid appids in arguments" +msgstr "U gjetën appid-e të pavlefshëm te argumente" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Found invalid versionCodes for some apps" +msgstr "U gjetën versionCodes të pavlefshëm për disa aplikacione" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Found multiple metadata files for {appid}" +msgstr "U gjetën kartela të shumta tejtëdhënash për {appid}" + +#: ../fdroidserver/index.py +msgid "Found multiple signing certificates for repository." +msgstr "U gjetën dëshmi të shumta nënshkrimi për depon." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found multiple signing certificates in {path}" +msgstr "U gjetën dëshmi të shumta nënshkrimi te {path}" + +#: ../fdroidserver/index.py +msgid "Found no signing certificates for repository." +msgstr "S’u gjetën dëshmi nënshkrimi për depon." + +#: ../fdroidserver/lint.py +#, python-format +msgid "Found non-file at %s" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Generated skeleton metadata for {appid}" +msgstr "U prodhuan tejtëdhëna skeleton për {appid}" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git checkout of '%s' failed" +msgstr "Veprimi “git checkout” për '%s' dështoi" + +#: ../fdroidserver/common.py +msgid "Git clean failed" +msgstr "Veprimi “git clean” dështoi" + +#: ../fdroidserver/common.py +msgid "Git fetch failed" +msgstr "Veprimi “git fetch” dështoi" + +#: ../fdroidserver/common.py +msgid "Git remote set-head failed" +msgstr "Veprimi “git remote set-head” dështoi" + +#: ../fdroidserver/common.py +msgid "Git reset failed" +msgstr "Veprimi “git reset” dështoi" + +#: ../fdroidserver/common.py +msgid "Git submodule sync failed" +msgstr "Veprimi “git submodule sync” dështoi" + +#: ../fdroidserver/common.py +msgid "Git submodule update failed" +msgstr "Veprimi “git submodule update” dështoi" + +#: ../fdroidserver/common.py +msgid "HTTPS must be used with Subversion URLs!" +msgstr "Me URL Subversion duhet përdorur HTTPS!" + +#: ../fdroidserver/index.py +msgid "Ignoring package without metadata: " +msgstr "Po shpërfillet paketë pa tejtëdhëna: " + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Ignoring stale cache data for {apkfilename}" +msgstr "Po shpërfillen të dhëna të ndenjura fshehtine për {apkfilename}" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Ignoring {ext} file at '{path}'" +msgstr "Po shpërfillet kartelë {ext} te '{path}'" + +#: ../fdroidserver/update.py +msgid "Include APKs that are signed with disabled algorithms like MD5" +msgstr "Përfshi APKra që janë nënshkruar me algoritme të çaktivizuar, bie fjala, me MD5" + +#: ../fdroidserver/common.py +msgid "Initialising submodules" +msgstr "Po gatiten nënmodule" + +#: ../fdroidserver/install.py +msgid "Install all signed applications available" +msgstr "Instalo krejt aplikacionet e nënshkruara që mundet" + +#: ../fdroid +msgid "Install built packages on devices" +msgstr "Instalo në pajisje paketat montuara" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s…" +msgstr "Po instalohet %s…" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}…" +msgstr "Po instalohet '{apkfilename}' në {dev}…" + +#: ../fdroid +msgid "Interact with the repo HTTP server" +msgstr "Ndërveproni me shërbyesin HTTP të depos" + +#: ../fdroidserver/update.py +msgid "Invalid APK" +msgstr "APK e pavlefshme" + +#: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid VercodeOperation: {field}" +msgstr "VercodeOperationi pavlefshëm: {field}" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid boolean '%s'" +msgstr "Bulean i pavlefshëm '%s'" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build flag at {line} in {linedesc}" +msgstr "Flamurkë e pavlefshme montimi te {line} në {linedesc}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build format: {value} in {name}" +msgstr "Format i pavlefshëm montimesh: {value} në {name}" + +#: ../fdroidserver/lint.py +msgid "Invalid bulleted list" +msgstr "Listë me toptha e pavlefshme" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" +msgstr "Etiketë e pavlefshme licence \"%s\"! Përdorni vetëm etiketa nga https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "Lidhje e pavlefshme - përdorni [http://lidhja_që_na_intereson Lidhje titull] ose [http://lidhja_që_na_intereson]" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid metadata in %s:%d" +msgstr "Tejtëdhëna të pavlefshme te %s:%d" + +#: ../fdroidserver/metadata.py +msgid "Invalid metadata in: " +msgstr "Tejtëdhëna të pavlefshme te: " + +#: ../fdroidserver/common.py +#, python-format +msgid "Invalid name for published file: %s" +msgstr "Emër i pavlefshëm për kartelë të botuar: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid package name {0}" +msgstr "Emër i pavlefshëm pakete {0}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid redirect to non-HTTPS: {before} -> {after} " +msgstr "Ridrejtim i pavlefshëm te non-HTTPS: {before} -> {after} " + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" +msgstr "versionCode i pavlefshëm: \"{versionCode}\" s’është numër i plotë!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature failed to verify: {path}" +msgstr "Dështoi verifikimi i nënshkrimit JAR: {path}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature verified: {path}" +msgstr "Nënshkrimi JAR u verifikua: {path}" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#: ../fdroidserver/mirror.py +msgid "Java JDK not found! Install in standard location or set java_paths!" +msgstr "S’u gjet Java JDK! Instalojeni në vendndodhje standarde ose caktoni java_paths!" + +#: ../fdroidserver/signindex.py +msgid "Java jarsigner not found! Install in standard location or set java_paths!" +msgstr "S’u gjet Java jarsigner! Instalojeni në vendndodhje standarde ose caktoni java_paths!" + +#: ../fdroidserver/lint.py +msgid "Javascript in HTML src attributes" +msgstr "Javascript në atribute src HTML" + +#: ../fdroidserver/init.py +msgid "Keystore for signing key:\t" +msgstr "Depo kyçesh për kyç nënshkrimi:\t" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgstr "Parashtrimi '{commit}' i përdorur së fundi duket si etiketë, por si Mënyrë Kontrolli Përditësimesh është '{ucm}'" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the LiberapayID flag" +msgstr "Metodat e dhurimit përmes Liberapay i takojnë flamurkës Liberapay" + +#: ../fdroidserver/rewritemeta.py +msgid "List files that would be reformatted" +msgstr "Paraqit kartela që do të riformatoheshin" + +#: ../fdroidserver/lint.py +msgid "Locale included in f-droid.org URL" +msgstr "Vendore e përfshirë te URL f-droid.org" + +#: ../fdroidserver/build.py +msgid "Make the build stop on exceptions" +msgstr "Bëje montimin të ndalet kur has përjashtime" + +#: ../fdroidserver/index.py +msgid "Malformed repository mirrors." +msgstr "Pasqyra depoje të keqformuara." + +#: ../fdroidserver/server.py +msgid "Malformed serverwebroot line:" +msgstr "Rresht serverwebroot i keqformuar:" + +#: ../fdroidserver/gpgsign.py +msgid "Missing output directory" +msgstr "Mungon drejtori përfundimesh" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Name '%s' is just the auto name - remove it" +msgstr "Emri '%s' është thjesht emër i automatizuar - hiqeni" + +#: ../fdroidserver/common.py +msgid "No 'config.py' found, using defaults." +msgstr "S’u gjet 'config.py', po përdoren parazgjedhjet." + +#: ../fdroidserver/common.py +msgid "No Android SDK found!" +msgstr "S’u gjet SDK Android!" + +#: ../fdroidserver/import.py +msgid "No android or kivy project could be found. Specify --subdir?" +msgstr "S’u gjet dot projekt android ose kivy. Të specifikohet --subdir?" + +#: ../fdroidserver/install.py +msgid "No attached devices found" +msgstr "S’u gjetën pajisje të bashkëngjitura" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "No commit specified for {versionName} in {linedesc}" +msgstr "Te {linedesc} s’ka parashtrim të specifikuar për {versionName}" + +#: ../fdroidserver/index.py +msgid "No fingerprint in URL." +msgstr "S’ka shenja gishtash te URL-ja." + +#: ../fdroidserver/common.py +msgid "No git submodules available" +msgstr "S’ka “git submodules”" + +#: ../fdroidserver/import.py +msgid "No information found." +msgstr "S’u gjetën të dhëna." + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is Free Software" +msgstr "S’ka nevojë të specifikohet që aplikacioni është Software i Lirë" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is for Android" +msgstr "S’ka nevojë të specifikohet që aplikacioni është për Android" + +#: ../fdroidserver/server.py +msgid "No option set! Edit your config.py to set at least one of these:" +msgstr "S’ka mundësi të ujdisur! Përpunoni config.py tuaj që të ujdisni të paktën një prej:" + +#: ../fdroidserver/common.py +msgid "No packages specified" +msgstr "S’u specifikuan paketa" + +#: ../fdroidserver/install.py +#, python-format +msgid "No signed apk available for %s" +msgstr "S’ka të gatshme apk të nënshkruara për %s" + +#: ../fdroidserver/install.py +msgid "No signed output directory - nothing to do" +msgstr "S’ka drejtori output-i të nënshkruar - s’ka ç’bëhet" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "No signing certificates found in {path}" +msgstr "S’u gjetën dëshmi nënshkrimi te {path}" + +#: ../fdroidserver/common.py +#, python-format +msgid "No such package: %s" +msgstr "S’ka paketë të tillë: %s" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No such versionCode {versionCode} for app {appid}" +msgstr "S’ka versionCode {versionCode} për aplikacionin {appid}" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +msgid "No unsigned directory - nothing to do" +msgstr "S’ka drejtori të panënshkruar - s’ka ç’bëhet" + +#: ../fdroidserver/signindex.py +msgid "Nothing to do" +msgstr "S’ka ç’bëhet" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Nothing to do for {appid}." +msgstr "S’ka ç’bëhet për {appid}." + +#: ../fdroidserver/init.py +msgid "Now set these in config.py:" +msgstr "Tani, ujdisini këto te config.py:" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "OBB file has newer versionCode({integer}) than any APK:" +msgstr "Kartela OBB ka versionCode({integer}) më të ri se sa cilado APK:" + +#: ../fdroidserver/update.py +msgid "OBB filename must start with \"main.\" or \"patch.\":" +msgstr "Emri i kartelës OBB duhet të fillojë me \"main.\" ose \"patch.\":" + +#: ../fdroidserver/update.py +msgid "OBB's packagename does not match a supported APK:" +msgstr "packagename i OBB-së nuk përputhet me ndonjë APK të mbuluar:" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Old APK signature failed to verify: {path}" +msgstr "S’u arrit të verifikohej nënshkrim i vjetër APK-je: {path}" + +#: ../fdroid +msgid "Old, deprecated name for fdroid deploy" +msgstr "Emër i vjetër, i nxjerrë nga përdorimi për sendërtim fdroid" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Only PNG and JPEG are supported for graphics, found: {path}" +msgstr "Si formate grafike mbulohen vetëm PNG dhe JPEG, u gjet: {path}" + +#: ../fdroidserver/checkupdates.py +msgid "Only print differences with the Play Store" +msgstr "Shtyp vetëm dallimet me Play Store-in" + +#: ../fdroidserver/checkupdates.py +msgid "Only process apps with auto-updates" +msgstr "Kryeje vetëm për aplikacione me vetëpërditësime" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Options" +msgstr "Mundësi" + +#: ../fdroidserver/verify.py +msgid "Output JSON report to file named after APK." +msgstr "Hidhe raportin JSON te kartelë e emërtuar sipas APK-sh." + +#: ../fdroidserver/import.py +msgid "Overall license of the project." +msgstr "Licenca e përgjithshme e projektit." + +#: ../fdroidserver/dscanner.py +msgid "Override path for repo APKs (default: ./repo)" +msgstr "Shteg anashkalimi për APK-ra depoje (parazgjedhje: ./repo)" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" +msgstr "Po anashkalohet versionName i zbrazët te {apkfilename} prej tejtëdhënash: {version}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Parsing manifest at '{path}'" +msgstr "Po përtypet manifest te '{path}'" + +#: ../fdroidserver/common.py +msgid "Password required with username" +msgstr "Me emrin e përdoruesit lypset fjalëkalim" + +#: ../fdroidserver/import.py +msgid "Path to main Android project subdirectory, if not in root." +msgstr "Shteg për te nëndrejtoria e projektit kryesor Android, në mos qoftë rrënja." + +msgid "Path to main android project subdirectory, if not in root." +msgstr "Shteg për te nëndrejtoria e projektit kryesor android, në mos qoftë rrënja." + +#: ../fdroidserver/init.py +msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)" +msgstr "Shteg për te SDK Android-i (ndonjëherë caktuar te ANDROID_HOME)" + +#: ../fdroidserver/btlog.py +msgid "Path to the git repo to use as the log" +msgstr "Shteg për te depo git për t’u përdorur si regjistri" + +#: ../fdroidserver/init.py +msgid "Path to the keystore for the repo signing key" +msgstr "Shteg për te depo kyçesh për kyçin e nënshkrimit të depos" + +#: ../fdroidserver/dscanner.py +msgid "Prepare Drozer to run a scan" +msgstr "Përgatite Drozer-in të bëjë një skanim" + +msgid "Prepare drozer to run a scan" +msgstr "Përgatite Drozer-in të kryejë një skanim" + +#: ../fdroidserver/nightly.py +msgid "Print the secret variable to the terminal for easy copy/paste" +msgstr "Shtype ndryshoren e fshehtë te terminali, për kopjim/ngjitje të kollajtë" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Problem with description of {appid}: {error}" +msgstr "Problem me përshkrimin e {appid}: {error}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Problem with xml at '{path}'" +msgstr "Problem me xml-në te '{path}'" + +#: ../fdroidserver/checkupdates.py +msgid "Process auto-updates" +msgstr "Kryeji vetëpërditësimet" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#, python-brace-format +msgid "Processing {apkfilename}" +msgstr "Po përpunohet {apkfilename}" + +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#, python-brace-format +msgid "Processing {appid}" +msgstr "Po përpunohet {appid}" + +#: ../fdroidserver/update.py +msgid "Produce human-readable XML/JSON for index files" +msgstr "Për kartela treguesish, prodho XML/JSON të lexueshëm nga syri njerëzor" + +#: ../fdroidserver/update.py +msgid "Produce human-readable index.xml" +msgstr "Prodho index.xml të lexueshme nga syri njerëzor" + +#: ../fdroidserver/import.py +msgid "Project URL to import from." +msgstr "URL prej nga të importohet projekt." + +#: ../fdroidserver/lint.py +msgid "Punctuation should be avoided" +msgstr "Pikësimi duhet shmangur" + +#: ../fdroidserver/btlog.py +msgid "Push the log to this git remote repository" +msgstr "Kryej push të regjistrit te kjo depo e largët git" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing binary transparency log to {url}" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing to {url}" +msgstr "" + +#: ../fdroid +msgid "Quickly start a new repository" +msgstr "Filloni shpejt e shpejt një depo të re" + +#: ../fdroid +msgid "Read all the metadata files and exit" +msgstr "Lexo krejt kartelat e tejtëdhënave dhe dil" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading '{config_file}'" +msgstr "Po lexohet '{config_file}'" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading minSdkVersion failed: \"{apkfilename}\"" +msgstr "Leximi i minSdkVersion dështoi: \"{apkfilename}\"" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" +msgstr "Leximi i packageName/versionCode/versionName dështoi, APK e pavlefshme: '{apkfilename}'" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Reading {apkfilename} from cache" +msgstr "Po lexohet {apkfilename} prej fshehtine" + +#: ../fdroidserver/stats.py +msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." +msgstr "Rinjehso statistika përmbledhëse - përdoreni kur janë bërë ndryshime të cilat mund të bënin të pavlefshme të dhëna të vjetra të ruajtura në fshehtinë." + +#: ../fdroidserver/common.py +msgid "Removing specified files" +msgstr "Po hiqen kartelat e treguara" + +#: ../fdroidserver/update.py +msgid "Rename APK files that do not match package.name_123.apk" +msgstr "Riemërtoni kartelat APK që nuk përputhen me package.name_123.apk" + +#: ../fdroidserver/update.py +msgid "Report on build data status" +msgstr "Raport mbi gjendje të dhënash montimi" + +#: ../fdroidserver/build.py +msgid "Reset and create a brand new build server, even if the existing one appears to be ok." +msgstr "Zeroje dhe krijo një shërbyes montimesh të ri fringo, edhe nëse ai ekzistuesi duket të jetë në rregull." + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Resigning {apkfilename} with provided debug.keystore" +msgstr "Po rinënshkruhet {apkfilename} me debug.keystore e furnizuar" + +#: ../fdroidserver/update.py +msgid "Resize all the icons exceeding the max pixel size and exit" +msgstr "Ripërmaso krejt ikonat që tejkalojnë madhësinë maksimum në piksel dhe dil" + +#: ../fdroidserver/common.py +msgid "Restrict output to warnings and errors" +msgstr "Kufizoje output-in në sinjalizime dhe gabime" + +#: ../fdroid +msgid "Rewrite all the metadata files" +msgstr "Rishkruaj krejt kartelat e tejtëdhënave" + +#: ../fdroidserver/rewritemeta.py +msgid "Rewrite to a specific format: " +msgstr "Rishkruajeni në një format specifik: " + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}'" +msgstr "Po rishkruhet '{appid}'" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}' to '{path}'" +msgstr "Po rishkruhet '{appid}' te '{path}'" + +#: ../fdroidserver/checkupdates.py +msgid "Run on git repo that has uncommitted changes" +msgstr "Xhirojeni në depo git që ka ndryshime të padepozituara te dega vendore" + +#: ../fdroidserver/lint.py +msgid "Run rewritemeta to fix formatting" +msgstr "Që të ndreqet formatimi, xhironi rewritemeta" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Running first pass with MD5 checking disabled" +msgstr "Po xhirohet kalimi i parë me kontrollin MD5 të çaktivizuar" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Running wget in {path}" +msgstr "Po xhirohet wget te {path}" + +#: ../fdroidserver/dscanner.py +msgid "Scan only the latest version of each package" +msgstr "Skano vetëm versionin më të ri të çdo pakete" + +#: ../fdroid +msgid "Scan the source code of a package" +msgstr "Skanoni kodin burim të një pakete" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:" +msgstr "Skaneri gjeti {count} probleme te {appid}:" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:{versionCode}:" +msgstr "Kontrolli gjeti {count} probleme te {appid}:{versionCode}:" + +#: ../fdroidserver/build.py +msgid "Scanner found {} problem" +msgid_plural "Scanner found {} problems" +msgstr[0] "Skaneri gjeti {} problem" +msgstr[1] "Skaneri gjeti {} probleme" + +#: ../fdroidserver/common.py +msgid "Set clock to that time using:" +msgstr "Vëre sahatin në atë kohë duke përdorur:" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Set open file limit to {integer}" +msgstr "Si kufi hapjeje kartele cakto {integer}" + +#: ../fdroid +msgid "Set up an app build for a nightly build repo" +msgstr "Ujdisni një montim aplikacioni për një depo montimesh të përnatshme" + +#: ../fdroidserver/build.py +msgid "Setting open file limit failed: " +msgstr "Dështoi ujdisje kufiri hapjesh kartelash: " + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Setting {0} sec timeout for this build" +msgstr "Po ujdiset mbarim kohe {0} sekonda për këtë montim" + +#: ../fdroidserver/build.py +msgid "Setup an emulator, install the APK on it and perform a Drozer scan" +msgstr "Ujdisni një emulues, instaloni në të APK-në dhe kryeni një skanim Drozer" + +msgid "Setup an emulator, install the apk on it and perform a drozer scan" +msgstr "Ujdisni një emulues, instaloni në të APK-në dhe kryeni një skanim Drozer" + +#: ../fdroid +msgid "Sign and place packages in the repo" +msgstr "Nënshkruani dhe vendosni paketa te depoja" + +#: ../fdroid +msgid "Sign indexes created using update --nosign" +msgstr "Tregues nënshkrimi të krijuar duke përdorur “update --nosign”" + +#: ../fdroidserver/build.py +msgid "Skip scanning the source code for binaries and other problems" +msgstr "Anashkalo skanimin e kodit burim për dyorë dhe probleme të tjera" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping '{apkfilename}' with invalid signature!" +msgstr "Po anashkalohet '{apkfilename}' me nënshkrim i pavlefshëm!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping index generation for {appid}" +msgstr "Po anashkalohet prodhim treguesi për {appid}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping {apkfilename} with invalid signature!" +msgstr "Po anashkalohet {apkfilename} me nënshkrim të pavlefshëm!" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: disabled" +msgstr "Po anashkalohet {appid}: e çaktivizuar" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: no builds specified" +msgstr "Po anashkalohet {appid}: s’u specifikuan montime" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify a local folder to sync the repo to" +msgstr "Specifikoni një dosje vendore te e cila të njëkohësohet depoja" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify an identity file to provide to SSH for rsyncing" +msgstr "Specifikoni një kartelë identiteti për t’ia furnizuar SSH-s për njëkohësim me rsync-un" + +#: ../fdroidserver/build.py +msgid "Specify that we're running on the build server" +msgstr "Specifiko që po xhirojmë te shërbyesi i montimeve" + +#: ../fdroidserver/nightly.py +msgid "Specify which debug keystore file to use." +msgstr "Specifikoni cila kartelë depoje kyçesh diagnostikimesh të përdoret." + +#: ../fdroidserver/common.py +msgid "Spew out even more information than normal" +msgstr "U la të rrjedhë edhe më tepër informacion se sa normalisht" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Striping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Summary '%s' is just the app's name" +msgstr "Përmbledhja '%s' është thjesht emri i aplikacionit" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Summary of length {length} is over the {limit} char limit" +msgstr "Përmbledhja me gjatësi {length} është mbi kufirin prej {limit} shenjash" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "System clock is older than date in {path}!" +msgstr "Ora e sistemit është më herët se sa data në {path}!" + +#: ../fdroidserver/build.py +msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." +msgstr "Mënyra testim - hidhe output-in vetëm te drejtoria tmp, dhe monto përherë, edhe nëse output-i ekziston tashmë." + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "The OBB version code must come after \"{name}.\":" +msgstr "Kodi për versionin OBB duhet të vijë pas \"{name}.\":" + +#: ../fdroidserver/btlog.py +msgid "The base URL for the repo to log (default: https://f-droid.org)" +msgstr "URL bazë për depon për regjistrim (parazgjedhje: https://f-droid.org)" + +#: ../fdroidserver/mirror.py +msgid "The directory to write the mirror to" +msgstr "Drejtoria ku të shkruhet pasqyra" + +#: ../fdroidserver/nightly.py +msgid "The file to be included in the repo (path or glob)" +msgstr "Kartela që duhet përfshirë te depoja (shteg ose shenjë e gjithëpushtetshme)" + +#: ../fdroidserver/server.py +msgid "The only commands currently supported are 'init' and 'update'" +msgstr "Urdhrat e vetme të mbuluara janë 'init' dhe 'update'" + +#: ../fdroidserver/index.py +msgid "The repository's fingerprint does not match." +msgstr "Shenjat e gishtave të depos nuk përputhen." + +#: ../fdroidserver/common.py +msgid "The repository's index could not be verified." +msgstr "Treguesi i depos s’u verifikua dot." + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "The root dir for local_copy_dir \"{path}\" does not exist!" +msgstr "Drejtoria rrënjë për local_copy_dir \"{path}\" s’ekziston!" + +#: ../fdroidserver/publish.py +msgid "There is a keyalias collision - publishing halted" +msgstr "Ka një përplasje keyalias-i - botimi u ndal" + +#: ../fdroidserver/import.py +#, python-format +msgid "This repo already has local metadata: %s" +msgstr "Kjo depo ka tashmë tejtëdhëna vendore: %s" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" +msgstr "Për të përdorur awsbucket, te config.py duhen ujdisur edhe awssecretkey dhe awsaccesskey!" + +#: ../fdroidserver/lint.py +msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgstr "UCM është ujdisur, por duket sikur checkupdates s’është xhiruar ende" + +#: ../fdroidserver/lint.py +msgid "URL shorteners should not be used" +msgstr "S’duhen përdorur shkurtues URL-sh" + +#: ../fdroidserver/metadata.py +msgid "URL title is just the URL, use brackets: [URL]" +msgstr "Titulli i URL-së është thjesht URL-ja, përdorni kllapa: [URL]" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "URL {url} in Description: {error}" +msgstr "URL {url} te Përshkrim: {error}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unexpected text on same line as {field} in {linedesc}" +msgstr "Tekst i papritur në të njëjtin rresht me {field} te {linedesc}" + +#: ../fdroid +msgid "Unknown exception found!" +msgstr "U gjet përjashtim i panjohur!" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Unknown file '{filename}' in build '{versionName}'" +msgstr "Kartelë e panjohur '{filename}' te montimi '{versionName}'" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Unknown metadata format: %s" +msgstr "Format i panjohur tejtëdhënash: %s" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path}" +msgstr "Format i panjohur tejtëdhënash: {path}" + +#: ../fdroidserver/common.py +msgid "Unknown version of aapt, might cause problems: " +msgstr "Version i panjohur i aapt-së, mund të sjellë probleme: " + +#: ../fdroidserver/lint.py +msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "Lidhje e cila është hequr nga lidhje - përdorni [http://lidhja_që_na_intereson Lidhje titull] ose [http://lidhja_që_na_intereson]" + +#: ../fdroidserver/lint.py +msgid "Unnecessary leading space" +msgstr "Hapësirë e panevojshme në fillim" + +#: ../fdroidserver/lint.py +msgid "Unnecessary trailing space" +msgstr "Hapësirë e panevojshme në fund" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised app field '{fieldname}' in '{path}'" +msgstr "Fushë aplikacioni jo e pranuar '{fieldname}' te '{path}'" + +#: ../fdroidserver/metadata.py +msgid "Unrecognised app field: " +msgstr "Fushë aplikacioni jo e pranuar: " + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised build flag '{build_flag}' in '{path}'" +msgstr "Flamurkë e jo e pranuar montimi '{build_flag}' te '{path}'" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised field '{field}' in {linedesc}" +msgstr "Fushë jo e pranuar '{field}' te {linedesc}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported file type \"{extension}\" for repo graphic" +msgstr "Lloj i pambuluar kartele \"{extension}\" për grafik depoje" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported graphics file found: {path}" +msgstr "U gjet kartelë e pambuluar grafike: {path}" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Unsupported metadata format, use: --to [{supported}]" +msgstr "Format tejtëdhënash i pambuluar, përdorni: --to [{supported}]" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]" +msgstr "] e papërfunduar" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]]" +msgstr "]] të papërfunduara" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated build in {name}" +msgstr "Montim i papërfunduar në {name}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated continuation in {name}" +msgstr "Vazhdim i papërfunduar në {name}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused extlib at %s" +msgstr "extlib i papërdorur te %s" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused file at %s" +msgstr "Kartelë e papërdorur te %s" + +#: ../fdroidserver/lint.py +msgid "Update Check Name is set to the known app id - it can be removed" +msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" + +#: ../fdroid +msgid "Update repo information for new packages" +msgstr "Përditësoni të dhëna depoje për paketa të reja" + +#: ../fdroid +msgid "Update the binary transparency log for a URL" +msgstr "Përditësoni regjistrin e transparencës së dyorit për një URL" + +#: ../fdroid +msgid "Update the stats of the repo" +msgstr "Përditëso statistikat e depos" + +#: ../fdroidserver/update.py ../fdroidserver/build.py +msgid "Update the wiki" +msgstr "Përditësoni wiki-n" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "UpdateCheckData has invalid URL: {url}" +msgstr "UpdateCheckData ka URL të pavlefshme: {url}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must use HTTPS URL: {url}" +msgstr "UpdateCheckData duhet të përdorë URL HTTPS: {url}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData not a valid URL: {url}" +msgstr "UpdateCheckData s’është URL e vlefshme: {url}" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Usage" +msgstr "Përdorim" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "Usage: %s\n" +msgstr "Përdorim: %s\n" + +#: ../fdroidserver/lint.py +msgid "Use /HEAD instead of /master to point at a file in the default branch" +msgstr "Për të treguar një kartelë te dega parazgjedhje, përdorni /HEAD, në vend se /master" + +#: ../fdroidserver/update.py +msgid "Use `fdroid update -c` to create it." +msgstr "Përdor `fdroid update -c` për ta krijuar." + +#: ../fdroidserver/build.py +msgid "Use build server" +msgstr "Përdor shërbyes montimesh" + +#: ../fdroidserver/update.py +msgid "Use date from APK instead of current time for newly added APKs" +msgstr "Për APK-ra të shtuara rishtazi, përdor datë prej APK-je, në vend se kohën e tanishme" + +msgid "Use date from apk instead of current time for newly added apks" +msgstr "Për APK-ra të shtuara rishtazi, përdor datë prej APK-je, në vend se të kohës së tanishme" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using \"{path}\" for configuring s3cmd." +msgstr "Po përdoret \"{path}\" për formësim të s3cmd." + +#: ../fdroidserver/common.py +msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" +msgstr "Po përdoret jarsigner Java, nuk rekomandohet për verifikim APK-sh! Përdorni apksigner" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Using androguard from \"{path}\"" +msgstr "Po përdoret androguard prej \"{path}\"" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Using existing keystore \"{path}\"" +msgstr "Po përdoret depo ekzistuese kyçesh \"{path}\"" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using s3cmd to sync with: {url}" +msgstr "Po përdoret s3cmd për njëkohësim me: {url}" + +#: ../fdroid +msgid "Valid commands are:" +msgstr "Urdhrat e vlefshëm janë:" + +#: ../fdroidserver/verify.py +msgid "Verify against locally cached copy rather than redownloading." +msgstr "Verifikoje ndaj një kopjeje të ruajtur lokalisht në fshehtinë, në vend se ta rishkarkosh." + +#: ../fdroid +msgid "Verify the integrity of downloaded packages" +msgstr "Verifikoni integritetin e paketave të shkarkuara" + +#: ../fdroidserver/index.py +msgid "Verifying index signature:" +msgstr "Po verifikohet nënshkrim treguesi:" + +#: ../fdroid +msgid "Warn about possible metadata errors" +msgstr "Sinjalizo rreth gabimesh të mundshëm tejtëdhënash" + +#: ../fdroidserver/update.py +msgid "When configured for signed indexes, create only unsigned indexes at this stage" +msgstr "Kur është formësuar për tregues të nënshkruar, në këtë fazë krijo vetëm tregues të panënshkruar" + +msgid "X.509 'Distiguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/init.py +msgid "X.509 'Distinguished Name' used when generating keys" +msgstr "X.509 'Distinguished Name' i përdorur teksa prodhoheshin kyçe" + +#: ../fdroidserver/common.py +msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" +msgstr "Mund të përdorni ANDROID_HOME që të caktoni shtegun për te SDK-ja juaj, domethënë:" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "adding IdentityFile to {path}" +msgstr "po shtohet IdentityFile te {path}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "adding to {name}: {path}" +msgstr "po shtohet te {name}: {path}" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ambiguous option: %(option)s could match %(matches)s" +msgstr "mundësi e dykuptimtë: %(option)s mund të përputhej me %(matches)s" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "ambiguous option: %s (%s?)" +msgstr "mundësi e dykuptimtë: %s (%s?)" + +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +msgid "applicationId in the form APPID" +msgstr "applicationId në formën e APPID" + +#: ../fdroidserver/checkupdates.py +msgid "applicationId to check for updates" +msgstr "applicationId për të cilin të kontrollohet për përditësime" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/dscanner.py ../fdroidserver/build.py +#: ../fdroidserver/scanner.py ../fdroidserver/install.py +msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId me versionCode opsional në formën APPID[:VERCODE]" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "argument \"-\" with mode %r" +msgstr "argument \"-\" me mënyrën %r" + +#: ../fdroidserver/nightly.py +msgid "attempting bare ssh connection to test deploy key:" +msgstr "po tentohet lidhje ssh e zhveshur, për të testuar kyç sendërtimesh:" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "can't open '%s': %s" +msgstr "s’hapet dot '%s': %s" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "cannot have multiple subparser arguments" +msgstr "s’mund të kihen argumente të shumtë për subparser" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "cannot merge actions - two groups are named %r" +msgstr "s’mund të përzihen veprimet - ka dy grupe të quajtur %r" + +#: ../fdroidserver/nightly.py +msgid "cannot publish update, did you set the deploy key?" +msgstr "s’mund të botohet përditësim, e ujdisët kyçin e sendërtimit?" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "cloning {url}" +msgstr "po klonohet {url}" + +#: ../fdroidserver/server.py +msgid "command to execute, either 'init' or 'update'" +msgstr "urdhër për t’u ekzekutuar, ose 'init', ose 'update'" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "complex" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "conflicting option string: %s" +msgid_plural "conflicting option strings: %s" +msgstr[0] "varg mundësie me përplasje: %s" +msgstr[1] "vargje mundësish me përplasje: %s" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "copying {apkfilename} into {path}" +msgstr "po kopjohet {apkfilename} te {path}" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "created {path}" +msgstr "u krijua {path}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "deleting: repo/{apkfilename}" +msgstr "po fshihet: repo/{apkfilename}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed build logs to '{path}'" +msgstr "u vunë regjistra montimi te '{path}'" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "dest= is required for options like %r" +msgstr "dest= është e domosdoshme për mundësi si %r" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "expected %s argument" +msgid_plural "expected %s arguments" +msgstr[0] "pritej %s argument" +msgstr[1] "priteshin %s argumente" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at least one argument" +msgstr "pritej e pakta një argument" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at most one argument" +msgstr "pritej e shumta një argument" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected one argument" +msgstr "pritej një argument" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "failed deploying build logs to '{path}'" +msgstr "s’u arrit të hidhen regjistrat e montimeve te '{path}'" + +#: ../fdroid +msgid "fdroid [-h|--help|--version] []" +msgstr "fdroid [-h|--help|--version] []" + +#: ../fdroid +msgid "fdroid [] [-h|--help|--version|]" +msgstr "fdroid [] [-h|--help|--version|]" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "floating-point" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force errors to be warnings, or ignore" +msgstr "bëji detyrimisht gabimet të jenë sinjalizime, ose shpërfilli" + +#: ../fdroidserver/metadata.py +msgid "force metadata errors (default) to be warnings, or to be ignored." +msgstr "bëji gabimet e tejtëdhënave (parazgjedhje) të jenë sinjalizime, ose të shpërfillen." + +#: ../fdroidserver/common.py +msgid "git svn clone failed" +msgstr "veprimi “git svn clone” dështoi" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ignored explicit argument %r" +msgstr "u shpërfill argumenti eksplicit %r" + +#: ../fdroidserver/index.py +msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" +msgstr "index-v1 duhet të ketë një nënshkrim, përdorni `fdroid signindex` për ta krijuar!" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "integer" +msgstr "numër i plotë" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid %(type)s value: %(value)r" +msgstr "vlerë %(type)s e pavlefshme: %(value)r" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid choice: %(value)r (choose from %(choices)s)" +msgstr "zgjedhje e pavlefshme: %(value)r (zgjidhni nga %(choices)s)" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid conflict_resolution value: %r" +msgstr "vlerë e pavlefshme conflict_resolution: %r" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" +msgstr "varg i pavlefshëm mundësie %(option)r: duhet të fillojë me një shenjë %(prefix_chars)r" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" +msgstr "local_copy_dir does s’mbaron me \"fdroid\", ndoshta kishit në mendje: \"{path}\"" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be an absolute path!" +msgstr "local_copy_dir duhet të jetë një shteg absolut!" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be directory, not a file!" +msgstr "local_copy_dir duhet të jetë një drejtori, jo një kartelë!" + +#: ../fdroidserver/index.py +#, python-format +msgid "mirror '%s' does not end with 'fdroid'!" +msgstr "pasqyra '%s' s’përfundon me 'fdroid'!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "mutually exclusive arguments must be optional" +msgstr "argumentet që përjashtojnë njëri-tjetrin duhet të jenë opsionalë" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "no \"icon\" in {appid}" +msgstr "s’ka \"icon\" te {appid}" + +#: ../fdroidserver/signatures.py +msgid "no APK supplied" +msgstr "s’u dha APK" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "no such option: %s" +msgstr "s’ka mundësi të tillë: %s" + +#: ../fdroid +msgid "no version info found!" +msgstr "s’u gjetën të dhëna versioni!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "not allowed with argument %s" +msgstr "e palejuar me argumentin %s" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "one of the arguments %s is required" +msgstr "një nga argumentet %s është i domosdoshëm" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "only accepts strings, lists, and tuples" +msgstr "prano vetëm vargje, lista dhe dyshe" + +#: ../fdroidserver/install.py +#, python-format +msgid "option %s: If you really want to install all the signed apps, use --all" +msgstr "mundësi %s: Nëse doni vërtet të instaloni krejt aplikacionet e nënshkruar, përdorni --all" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid %s value: %r" +msgstr "mundësi %s: vlerë %s e pavlefshme: %r" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid choice: %r (choose from %s)" +msgstr "mundësia %s: zgjedhje e pavlefshme: %r (zgjidhni nga %s)" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s not recognized" +msgstr "mundësi -%s jo e pranuar" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s requires argument" +msgstr "mundësia -%s lyp argument" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s must not have an argument" +msgstr "mundësia --%s s’duhet të ketë një argument" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not a unique prefix" +msgstr "mundësia --%s s’është parashtesë unike" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not recognized" +msgstr "mundësi --%s e papranuar" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s requires argument" +msgstr "mundësia --%s lyp argument" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "optional arguments" +msgstr "argumente opsionalë" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "overwriting existing {path}" +msgstr "po mbishkruhet {path} ekzistues" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "positional arguments" +msgstr "argumente pozicionalë" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" +msgstr "refuzo shkarkim përmes lidhjeje HTTP të pasigurt (përdorni HTTPS ose specifikoni --no-https-check): {apkfilename}" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" +msgstr "mos pranon shkarkim përmes lidhjeje http të pasigurt (përdorni https ose specifikoni --no-https-check): {apkfilename}" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "s3cmd sync indexes {path} to {url} and delete" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "show program's version number and exit" +msgstr "shfaq numër versioni programi dhe dil" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.5/optparse.py +#: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py +msgid "show this help message and exit" +msgstr "shfaq këtë mesazh ndihme dhe dil" + +#: ../fdroidserver/signatures.py +msgid "signed APK, either a file-path or HTTPS URL." +msgstr "APK e nënshkruar, ose një shteg-kartele, ose URL HTTPS." + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: log content is empty" +msgstr "anashkalo sendërtim regjistrash të plotë montimesh: lëndë e regjistrit është e zbrazët" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: not enabled in config" +msgstr "anashkalo krijim regjistrash të plotë montimi: e paaktivizuar te formësimi" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "skipping source tarball: {path}" +msgstr "po anashkalohet paketë tar burimi: {path}" + +#: ../fdroidserver/lint.py +msgid "srclibs missing name and/or @" +msgstr "srclibs-it i mungon emër dhe/ose @" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" +msgstr "vlera '{timestamp}' e dhënë për vulën kohore s’është vulë kohore Unix" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "the following arguments are required: %s" +msgstr "argumentet vijuese janë të domosdoshëm: %s" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unexpected option string: %s" +msgstr "varg i papritur mundësie: %s" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unknown parser %(parser_name)r (choices: %(choices)s)" +msgstr "përtypës i panjohur %(parser_name)r (choices: %(choices)s)" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unrecognized arguments: %s" +msgstr "argumente të papranuar: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "unsafe permissions on '{config_file}' (should be 0600)!" +msgstr "leje jo të parrezikshme mbi '{config_file}' (duhet të ishin 0600)!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid +#: /usr/lib/python3.7/argparse.py +msgid "usage: " +msgstr "përdorimi: " + +#: ../fdroid +msgid "usage: fdroid [-h|--help|--version] []" +msgstr "përdorimi: fdroid [-h|--help|--version] []" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "using Apache libcloud to sync with {url}" +msgstr "po përdoret Apache libcloud për njëkohësim me {url}" + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "{0} app, {1} key aliases" +msgid_plural "{0} apps, {1} key aliases" +msgstr[0] "{0} aplikacion, {1} aliase kyçi" +msgstr[1] "{0} aplikacione, {1} aliase kyçi" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} ({appid}) has no metadata!" +msgstr "{apkfilename} ({appid}) s’ka tejtëdhëna!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" +msgstr "{apkfilename} ka shumë kartela {name}, duket si rreng me Kyçin e Përgjithshëm!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " +msgstr "AndroidManifest.xml e {apkfilename} ka një datë të gabuar: " + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using package name instead." +msgstr "{appid} s’ka emër! Në vend të tij po përdoret emër pakete." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android Package Name!" +msgstr "{appid} prej {path} s’është Emër i vlefshëm Pakete Android!" + +#: ../fdroidserver/metadata.py ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Java Package Name!" +msgstr "{appid} prej {path} s;është Emër i vlefshëm Pakete Java!" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{appid} is missing {name}" +msgstr "{appid} i mungon {name}" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: Unknown extlib {path} in build '{versionName}'" +msgstr "{appid}: extlib i panjohur {path} te montimi '{versionName}'" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "{appid}: no builds specified, running on current source state" +msgstr "{appid}: s’u specifikuan montime, po xhirohet me gjendjen e tanishme të burimit" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" +msgstr "{appid}: {field} duhet të jetë një '{type}', po është një '{fieldtype}!'" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" +msgstr "{appid}: {field} duhet të jetë një '{type}', por është një '{fieldtype}'!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{field} not terminated in {name}" +msgstr "{field} e papërfunduar te {name}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{name} \"{path}\" does not exist! Correct it in config.py." +msgstr "{name} \"{path}\" s’ekziston! Ndreqeni te config.py." + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "{path} does not exist! Create it by running:" +msgstr "{path} s’ekziston! Krijojeni duke xhiruar:" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" +msgstr "{path} ka \"{pattern}\" të gabuar nënshkrimi kartele, ka gjasa të jetë rreng Janus!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} is zero size!" +msgstr "{path} është me madhësi zero!" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{url} does not end with \"fdroid\", check the URL path!" +msgstr "{url} s’përfundon me \"fdroid\", kontrolloni shtegun e URL-së!" + +#: ../fdroidserver/build.py +msgid "{} build failed" +msgid_plural "{} builds failed" +msgstr[0] "Dështoi {} montim" +msgstr[1] "Dështuan {} montime" + +#: ../fdroidserver/build.py +msgid "{} build succeeded" +msgid_plural "{} builds succeeded" +msgstr[0] "{} doli me sukses" +msgstr[1] "{} dolën me sukses" From 99822a2b4f195adb0e044b47050be49d7301a1fc Mon Sep 17 00:00:00 2001 From: Leviatansan21 Date: Thu, 1 Oct 2020 11:00:41 +0200 Subject: [PATCH 0501/2775] Translated using Weblate: Spanish (Mexico) (es_MX) by Leviatansan21 Currently translated at 6.0% (29 of 477 strings) Translation: F-Droid/F-Droid Server Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es_MX/ Added translation using Weblate: Spanish (Mexico) (es_MX) by Leviatansan21 Co-authored-by: Leviatansan21 --- locale/es_MX/LC_MESSAGES/fdroidserver.po | 2244 ++++++++++++++++++++++ 1 file changed, 2244 insertions(+) create mode 100644 locale/es_MX/LC_MESSAGES/fdroidserver.po diff --git a/locale/es_MX/LC_MESSAGES/fdroidserver.po b/locale/es_MX/LC_MESSAGES/fdroidserver.po new file mode 100644 index 00000000..e5cceb0b --- /dev/null +++ b/locale/es_MX/LC_MESSAGES/fdroidserver.po @@ -0,0 +1,2244 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# Leviatansan21 , 2020. +msgid "" +msgstr "" +"Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" +"Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" +"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"PO-Revision-Date: 2020-04-22 23:03+0000\n" +"Last-Translator: Leviatansan21 \n" +"Language-Team: Spanish (Mexico) \n" +"Language: es_MX\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 4.0.2-dev\n" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH Public Key to be used as Deploy Key:" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "" +"\n" +"{path} encoded for the DEBUG_KEYSTORE secret variable:" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "\"%s/\" has no matching metadata file!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains outdated {name} ({version})" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains recent {name} ({version})" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "\"{path}\" exists but s3cmd is not installed!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "\"{path}\" is not an accepted format, convert to: {formats}" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%(option)s option requires %(number)d argument" +msgid_plural "%(option)s option requires %(number)d arguments" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/mirror.py +#, python-format +msgid "%(prog)s [options] url" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%(prog)s: error: %(message)s\n" +msgstr "%(prog)s: error: %(mensaje)s\n" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "%d problems found" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "%prog [options]" +msgstr "%prog [opciones]" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%r is not callable" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "%s is not an accepted build field" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%s option does not take a value" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keypass' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystore' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystorepass' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'repo_keyalias' not found in config.py!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "'required' is an invalid argument for positionals" +msgstr "" + +#: ../fdroidserver/common.py +msgid "'sdk_path' not set in 'config.py'!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "'{apkfilename}' is already installed on {dev}." +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{path}' failed to execute!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "...checkupdate failed for {appid} : {error}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid ".__call__() not defined" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "/issues is missing" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "A URL is required as an argument!" +msgstr "" + +#: ../fdroid +msgid "Add PGP signatures using GnuPG for packages in repo" +msgstr "" + +#: ../fdroid +msgid "Add a new application from its source code" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Add a repo signing key to an unsigned repo" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Add skeleton metadata files for APKs that are missing them" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Adding new repo for only {name}" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Alias of the repo signing key in the keystore" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Allows a different revision (or git branch) to be specified for the initial import" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Also mirror the full archive section" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Also warn about formatting issues, like rewritemeta -l" +msgstr "" + +#: ../fdroidserver/common.py ../fdroidserver/build.py +#, python-brace-format +msgid "Android SDK '{path}' does not have '{dirname}' installed!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Android SDK not found!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' is not a directory!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android build-tools path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "AndroidManifest.xml has no date" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "App is in '{repo}' but has a link to {url}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Appending .git is not necessary" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Archiving {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in srclib '{srclib}'" +msgstr "" + +#: ../fdroid +msgid "Build a package from source" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build all applications available" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Build generated by `fdroid import` - remove disable line once ready" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Build metadata git repo has uncommited changes!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build only the latest version of each package" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "Built repo based in \"%s\" with this config:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Can't build due to {} error while scanning" +msgid_plural "Can't build due to {} errors while scanning" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find a packageName for {path}!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find an appid for {path}!" +msgstr "" + +#: ../fdroidserver/vmtools.py +#, python-brace-format +msgid "Cannot read \"{path}\"!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot resolve app id {appid}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Cannot use --list and --to at the same time" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Categories '%s' is not valid" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Categories are not set" +msgstr "" + +#: ../fdroid +msgid "Check for updates to applications" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean after all scans have finished" +msgstr "Limpiar después de que todos los escaneos hayan terminado" + +#: ../fdroidserver/dscanner.py +msgid "Clean before the scans start and rebuild the container" +msgstr "Limpiar antes de que comiencen los escaneos y reconstruya el contenedor" + +#: ../fdroidserver/dscanner.py +msgid "Clean up all containers and then exit" +msgstr "Limpiar todos los contenedores y luego salir" + +#: ../fdroidserver/update.py +msgid "Clean update - don't uses caches, reprocess all APKs" +msgstr "Actualización limpia: no usar cachés, reprocese todos los APK" + +#: ../fdroidserver/import.py +msgid "Comma separated list of categories." +msgstr "Lista de categorías separadas por comas." + +#: ../fdroid +#, c-format, python-format +msgid "Command '%s' not recognised.\n" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes" +msgstr "Hacer Cambios" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not find '{command}' on your system" +msgstr "No se pudo encontrar '{command}' en su sistema" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not find {path} to remove it" +msgstr "No se pudo encontrar {path} para eliminarlo" + +#: ../fdroidserver/update.py +msgid "Could not open apk file for analysis" +msgstr "No se pudo abrir el archivo apk para su análisis" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/import.py +msgid "Couldn't find latest version code" +msgstr "No se pudo encontrar el código de la última versión" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/import.py +msgid "Couldn't find latest version name" +msgstr "No se pudo encontrar el nombre de la última versión" + +#: ../fdroidserver/import.py +msgid "Couldn't find package ID" +msgstr "No se pudo encontrar la ID del paquete" + +#: ../fdroidserver/update.py +msgid "Cowardily refusing to overwrite existing signing key setup!" +msgstr "¡Negarse cobardemente a sobrescribir la configuración de clave de firma existente!" + +#: ../fdroidserver/update.py +msgid "Create a repo signing key in a keystore" +msgstr "Crear una clave de firma de repositorio en un almacén de claves" + +#: ../fdroidserver/update.py +msgid "Create skeleton metadata files that are missing" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Created new container \"{name}\"" +msgstr "Se creó un nuevo contenedor \"{name}\"" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating \"{path}\" for configuring s3cmd." +msgstr "Creando \"{path}\" para configurar s3cmd." + +#: ../fdroidserver/publish.py +msgid "Creating log directory" +msgstr "Creando directorio de registro" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating new S3 bucket: {url}" +msgstr "Crear un nuevo depósito de S3: {url}" + +#: ../fdroidserver/publish.py +msgid "Creating output directory" +msgstr "Creando directorio de salida" + +#: ../fdroidserver/index.py +msgid "Creating signed index with this key (SHA256):" +msgstr "Creando índice firmado con esta clave (SHA256):" + +#: ../fdroidserver/import.py ../fdroidserver/verify.py +#: ../fdroidserver/publish.py +msgid "Creating temporary directory" +msgstr "Creando Directorio Temporal" + +#: ../fdroidserver/index.py +msgid "Creating unsigned index in preparation for signing" +msgstr "Creando índice sin firmar en preparación para la firma" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" +msgstr "El código de versión actual {cv} es menor que la entrada de compilación más antigua {versionCode}" + +#: ../fdroidserver/nightly.py +msgid "DEBUG_KEYSTORE is not set or the value is incomplete" +msgstr "DEBUG_KEYSTORE no está establecido o el valor está incompleto" + +#: ../fdroidserver/update.py +msgid "Delete APKs and/or OBBs without metadata from the repo" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Deleting unknown file: {path}" +msgstr "Eliminando archivo desconocido: {path}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description '%s' is just the app's summary" +msgstr "Descripción '%s' es solo el resumen de la aplicación" + +#: ../fdroidserver/lint.py +msgid "Description has a duplicate line" +msgstr "La descripción tiene una línea duplicada" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description has a list (%s) but it isn't bulleted (*) nor numbered (#)" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Description of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not deploy the new files to the repo" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Do not include \"{path}\" in URL!" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Do not prompt for Android SDK path, just fail" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not remove the private keys generated from the keystore" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't create a source tarball, useful when testing a build" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Don't do anything logs-related" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't refresh the repository, useful when testing a build with no internet connection" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/upload.py +msgid "Don't use rsync checksums" +msgstr "" + +#: ../fdroid +msgid "Download complete mirrors of small repos" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Download logs we don't have" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Downloading the repository already failed once, not trying again." +msgstr "" + +#: ../fdroidserver/verify.py +#, python-brace-format +msgid "Downloading {url} failed. {error}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Duplicate build recipe found for versionCode {versionCode} in {linedesc}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Duplicate link in '{field}': {url}" +msgstr "" + +#: ../fdroid +msgid "Dynamically scan APKs post build" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "" +"ERROR: this command should never be used to mirror f-droid.org!\n" +"A full mirror of f-droid.org requires more than 200GB." +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "ERROR: unsupported CI type, patches welcome!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Empty build flag at {linedesc}" +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"Enter the path to the Android SDK (%s) here:\n" +"> " +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/upload.py +#, python-format +msgid "Error while attempting to publish log: %s" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Error while getting repo address" +msgstr "" + +#: ../fdroid +msgid "Extract signatures from APKs" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Failed fetching signatures for '{apkfilename}': {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed reading {path}: {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed resizing {path}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Failed to align application" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Failed to create S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to get APK manifest information" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, deleting {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, skipping {path}" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Failed to install '{apkfilename}' on {dev}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/common.py +msgid "Failed to sign application" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to zipalign application" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Fetched buildserverid from VM: {buildserverid}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py +#: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "Finished" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID flag" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Forbidden HTML tags" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Force halting build after {0} sec timeout!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Found invalid appids in arguments" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Found invalid versionCodes for some apps" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Found multiple metadata files for {appid}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found multiple signing certificates for repository." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found multiple signing certificates in {path}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found no signing certificates for repository." +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Found non-file at %s" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Generated skeleton metadata for {appid}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git checkout of '%s' failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git clean failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git fetch failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git remote set-head failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git reset failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule sync failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule update failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "HTTPS must be used with Subversion URLs!" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Ignoring package without metadata: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Ignoring stale cache data for {apkfilename}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Ignoring {ext} file at '{path}'" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Include APKs that are signed with disabled algorithms like MD5" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Initialising submodules" +msgstr "" + +#: ../fdroidserver/install.py +msgid "Install all signed applications available" +msgstr "" + +#: ../fdroid +msgid "Install built packages on devices" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s…" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}…" +msgstr "" + +#: ../fdroid +msgid "Interact with the repo HTTP server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Invalid APK" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid VercodeOperation: {field}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid boolean '%s'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build flag at {line} in {linedesc}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build format: {value} in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid bulleted list" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid metadata in %s:%d" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Invalid metadata in: " +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Invalid name for published file: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid package name {0}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid redirect to non-HTTPS: {before} -> {after} " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature failed to verify: {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature verified: {path}" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#: ../fdroidserver/mirror.py +msgid "Java JDK not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Java jarsigner not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Javascript in HTML src attributes" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Keystore for signing key:\t" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the LiberapayID flag" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "List files that would be reformatted" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Locale included in f-droid.org URL" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Make the build stop on exceptions" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Malformed repository mirrors." +msgstr "" + +#: ../fdroidserver/server.py +msgid "Malformed serverwebroot line:" +msgstr "" + +#: ../fdroidserver/gpgsign.py +msgid "Missing output directory" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Name '%s' is just the auto name - remove it" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No 'config.py' found, using defaults." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No Android SDK found!" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No android or kivy project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No attached devices found" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "No commit specified for {versionName} in {linedesc}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "No fingerprint in URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No git submodules available" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No information found." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is Free Software" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is for Android" +msgstr "" + +#: ../fdroidserver/server.py +msgid "No option set! Edit your config.py to set at least one of these:" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No packages specified" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "No signed apk available for %s" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No signed output directory - nothing to do" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "No signing certificates found in {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "No such package: %s" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No such versionCode {versionCode} for app {appid}" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +msgid "No unsigned directory - nothing to do" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Nothing to do" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Nothing to do for {appid}." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Now set these in config.py:" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "OBB file has newer versionCode({integer}) than any APK:" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB filename must start with \"main.\" or \"patch.\":" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB's packagename does not match a supported APK:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Old APK signature failed to verify: {path}" +msgstr "" + +#: ../fdroid +msgid "Old, deprecated name for fdroid deploy" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Only PNG and JPEG are supported for graphics, found: {path}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only print differences with the Play Store" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only process apps with auto-updates" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Options" +msgstr "" + +#: ../fdroidserver/verify.py +msgid "Output JSON report to file named after APK." +msgstr "" + +#: ../fdroidserver/import.py +msgid "Overall license of the project." +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Override path for repo APKs (default: ./repo)" +msgstr "" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Parsing manifest at '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Password required with username" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Path to main Android project subdirectory, if not in root." +msgstr "" + +msgid "Path to main android project subdirectory, if not in root." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Path to the git repo to use as the log" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the keystore for the repo signing key" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Prepare Drozer to run a scan" +msgstr "" + +msgid "Prepare drozer to run a scan" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Print the secret variable to the terminal for easy copy/paste" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Problem with description of {appid}: {error}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Problem with xml at '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Process auto-updates" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#, python-brace-format +msgid "Processing {apkfilename}" +msgstr "" + +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#, python-brace-format +msgid "Processing {appid}" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable XML/JSON for index files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable index.xml" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Project URL to import from." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Punctuation should be avoided" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Push the log to this git remote repository" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing binary transparency log to {url}" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing to {url}" +msgstr "" + +#: ../fdroid +msgid "Quickly start a new repository" +msgstr "" + +#: ../fdroid +msgid "Read all the metadata files and exit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading '{config_file}'" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading minSdkVersion failed: \"{apkfilename}\"" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Reading {apkfilename} from cache" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Removing specified files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Rename APK files that do not match package.name_123.apk" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Report on build data status" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Reset and create a brand new build server, even if the existing one appears to be ok." +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Resigning {apkfilename} with provided debug.keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Resize all the icons exceeding the max pixel size and exit" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Restrict output to warnings and errors" +msgstr "" + +#: ../fdroid +msgid "Rewrite all the metadata files" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Rewrite to a specific format: " +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}'" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}' to '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Run on git repo that has uncommitted changes" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Run rewritemeta to fix formatting" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Running first pass with MD5 checking disabled" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Running wget in {path}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Scan only the latest version of each package" +msgstr "" + +#: ../fdroid +msgid "Scan the source code of a package" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:{versionCode}:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Scanner found {} problem" +msgid_plural "Scanner found {} problems" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/common.py +msgid "Set clock to that time using:" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Set open file limit to {integer}" +msgstr "" + +#: ../fdroid +msgid "Set up an app build for a nightly build repo" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setting open file limit failed: " +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Setting {0} sec timeout for this build" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setup an emulator, install the APK on it and perform a Drozer scan" +msgstr "" + +msgid "Setup an emulator, install the apk on it and perform a drozer scan" +msgstr "" + +#: ../fdroid +msgid "Sign and place packages in the repo" +msgstr "" + +#: ../fdroid +msgid "Sign indexes created using update --nosign" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Skip scanning the source code for binaries and other problems" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping '{apkfilename}' with invalid signature!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping index generation for {appid}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: disabled" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: no builds specified" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify a local folder to sync the repo to" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify an identity file to provide to SSH for rsyncing" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Specify that we're running on the build server" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Specify which debug keystore file to use." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Spew out even more information than normal" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Striping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Summary '%s' is just the app's name" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Summary of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "System clock is older than date in {path}!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "The OBB version code must come after \"{name}.\":" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "The base URL for the repo to log (default: https://f-droid.org)" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "The directory to write the mirror to" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "The file to be included in the repo (path or glob)" +msgstr "" + +#: ../fdroidserver/server.py +msgid "The only commands currently supported are 'init' and 'update'" +msgstr "" + +#: ../fdroidserver/index.py +msgid "The repository's fingerprint does not match." +msgstr "" + +#: ../fdroidserver/common.py +msgid "The repository's index could not be verified." +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "The root dir for local_copy_dir \"{path}\" does not exist!" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "There is a keyalias collision - publishing halted" +msgstr "" + +#: ../fdroidserver/import.py +#, python-format +msgid "This repo already has local metadata: %s" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "URL shorteners should not be used" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "URL title is just the URL, use brackets: [URL]" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "URL {url} in Description: {error}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unexpected text on same line as {field} in {linedesc}" +msgstr "" + +#: ../fdroid +msgid "Unknown exception found!" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Unknown file '{filename}' in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Unknown metadata format: %s" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path}" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Unknown version of aapt, might cause problems: " +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary leading space" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary trailing space" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised app field '{fieldname}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unrecognised app field: " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised build flag '{build_flag}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised field '{field}' in {linedesc}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported file type \"{extension}\" for repo graphic" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported graphics file found: {path}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Unsupported metadata format, use: --to [{supported}]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated build in {name}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated continuation in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused extlib at %s" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused file at %s" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Update Check Name is set to the known app id - it can be removed" +msgstr "" + +#: ../fdroid +msgid "Update repo information for new packages" +msgstr "" + +#: ../fdroid +msgid "Update the binary transparency log for a URL" +msgstr "" + +#: ../fdroid +msgid "Update the stats of the repo" +msgstr "" + +#: ../fdroidserver/update.py ../fdroidserver/build.py +msgid "Update the wiki" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "UpdateCheckData has invalid URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must use HTTPS URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData not a valid URL: {url}" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Usage" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "Usage: %s\n" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Use /HEAD instead of /master to point at a file in the default branch" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use `fdroid update -c` to create it." +msgstr "" + +#: ../fdroidserver/build.py +msgid "Use build server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use date from APK instead of current time for newly added APKs" +msgstr "" + +msgid "Use date from apk instead of current time for newly added apks" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Using androguard from \"{path}\"" +msgstr "" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Using existing keystore \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using s3cmd to sync with: {url}" +msgstr "" + +#: ../fdroid +msgid "Valid commands are:" +msgstr "" + +#: ../fdroidserver/verify.py +msgid "Verify against locally cached copy rather than redownloading." +msgstr "" + +#: ../fdroid +msgid "Verify the integrity of downloaded packages" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Verifying index signature:" +msgstr "" + +#: ../fdroid +msgid "Warn about possible metadata errors" +msgstr "" + +#: ../fdroidserver/update.py +msgid "When configured for signed indexes, create only unsigned indexes at this stage" +msgstr "" + +msgid "X.509 'Distiguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/init.py +msgid "X.509 'Distinguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/common.py +msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "adding IdentityFile to {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "adding to {name}: {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ambiguous option: %(option)s could match %(matches)s" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "ambiguous option: %s (%s?)" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +msgid "applicationId in the form APPID" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "applicationId to check for updates" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/dscanner.py ../fdroidserver/build.py +#: ../fdroidserver/scanner.py ../fdroidserver/install.py +msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "argument \"-\" with mode %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "attempting bare ssh connection to test deploy key:" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "can't open '%s': %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "cannot have multiple subparser arguments" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "cannot merge actions - two groups are named %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "cannot publish update, did you set the deploy key?" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "cloning {url}" +msgstr "" + +#: ../fdroidserver/server.py +msgid "command to execute, either 'init' or 'update'" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "complex" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "conflicting option string: %s" +msgid_plural "conflicting option strings: %s" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "copying {apkfilename} into {path}" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "created {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "deleting: repo/{apkfilename}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed build logs to '{path}'" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "dest= is required for options like %r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "expected %s argument" +msgid_plural "expected %s arguments" +msgstr[0] "" +msgstr[1] "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at least one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at most one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected one argument" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "failed deploying build logs to '{path}'" +msgstr "" + +#: ../fdroid +msgid "fdroid [-h|--help|--version] []" +msgstr "" + +#: ../fdroid +msgid "fdroid [] [-h|--help|--version|]" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "floating-point" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force errors to be warnings, or ignore" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force metadata errors (default) to be warnings, or to be ignored." +msgstr "" + +#: ../fdroidserver/common.py +msgid "git svn clone failed" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ignored explicit argument %r" +msgstr "" + +#: ../fdroidserver/index.py +msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "integer" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid %(type)s value: %(value)r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid choice: %(value)r (choose from %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid conflict_resolution value: %r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be an absolute path!" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be directory, not a file!" +msgstr "" + +#: ../fdroidserver/index.py +#, python-format +msgid "mirror '%s' does not end with 'fdroid'!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "mutually exclusive arguments must be optional" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "no \"icon\" in {appid}" +msgstr "" + +#: ../fdroidserver/signatures.py +msgid "no APK supplied" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "no such option: %s" +msgstr "" + +#: ../fdroid +msgid "no version info found!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "not allowed with argument %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "one of the arguments %s is required" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "only accepts strings, lists, and tuples" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "option %s: If you really want to install all the signed apps, use --all" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid %s value: %r" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid choice: %r (choose from %s)" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s not recognized" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s requires argument" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s must not have an argument" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not a unique prefix" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not recognized" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s requires argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "optional arguments" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "overwriting existing {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "positional arguments" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "s3cmd sync indexes {path} to {url} and delete" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "show program's version number and exit" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.5/optparse.py +#: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py +msgid "show this help message and exit" +msgstr "" + +#: ../fdroidserver/signatures.py +msgid "signed APK, either a file-path or HTTPS URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: log content is empty" +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: not enabled in config" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "skipping source tarball: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "srclibs missing name and/or @" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "the following arguments are required: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unexpected option string: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unknown parser %(parser_name)r (choices: %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unrecognized arguments: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "unsafe permissions on '{config_file}' (should be 0600)!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid +#: /usr/lib/python3.7/argparse.py +msgid "usage: " +msgstr "" + +#: ../fdroid +msgid "usage: fdroid [-h|--help|--version] []" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "using Apache libcloud to sync with {url}" +msgstr "" + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "{0} app, {1} key aliases" +msgid_plural "{0} apps, {1} key aliases" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} ({appid}) has no metadata!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using package name instead." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android Package Name!" +msgstr "" + +#: ../fdroidserver/metadata.py ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Java Package Name!" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{appid} is missing {name}" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: Unknown extlib {path} in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "{appid}: no builds specified, running on current source state" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{field} not terminated in {name}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{name} \"{path}\" does not exist! Correct it in config.py." +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "{path} does not exist! Create it by running:" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} is zero size!" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{url} does not end with \"fdroid\", check the URL path!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "{} build failed" +msgid_plural "{} builds failed" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/build.py +msgid "{} build succeeded" +msgid_plural "{} builds succeeded" +msgstr[0] "" +msgstr[1] "" From 4e2844629cfdf66eedda323b51b47dde1724935d Mon Sep 17 00:00:00 2001 From: Jeannette L Date: Thu, 1 Oct 2020 11:00:41 +0200 Subject: [PATCH 0502/2775] Translated using Weblate: French (fr) by Jeannette L Currently translated at 68.7% (328 of 477 strings) Co-authored-by: Jeannette L Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 5a124399..c15543ef 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -3,20 +3,21 @@ # Julien Gontier , 2020. # anonymous , 2020. # Hans-Christoph Steiner , 2020. +# Jeannette L , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-15 12:27+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-04-29 11:11+0000\n" +"Last-Translator: Jeannette L \n" "Language-Team: French \n" "Language: fr\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 4.0-dev\n" +"X-Generator: Weblate 4.0.2\n" #: ../fdroidserver/nightly.py msgid "" @@ -640,7 +641,7 @@ msgstr "Impossible d'aligner les applications" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" -msgstr "La création du S3 Bucket a échoué: {url}" +msgstr "La création du S3 Bucket a échoué : {url}" #: ../fdroidserver/common.py msgid "Failed to get APK manifest information" @@ -659,7 +660,7 @@ msgstr "Échoument lors de la récupération des informations de l'APK, saut de #: ../fdroidserver/install.py #, python-brace-format msgid "Failed to install '{apkfilename}' on {dev}: {error}" -msgstr "Impossible d'installer '{apkfilename}' sur {dev}: {error}" +msgstr "Impossible d'installer « {apkfilename} » sur {dev} : {error}" #: ../fdroidserver/publish.py ../fdroidserver/common.py msgid "Failed to sign application" @@ -672,7 +673,7 @@ msgstr "Impossible d'optimiser avec zipalign cette application" #: ../fdroidserver/build.py #, python-brace-format msgid "Fetched buildserverid from VM: {buildserverid}" -msgstr "Récupération de l'ID du serveur de construction depuis la VM: {buildserverid}" +msgstr "Récupération de l'ID du serveur de construction depuis la VM : {buildserverid}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -701,12 +702,12 @@ msgstr "Forcer la construction des application désactiver, et opérateur indép #: ../fdroidserver/build.py #, python-brace-format msgid "Force halting build after {0} sec timeout!" -msgstr "Arrêt forcer de la construction apès {0} secondes de timeout!" +msgstr "Arrêt forcer de la construction après {0} secondes de délai d'attente !" #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" -msgstr "\"{path}\" graphique trouvée sans metadonnées pour l'application \"{name}\"!" +msgstr "« {path} » graphique trouvée sans métadonnées pour l'application « {name} » !" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" @@ -1269,7 +1270,7 @@ msgstr "Réécrire dans un format spécifique : " #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Rewriting '{appid}'" -msgstr "" +msgstr "Réécriture de « {appid} »" #: ../fdroidserver/rewritemeta.py #, python-brace-format @@ -1314,8 +1315,8 @@ msgstr "" #: ../fdroidserver/build.py msgid "Scanner found {} problem" msgid_plural "Scanner found {} problems" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Le scanneur a trouvé {} problème" +msgstr[1] "Le scanneur a trouvé {} problèmes" #: ../fdroidserver/common.py msgid "Set clock to that time using:" From 81a4e103b55f64a169faf18f575c455f8bb5b97b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 11:00:42 +0200 Subject: [PATCH 0503/2775] Translated using Weblate: Spanish (Argentina) (es_AR) by Hans-Christoph Steiner Currently translated at 16.5% (79 of 477 strings) Translated using Weblate: Spanish (Mexico) (es_MX) by Hans-Christoph Steiner Currently translated at 6.0% (29 of 477 strings) Co-authored-by: Hans-Christoph Steiner Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es_AR/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es_MX/ Translation: F-Droid/F-Droid Server --- locale/es_AR/LC_MESSAGES/fdroidserver.po | 41 +++++++++++------------- locale/es_MX/LC_MESSAGES/fdroidserver.po | 9 +++--- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/locale/es_AR/LC_MESSAGES/fdroidserver.po b/locale/es_AR/LC_MESSAGES/fdroidserver.po index 12aa9cca..f0323c3d 100644 --- a/locale/es_AR/LC_MESSAGES/fdroidserver.po +++ b/locale/es_AR/LC_MESSAGES/fdroidserver.po @@ -1,22 +1,21 @@ # 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 , YEAR. -# +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2019-01-27 13:19+0000\n" -"Last-Translator: Andrés S \n" +"PO-Revision-Date: 2020-10-01 09:00+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Spanish (Argentina) \n" "Language: es_AR\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 3.5-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -718,9 +717,9 @@ msgid "Found invalid versionCodes for some apps" msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found multiple metadata files for {appid}" -msgstr "Crear plantilla de metadatos de los archivos faltantes" +msgstr "" #: ../fdroidserver/index.py msgid "Found multiple signing certificates for repository." @@ -741,9 +740,9 @@ msgid "Found non-file at %s" msgstr "" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Generated skeleton metadata for {appid}" -msgstr "Crear plantilla de metadatos de los archivos faltantes" +msgstr "Crear plantilla de metadatos de {appid}" #: ../fdroidserver/common.py #, python-format @@ -1189,9 +1188,9 @@ msgid "Push the log to this git remote repository" msgstr "Subir el registro al repositorio remoto de git" #: ../fdroidserver/server.py ../fdroidserver/upload.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Pushing binary transparency log to {url}" -msgstr "Actualizar el registro de transparencia binario de un URL" +msgstr "Actualizar el registro de transparencia binario de {url}" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -1231,7 +1230,7 @@ msgstr "" #: ../fdroidserver/stats.py #, fuzzy msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." -msgstr "Recalcular las agregaciones - usar cuando haya cambios " +msgstr "Recalcular las agregaciones - usar cuando haya cambios" #: ../fdroidserver/common.py msgid "Removing specified files" @@ -1286,9 +1285,8 @@ msgid "Run on git repo that has uncommitted changes" msgstr "" #: ../fdroidserver/lint.py -#, fuzzy msgid "Run rewritemeta to fix formatting" -msgstr "Rescribir a un formato especifico: " +msgstr "" #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" @@ -1522,9 +1520,9 @@ msgid "Unknown metadata format: %s" msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path}" -msgstr "Crear plantilla de metadatos de los archivos faltantes" +msgstr "" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1897,9 +1895,8 @@ msgid "force errors to be warnings, or ignore" msgstr "forzar errores al ser advertencias, o ignorar" #: ../fdroidserver/metadata.py -#, fuzzy msgid "force metadata errors (default) to be warnings, or to be ignored." -msgstr "forzar errores al ser advertencias, o ignorar" +msgstr "forzar errores al ser advertencias, o ignorar." #: ../fdroidserver/common.py msgid "git svn clone failed" @@ -2022,9 +2019,9 @@ msgstr "" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py -#, fuzzy, python-format +#, python-format msgid "option -%s not recognized" -msgstr "No se reconoce el comando \"%s\".\n" +msgstr "No se reconoce el comando \"%s\"" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py @@ -2046,9 +2043,9 @@ msgstr "" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py -#, fuzzy, python-format +#, python-format msgid "option --%s not recognized" -msgstr "No se reconoce el comando \"%s\".\n" +msgstr "No se reconoce el comando --\"%s\"" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py diff --git a/locale/es_MX/LC_MESSAGES/fdroidserver.po b/locale/es_MX/LC_MESSAGES/fdroidserver.po index e5cceb0b..7981a7db 100644 --- a/locale/es_MX/LC_MESSAGES/fdroidserver.po +++ b/locale/es_MX/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. # Leviatansan21 , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-22 23:03+0000\n" -"Last-Translator: Leviatansan21 \n" +"PO-Revision-Date: 2020-04-29 12:49+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Spanish (Mexico) \n" "Language: es_MX\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 4.0.2-dev\n" +"X-Generator: Weblate 4.0.2\n" #: ../fdroidserver/nightly.py msgid "" @@ -71,7 +72,7 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "%(prog)s: error: %(message)s\n" -msgstr "%(prog)s: error: %(mensaje)s\n" +msgstr "%(prog)s: error: %(message)s\n" #: ../fdroidserver/scanner.py #, python-format From a5ae4f4a66a3a9b128f4e05c2d6f460c04a8ae7a Mon Sep 17 00:00:00 2001 From: Nathan Date: Thu, 1 Oct 2020 11:00:42 +0200 Subject: [PATCH 0504/2775] Translated using Weblate: French (fr) by Nathan Currently translated at 69.1% (330 of 477 strings) Co-authored-by: Nathan Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index c15543ef..3b78cb87 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -4,20 +4,21 @@ # anonymous , 2020. # Hans-Christoph Steiner , 2020. # Jeannette L , 2020. +# Nathan , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-29 11:11+0000\n" -"Last-Translator: Jeannette L \n" +"PO-Revision-Date: 2020-05-02 11:11+0000\n" +"Last-Translator: Nathan \n" "Language-Team: French \n" "Language: fr\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 4.0.2\n" +"X-Generator: Weblate 4.1-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -1106,7 +1107,7 @@ msgstr "Substitution du nom de version vide dans {apkfilename} des métadonnées #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" -msgstr "" +msgstr "Analyse du fichier manifeste sur « {path} »" #: ../fdroidserver/common.py msgid "Password required with username" @@ -1145,7 +1146,7 @@ msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Problem with description of {appid}: {error}" -msgstr "" +msgstr "Problème avec la description de {appid} : {error}" #: ../fdroidserver/common.py #, python-brace-format From 66bbe51a4d3f7248ffce01a36b3a23bc4ae4514b Mon Sep 17 00:00:00 2001 From: Manuela Silva Date: Thu, 1 Oct 2020 11:00:43 +0200 Subject: [PATCH 0505/2775] Translated using Weblate: Portuguese (Portugal) (pt_PT) by Manuela Silva Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Manuela Silva Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_PT/ Translation: F-Droid/F-Droid Server --- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 43 ++++++++++++------------ 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index 272e6058..ffdcd72a 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -1,22 +1,21 @@ # 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 , YEAR. -# +# Manuela Silva , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2019-01-31 13:32+0000\n" -"Last-Translator: ssantos \n" +"PO-Revision-Date: 2020-05-13 22:41+0000\n" +"Last-Translator: Manuela Silva \n" "Language-Team: Portuguese (Portugal) \n" "Language: pt_PT\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 3.5-dev\n" +"X-Generator: Weblate 4.1-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -167,7 +166,7 @@ msgstr "'{path}' falhou ao executar!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" -msgstr "'{value}' não é um{field} válido em {appid}. Regex padrão: {pattern}" +msgstr "'{value}' não é um {field} válido em {appid}. Padrão Regex: {pattern}" #: ../fdroidserver/checkupdates.py #, python-brace-format @@ -1158,12 +1157,12 @@ msgstr "Processar atualizações automáticas" #: ../fdroidserver/publish.py ../fdroidserver/update.py #, python-brace-format msgid "Processing {apkfilename}" -msgstr "Processando {apkfilename}" +msgstr "A processar {apkfilename}" #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py #, python-brace-format msgid "Processing {appid}" -msgstr "Processando {appid}" +msgstr "A processar {appid}" #: ../fdroidserver/update.py msgid "Produce human-readable XML/JSON for index files" @@ -1183,35 +1182,35 @@ msgstr "A pontuação deve ser evitada" #: ../fdroidserver/btlog.py msgid "Push the log to this git remote repository" -msgstr "Mandar o registro de mudanças para este repositório git remoto" +msgstr "Submeter o registo de eventos para este repositório git remoto" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" -msgstr "Atualizar o log de transparência de um binário para {url}" +msgstr "A submeter o registo de transparência de binário para {url}" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" -msgstr "Empurrando para {url}" +msgstr "A submeter para {url}" #: ../fdroid msgid "Quickly start a new repository" -msgstr "Criação de um novo repositório" +msgstr "Criar rapidamente um novo repositório" #: ../fdroid msgid "Read all the metadata files and exit" -msgstr "Lê todos os metadados dos ficheiros e sai" +msgstr "Ler todos os ficheiros de metadados e sair" #: ../fdroidserver/common.py #, python-brace-format msgid "Reading '{config_file}'" -msgstr "Lendo '{config_file}'" +msgstr "A ler '{config_file}'" #: ../fdroidserver/common.py #, python-brace-format msgid "Reading minSdkVersion failed: \"{apkfilename}\"" -msgstr "Leitura de minSdkVersion falhou: \"{apkfilename}\"" +msgstr "A leitura de minSdkVersion falhou: \"{apkfilename}\"" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname @@ -1235,7 +1234,7 @@ msgstr "Apagando ficheiros especificados" #: ../fdroidserver/update.py msgid "Rename APK files that do not match package.name_123.apk" -msgstr "Renomeia todos os nomes dos APKs que não têm o mesmo nome que package.name_123.apk" +msgstr "Renomear todos os ficheiros APKs que não correspondem com package.name_123.apk" #: ../fdroidserver/update.py msgid "Report on build data status" @@ -1260,7 +1259,7 @@ msgstr "Restringir a saída a erros e avisos" #: ../fdroid msgid "Rewrite all the metadata files" -msgstr "Reescreve todos os ficheiros de metadados" +msgstr "Regravar todos os ficheiros de metadados" #: ../fdroidserver/rewritemeta.py msgid "Rewrite to a specific format: " @@ -1299,7 +1298,7 @@ msgstr "Escanear apenas a versão mais recente de cada pacote" #: ../fdroid msgid "Scan the source code of a package" -msgstr "Analise do código fonte do pacote" +msgstr "Analisar o código fonte de um pacote" #: ../fdroidserver/scanner.py #, python-brace-format @@ -1348,11 +1347,11 @@ msgstr "Configure um emulador, instale o apk nele e execute um scan do drozer" #: ../fdroid msgid "Sign and place packages in the repo" -msgstr "Assine e coloque pacotes no repositório" +msgstr "Assinar e colocar os pacotes no repositório" #: ../fdroid msgid "Sign indexes created using update --nosign" -msgstr "Assinar os índices criados usando update --nosign" +msgstr "Assinar os índices criados com o uso de update --nosign" #: ../fdroidserver/build.py msgid "Skip scanning the source code for binaries and other problems" @@ -1601,11 +1600,11 @@ msgstr "O nome da verificação de atualização (Update Check Name) é definido #: ../fdroid msgid "Update repo information for new packages" -msgstr "Atualize as informações do repositório para novos pacotes" +msgstr "Atualizar a informação do repositório para novos pacotes" #: ../fdroid msgid "Update the binary transparency log for a URL" -msgstr "Atualizar o log de transparência de um binário para um URL" +msgstr "Atualizar o registo de transparência de binário para um URL" #: ../fdroid msgid "Update the stats of the repo" From c80a5fb1b149dba9ec88c079efbe5f69c0508cba Mon Sep 17 00:00:00 2001 From: Virgile L Date: Thu, 1 Oct 2020 11:00:43 +0200 Subject: [PATCH 0506/2775] Translated using Weblate: French (fr) by Virgile L. Currently translated at 69.6% (332 of 477 strings) Co-authored-by: Virgile L Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 3b78cb87..6f87e2f4 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -5,13 +5,14 @@ # Hans-Christoph Steiner , 2020. # Jeannette L , 2020. # Nathan , 2020. +# Virgile L. , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-05-02 11:11+0000\n" -"Last-Translator: Nathan \n" +"PO-Revision-Date: 2020-05-13 22:41+0000\n" +"Last-Translator: Virgile L. \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1111,7 +1112,7 @@ msgstr "Analyse du fichier manifeste sur « {path} »" #: ../fdroidserver/common.py msgid "Password required with username" -msgstr "Mot de passe requis avec nom d'utilisateur" +msgstr "Mot de passe requis avec le nom d'utilisateur" #: ../fdroidserver/import.py msgid "Path to main Android project subdirectory, if not in root." @@ -1134,10 +1135,10 @@ msgstr "" #: ../fdroidserver/dscanner.py msgid "Prepare Drozer to run a scan" -msgstr "" +msgstr "Préparer Drozer pour lancer une analyse" msgid "Prepare drozer to run a scan" -msgstr "" +msgstr "Préparer Drozer pour lancer un scanne" #: ../fdroidserver/nightly.py msgid "Print the secret variable to the terminal for easy copy/paste" From 6ccaa209cda5ec050298ce3f749078a990203d98 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Thu, 1 Oct 2020 11:00:44 +0200 Subject: [PATCH 0507/2775] Translated using Weblate: Ukrainian (uk) by ihor_ck Currently translated at 100.0% (477 of 477 strings) Translated using Weblate: Ukrainian (uk) by ihor_ck Currently translated at 46.7% (223 of 477 strings) Translated using Weblate: Ukrainian (uk) by ihor_ck Currently translated at 41.0% (196 of 477 strings) Translated using Weblate: Ukrainian (uk) by ihor_ck Currently translated at 41.0% (196 of 477 strings) Co-authored-by: ihor_ck Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/uk/ Translation: F-Droid/F-Droid Server --- locale/uk/LC_MESSAGES/fdroidserver.po | 661 +++++++++++++------------- 1 file changed, 320 insertions(+), 341 deletions(-) diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index 6135ec84..b0a6660b 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # Hans-Christoph Steiner , 2020. +# ihor_ck , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-07 13:43+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-09-19 17:03+0000\n" +"Last-Translator: ihor_ck \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.0-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -136,7 +137,7 @@ msgstr "'sdk_path' не встановлено в 'config.py'!" #: ../fdroidserver/common.py #, python-brace-format msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" -msgstr "'{aapt}' занадто старий, fdroid вимагає інструментів-створення 23.0.0 або новіший!" +msgstr "'{aapt}' занадто старий, fdroid вимагає build-tools-23.0.0 або новіших!" #: ../fdroidserver/common.py #, python-brace-format @@ -151,7 +152,7 @@ msgstr "'{apkfilename}' вже встановлено на {dev}." #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" -msgstr "" +msgstr "'{field}' у {linedesc} застаріло, поточні поля вказано в документації:" #: ../fdroidserver/common.py #, python-brace-format @@ -274,18 +275,18 @@ msgstr "Архівую {apkfilename} з неправильним підписо #: ../fdroidserver/mirror.py msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" -msgstr "" +msgstr "Базова URL-адреса для дзеркала може містити ключ підпису індексу за допомогою рядка запиту: ?fingerprint=" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/lint.py #, python-brace-format msgid "Branch '{branch}' used as commit in build '{versionName}'" -msgstr "" +msgstr "Гілка \"{branch}\" використовується як подання до збірки '{versionName}'" #: ../fdroidserver/lint.py #, python-brace-format msgid "Branch '{branch}' used as commit in srclib '{srclib}'" -msgstr "" +msgstr "Гілка '{branch}' використовується як подання в бібліотеку srclib '{srclib}'" #: ../fdroid msgid "Build a package from source" @@ -297,11 +298,11 @@ msgstr "Створіть всі доступні застосунки" #: ../fdroidserver/lint.py msgid "Build generated by `fdroid import` - remove disable line once ready" -msgstr "" +msgstr "Збірку, створено за допомогою `fdroid import` - видаліть рядок вимикання після готовності" #: ../fdroidserver/checkupdates.py msgid "Build metadata git repo has uncommited changes!" -msgstr "" +msgstr "У сховищі з метаданими збірки є незбережені зміни!" #: ../fdroidserver/build.py msgid "Build only the latest version of each package" @@ -310,51 +311,51 @@ msgstr "Створіть лише останню версію кожного п #: ../fdroidserver/metadata.py #, python-brace-format msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" -msgstr "" +msgstr "Для побудови необхідно розділяти versionName і versionCode комою. Ви вказали \"{value}\" в рядку {linedesc}" #: ../fdroidserver/init.py #, python-format msgid "Built repo based in \"%s\" with this config:" -msgstr "" +msgstr "Вбудоване сховище створено у \"%s\" на основі конфігурації:" #: ../fdroidserver/build.py msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "Неможливо створити через {} помилку під час сканування" +msgstr[1] "Неможливо створити через {} помилки під час сканування" +msgstr[2] "Неможливо створити через {} помилок під час сканування" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Cannot find a packageName for {path}!" -msgstr "" +msgstr "Неможливо знайти packageName за шляхом {path}!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Cannot find an appid for {path}!" -msgstr "" +msgstr "Не вдається знайти appid за шляхом {path}!" #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" -msgstr "" +msgstr "Неправильно вказано шлях \"{path}\"!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Cannot resolve app id {appid}" -msgstr "" +msgstr "Неможливо розв'язати id застосунку {appid}" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" -msgstr "" +msgstr "Не можна одночасно використовувати --list та --to" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" -msgstr "" +msgstr "Неможливо записати \"{path}\", не прийнятний формат, використовуйте: {formats}" #: ../fdroidserver/lint.py -#, fuzzy, python-format +#, python-format msgid "Categories '%s' is not valid" msgstr "Категорія '%s' неприпустима" @@ -369,7 +370,7 @@ msgstr "Перевірте наявність оновлень для засто #: ../fdroidserver/update.py #, python-brace-format msgid "Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" -msgstr "" +msgstr "Перевірка архівації на {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" #: ../fdroidserver/dscanner.py msgid "Clean after all scans have finished" @@ -384,9 +385,8 @@ msgid "Clean up all containers and then exit" msgstr "Очистити усі контейнери, а потім вийти" #: ../fdroidserver/update.py -#, fuzzy msgid "Clean update - don't uses caches, reprocess all APKs" -msgstr "Очистити оновлення - не використовує кеш, повторно обробляє всі apks" +msgstr "Очистити оновлення - не використовує кеш, повторно обробляє всі APK" #: ../fdroidserver/import.py msgid "Comma separated list of categories." @@ -409,7 +409,7 @@ msgstr "Не вдалося знайти '{command}' у вашій систем #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" -msgstr "" +msgstr "Не вдалося знайти шлях {path}, щоб вилучити його" #: ../fdroidserver/update.py msgid "Could not open apk file for analysis" @@ -431,7 +431,7 @@ msgstr "Не вдається знайти ідентифікатор пакет #: ../fdroidserver/update.py msgid "Cowardily refusing to overwrite existing signing key setup!" -msgstr "" +msgstr "Боязно трохи, ми відмовляємося перезаписувати наявний ключ підписування!" #: ../fdroidserver/update.py msgid "Create a repo signing key in a keystore" @@ -449,7 +449,7 @@ msgstr "Створено новий контейнер \"{name}\"" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." -msgstr "" +msgstr "Створення \"{path}\" для налаштування s3cmd." #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -480,11 +480,11 @@ msgstr "Створення непідписаного індексу під ча #: ../fdroidserver/lint.py #, python-brace-format msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" -msgstr "" +msgstr "CurrentVersionCode {cv} менше, ніж найстаріший запис збірки {versionCode}" #: ../fdroidserver/nightly.py msgid "DEBUG_KEYSTORE is not set or the value is incomplete" -msgstr "" +msgstr "DEBUG_KEYSTORE не встановлено або значення є неповним" #: ../fdroidserver/update.py msgid "Delete APKs and/or OBBs without metadata from the repo" @@ -493,7 +493,7 @@ msgstr "Видалити APKs і/або OBBs без метаданих зі сх #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" -msgstr "" +msgstr "Видалення невідомого файлу: {path}" #: ../fdroidserver/lint.py #, python-format @@ -516,12 +516,12 @@ msgstr "Довжина опису {length} перевищує ліміт {limit} #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" -msgstr "" +msgstr "Не розміщувати нові файли до сховища одразу" #: ../fdroidserver/mirror.py #, python-brace-format msgid "Do not include \"{path}\" in URL!" -msgstr "" +msgstr "Не включайте \"{path}\" до URL-адреси!" #: ../fdroidserver/init.py msgid "Do not prompt for Android SDK path, just fail" @@ -529,7 +529,7 @@ msgstr "Не точний шлях Android SDK, просто збій" #: ../fdroidserver/nightly.py msgid "Do not remove the private keys generated from the keystore" -msgstr "" +msgstr "Не видаляйте приватні ключі, утворені у сховищі ключів" #: ../fdroidserver/build.py msgid "Don't create a source tarball, useful when testing a build" @@ -550,7 +550,7 @@ msgstr "Не використовуйте контрольні суми rsync" #: ../fdroid msgid "Download complete mirrors of small repos" -msgstr "" +msgstr "Завантажувати повноцінні дзеркала невеликих сховищ" #: ../fdroidserver/stats.py msgid "Download logs we don't have" @@ -558,7 +558,7 @@ msgstr "Журналів завантаження у нас немає" #: ../fdroidserver/common.py msgid "Downloading the repository already failed once, not trying again." -msgstr "Завантаження репозиторія вже не відбулося один раз, не намагайтеся знову." +msgstr "Завантаження сховища вже не вдалося, не намагайтеся знову." #: ../fdroidserver/verify.py #, python-brace-format @@ -568,7 +568,7 @@ msgstr "Завантаження {url} не вдалося. {error}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Duplicate build recipe found for versionCode {versionCode} in {linedesc}" -msgstr "" +msgstr "Подвоєний рецепт збірки, знайдено для versionCode {versionCode} у {linedesc}" #: ../fdroidserver/lint.py #, python-brace-format @@ -584,15 +584,17 @@ msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" "A full mirror of f-droid.org requires more than 200GB." msgstr "" +"ПОМИЛКА: ця команда ніколи не повинна використовуватися для створення дзеркала f-droid.org!\n" +"Повне дзеркало f-droid.org вимагає понад 200GB." #: ../fdroidserver/nightly.py msgid "ERROR: unsupported CI type, patches welcome!" -msgstr "" +msgstr "ПОМИЛКА: непідтримуваний вид CI, виправлення вітається!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Empty build flag at {linedesc}" -msgstr "" +msgstr "Порожній прапорець збірки на {linedesc}" #: ../fdroidserver/init.py #, python-format @@ -605,9 +607,9 @@ msgstr "" #: ../fdroidserver/server.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py -#, fuzzy, python-format +#, python-format msgid "Error while attempting to publish log: %s" -msgstr "Помилка при отриманні адреси репозиторія: %s" +msgstr "Помилка під час отримання адреси сховища: %s" #: ../fdroidserver/import.py msgid "Error while getting repo address" @@ -625,17 +627,16 @@ msgstr "Не вдалося завантажити підписи для '{apkfi #: ../fdroidserver/update.py #, python-brace-format msgid "Failed reading {path}: {error}" -msgstr "" +msgstr "Не вдалося розпізнати {path}: {error}" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed resizing {path}: {error}" -msgstr "" +msgstr "Не вдалося змінити розмір {path}: {error}" #: ../fdroidserver/publish.py -#, fuzzy msgid "Failed to align application" -msgstr "Створіть всі доступні застосунки" +msgstr "Не вдалося оптимізувати (align) застосунок" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -644,17 +645,17 @@ msgstr "Не вдалося створити сигмент S3: {url}" #: ../fdroidserver/common.py msgid "Failed to get APK manifest information" -msgstr "Не вдалося отримати інформацію про APK" +msgstr "Не вдалося отримати подробиці про APK" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed to get apk information, deleting {path}" -msgstr "" +msgstr "Не вдалося отримати подробиці про apk, {path} буде видалено" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed to get apk information, skipping {path}" -msgstr "" +msgstr "Не вдалося отримати подробиці про apk, {path} буде пропущено" #: ../fdroidserver/install.py #, python-brace-format @@ -666,19 +667,18 @@ msgid "Failed to sign application" msgstr "Не вдалося підписати застосунок" #: ../fdroidserver/common.py -#, fuzzy msgid "Failed to zipalign application" -msgstr "Створіть всі доступні застосунки" +msgstr "Не вдалося оптимізувати (zipalign) застосунок" #: ../fdroidserver/build.py #, python-brace-format msgid "Fetched buildserverid from VM: {buildserverid}" -msgstr "" +msgstr "Сервер для збірки скопійовано з ВМ {buildserverid}" #: ../fdroidserver/signatures.py #, python-brace-format msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" -msgstr "Отримані підписи для '{apkfilename}' -> '{sigdir}'" +msgstr "Отримані підписи для '{apkfilename}' -> '{sigdir}'" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -688,27 +688,26 @@ msgid "Finished" msgstr "Готово" #: ../fdroidserver/lint.py -#, fuzzy msgid "Flattr donation methods belong in the FlattrID flag" -msgstr "Методи донорства Flattr належать до прапора FlattrID" +msgstr "Методи допомоги Flattr належать до прапора FlattrID" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" -msgstr "" +msgstr "Заборонені мітки HTML" #: ../fdroidserver/build.py msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." -msgstr "Примусити створювати інвалідні додатки, і здійснювати розміщення незалежно від проблем сканування. Лише дозволено в тестовому режимі." +msgstr "Збирати заблоковані застосунки попри проблеми сканування. Дозволено лише в тестовому режимі." #: ../fdroidserver/build.py #, python-brace-format msgid "Force halting build after {0} sec timeout!" -msgstr "" +msgstr "Примусово зупиняти збірку після {0} сек. затримки!" #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" -msgstr "" +msgstr "У \"{path}\" виявлено зображення без метаданих для застосунку \"{name}\"!" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" @@ -726,16 +725,16 @@ msgstr "Знайдено кілька файлів метаданих для {ap #: ../fdroidserver/index.py msgid "Found multiple signing certificates for repository." -msgstr "Знайдено кілька сертифікатів підписування для репозиторію." +msgstr "Знайдено кілька сертифікатів підписування для сховища." #: ../fdroidserver/update.py #, python-brace-format msgid "Found multiple signing certificates in {path}" -msgstr "" +msgstr "Знайдено кілька сертифікатів для підписання на {path}" #: ../fdroidserver/index.py msgid "Found no signing certificates for repository." -msgstr "Не знайдено сертифікатів підписування для репозиторію." +msgstr "Не знайдено сертифікатів підписування для сховища." #: ../fdroidserver/lint.py #, python-format @@ -769,40 +768,38 @@ msgid "Git reset failed" msgstr "Скидання Git не вдалося" #: ../fdroidserver/common.py -#, fuzzy msgid "Git submodule sync failed" msgstr "Не вдалося синхронізувати підмодуль Git" #: ../fdroidserver/common.py -#, fuzzy msgid "Git submodule update failed" msgstr "Не вдалося оновити підмодуль Git" #: ../fdroidserver/common.py msgid "HTTPS must be used with Subversion URLs!" -msgstr "" +msgstr "HTTPS потрібно використовувати з URL-адресами Subversion!" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " -msgstr "" +msgstr "Нехтування пакунком без метаданих: " #: ../fdroidserver/update.py #, python-brace-format msgid "Ignoring stale cache data for {apkfilename}" -msgstr "" +msgstr "Нехтування застарілим кешем для {apkfilename}" #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Ignoring {ext} file at '{path}'" -msgstr "" +msgstr "Нехтування файлом {ext} у '{path}'" #: ../fdroidserver/update.py msgid "Include APKs that are signed with disabled algorithms like MD5" -msgstr "" +msgstr "Включити APK, які підписані без алгоритмів, таких як MD5" #: ../fdroidserver/common.py msgid "Initialising submodules" -msgstr "" +msgstr "Під'єднання підмодулів" #: ../fdroidserver/install.py msgid "Install all signed applications available" @@ -815,12 +812,12 @@ msgstr "Встановити побудовані пакети на пристр #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" -msgstr "" +msgstr "Встановлення %s…" #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" -msgstr "" +msgstr "Встановлення '{apkfilename}' на {dev}…" #: ../fdroid msgid "Interact with the repo HTTP server" @@ -828,107 +825,105 @@ msgstr "Взаємодія з HTTP-сервером сховища" #: ../fdroidserver/update.py msgid "Invalid APK" -msgstr "" +msgstr "Недійсний APK" #: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py #, python-brace-format msgid "Invalid VercodeOperation: {field}" -msgstr "" +msgstr "Недійсна VercodeOperation: {field}" #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" -msgstr "" +msgstr "Недійсний логічний '%s'" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid build flag at {line} in {linedesc}" -msgstr "" +msgstr "Недійсний прапорець збірки у рядку {line} в {linedesc}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid build format: {value} in {name}" -msgstr "" +msgstr "Недійсний формат збірки: {value} у {name}" #: ../fdroidserver/lint.py msgid "Invalid bulleted list" -msgstr "" +msgstr "Недійсний розмічений список" #: ../fdroidserver/lint.py #, python-format msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" -msgstr "" +msgstr "Недійсна мітка ліцензії \"%s\"! Використовуйте лише мітки з https://spdx.org/license-list" #: ../fdroidserver/lint.py msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" -msgstr "" +msgstr "Недійсне посилання — використовуйте [http://foo.bar текст посилання] чи [http://foo.bar]" #: ../fdroidserver/metadata.py #, python-format msgid "Invalid metadata in %s:%d" -msgstr "" +msgstr "Недійсні метадані у %s: %d" #: ../fdroidserver/metadata.py msgid "Invalid metadata in: " -msgstr "" +msgstr "Недійсні метадані в: " #: ../fdroidserver/common.py #, python-format msgid "Invalid name for published file: %s" -msgstr "" +msgstr "Неправильне ім'я для оприлюдненого файлу: %s" #: ../fdroidserver/common.py #, python-brace-format msgid "Invalid package name {0}" -msgstr "" +msgstr "Неправильна назва пакунку {0}" #: ../fdroidserver/common.py #, python-brace-format msgid "Invalid redirect to non-HTTPS: {before} -> {after} " -msgstr "" +msgstr "Недійсне переспрямування на не-HTTPS: {before} -> {after} " #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" -msgstr "" +msgstr "Недійсний versionCode: \"{versionCode}\" не є цілим числом!" #: ../fdroidserver/common.py #, python-brace-format msgid "JAR signature failed to verify: {path}" -msgstr "" +msgstr "Підпис JAR не вдалося перевірити: {path}" #: ../fdroidserver/common.py #, python-brace-format msgid "JAR signature verified: {path}" -msgstr "" +msgstr "Підтверджено підпис JAR: {path}" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" -msgstr "" +msgstr "Java JDK не знайдено! Встановіть в усталеному розташуванні або встановіть java_paths!" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" -msgstr "" +msgstr "Jarsigner Java не знайдено! Встановіть в усталеному розташуванні або встановіть java_paths!" #: ../fdroidserver/lint.py msgid "Javascript in HTML src attributes" -msgstr "" +msgstr "В атрибутах джерельного HTML коду міститься Javascript" #: ../fdroidserver/init.py -#, fuzzy msgid "Keystore for signing key:\t" -msgstr "Шлях до сховища ключа для підписного ключа репозиторія" +msgstr "Шлях до сховища ключів для ключа підпису сховища\t" #: ../fdroidserver/lint.py #, python-brace-format msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" -msgstr "" +msgstr "Останнє подання '{commit}' виглядає як мітка, але в режимі перевірки оновлення '{ucm}'" #: ../fdroidserver/lint.py -#, fuzzy msgid "Liberapay donation methods belong in the LiberapayID flag" -msgstr "Методи донорства Flattr належать до прапора FlattrID" +msgstr "Методи допомоги Flattr належать до прапора FlattrID" #: ../fdroidserver/rewritemeta.py msgid "List files that would be reformatted" @@ -936,7 +931,7 @@ msgstr "Список файлів, які будуть переформатов #: ../fdroidserver/lint.py msgid "Locale included in f-droid.org URL" -msgstr "" +msgstr "Переклад включено до URL-адреси f-droid.org" #: ../fdroidserver/build.py msgid "Make the build stop on exceptions" @@ -944,140 +939,139 @@ msgstr "Зробити зупинку створення за винятками #: ../fdroidserver/index.py msgid "Malformed repository mirrors." -msgstr "" +msgstr "Несправні дзеркала сховища." #: ../fdroidserver/server.py msgid "Malformed serverwebroot line:" -msgstr "" +msgstr "Несправний шлях serverwebroot:" #: ../fdroidserver/gpgsign.py msgid "Missing output directory" -msgstr "" +msgstr "Відсутній вихідний шлях" #: ../fdroidserver/lint.py #, python-format msgid "Name '%s' is just the auto name - remove it" -msgstr "" +msgstr "Назву '%s' — створено самочинно, вилучіть її" #: ../fdroidserver/common.py msgid "No 'config.py' found, using defaults." -msgstr "" +msgstr "Не знайдено 'config.py', використовуючи типові налаштування." #: ../fdroidserver/common.py msgid "No Android SDK found!" -msgstr "" +msgstr "Не знайдено Android SDK!" #: ../fdroidserver/import.py msgid "No android or kivy project could be found. Specify --subdir?" -msgstr "" +msgstr "Не знайдено жодного Android чи kivy проєкту. Вказати його у --subdir?" #: ../fdroidserver/install.py msgid "No attached devices found" -msgstr "" +msgstr "Не знайдено приєднаних пристроїв" #: ../fdroidserver/metadata.py #, python-brace-format msgid "No commit specified for {versionName} in {linedesc}" -msgstr "" +msgstr "У версії {linedesc} не вказано поданнь для {versionName}" #: ../fdroidserver/index.py msgid "No fingerprint in URL." -msgstr "" +msgstr "Немає власного цифрового відбитка в URL-адресі." #: ../fdroidserver/common.py msgid "No git submodules available" -msgstr "" +msgstr "Немає доступних підмодулів git" #: ../fdroidserver/import.py msgid "No information found." -msgstr "" +msgstr "Подробиць не знайдено." #: ../fdroidserver/lint.py msgid "No need to specify that the app is Free Software" -msgstr "" +msgstr "Не має потреби вказувати, що застосунок є вільним ПЗ" #: ../fdroidserver/lint.py msgid "No need to specify that the app is for Android" -msgstr "" +msgstr "Не має потреби вказувати, що застосунок призначено для Android" #: ../fdroidserver/server.py msgid "No option set! Edit your config.py to set at least one of these:" -msgstr "" +msgstr "Недостатньо параметрів! Змініть свій config.py, щоб встановити принаймні один з цих:" #: ../fdroidserver/common.py msgid "No packages specified" -msgstr "" +msgstr "Пакунків не вказано" #: ../fdroidserver/install.py #, python-format msgid "No signed apk available for %s" -msgstr "" +msgstr "Немає підписаних apk для %s" #: ../fdroidserver/install.py msgid "No signed output directory - nothing to do" -msgstr "" +msgstr "Немає підписаного вихідного шляху — нічого виконувати" #: ../fdroidserver/update.py #, python-brace-format msgid "No signing certificates found in {path}" -msgstr "" +msgstr "У {path} не знайдено сертифікатів для підписання" #: ../fdroidserver/common.py #, python-format msgid "No such package: %s" -msgstr "" +msgstr "Такого пакунка немає: %s" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py #, python-brace-format msgid "No such versionCode {versionCode} for app {appid}" -msgstr "" +msgstr "Немає такого versionCode {versionCode} для застосунку {appid}" #: ../fdroidserver/verify.py ../fdroidserver/publish.py msgid "No unsigned directory - nothing to do" -msgstr "" +msgstr "Немає непідписаної теки — нічого виконувати" #: ../fdroidserver/signindex.py msgid "Nothing to do" -msgstr "" +msgstr "Нічого виконувати" #: ../fdroidserver/checkupdates.py #, python-brace-format msgid "Nothing to do for {appid}." -msgstr "" +msgstr "Для {appid} нічого виконувати." #: ../fdroidserver/init.py -#, fuzzy msgid "Now set these in config.py:" -msgstr "'sdk_path' не встановлено в 'config.py'!" +msgstr "Тепер встановіть їх у config.py:" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py #, python-brace-format msgid "OBB file has newer versionCode({integer}) than any APK:" -msgstr "" +msgstr "OBB-файл має новішу версію коду ({integer}), ніж будь-який APK:" #: ../fdroidserver/update.py msgid "OBB filename must start with \"main.\" or \"patch.\":" -msgstr "" +msgstr "Назва файлу OBB повинна починатися з \"main.\" або \"patch.\":" #: ../fdroidserver/update.py msgid "OBB's packagename does not match a supported APK:" -msgstr "" +msgstr "Назва пакунку OBB не відповідає підтримуваному APK:" #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" -msgstr "" +msgstr "Не вдалося підтвердити старий підпис APK: {path}" #: ../fdroid msgid "Old, deprecated name for fdroid deploy" -msgstr "" +msgstr "Застаріла назва розгортання (deploy) fdroid" #: ../fdroidserver/update.py #, python-brace-format msgid "Only PNG and JPEG are supported for graphics, found: {path}" -msgstr "" +msgstr "Підтримуються лише PNG та JPEG зображення, знайдено: {path}" #: ../fdroidserver/checkupdates.py msgid "Only print differences with the Play Store" @@ -1094,7 +1088,7 @@ msgstr "Параметри" #: ../fdroidserver/verify.py msgid "Output JSON report to file named after APK." -msgstr "" +msgstr "Виведіть JSON-звіт у назві файлу APK." #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1102,26 +1096,25 @@ msgstr "Загальна ліцензія проекту." #: ../fdroidserver/dscanner.py msgid "Override path for repo APKs (default: ./repo)" -msgstr "Перевизначити шлях для APK-файлів комори даних (усталено: ./repo)" +msgstr "Перевизначити шлях для сховища APK-файлів (типово: ./repo)" #: ../fdroidserver/index.py #, python-brace-format msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" -msgstr "" +msgstr "Перезапис порожнього versionName у {apkfilename} з метаданих: {version}" #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" -msgstr "" +msgstr "Читання маніфесту у '{path}'" #: ../fdroidserver/common.py msgid "Password required with username" -msgstr "" +msgstr "Потрібен парольіз іменем користувача" #: ../fdroidserver/import.py -#, fuzzy msgid "Path to main Android project subdirectory, if not in root." -msgstr "Шлях до основного підкаталогу андроїда, якщо не в кореневому каталозі." +msgstr "Шлях до основного підкаталогу проєкту Android, якщо не в кореневому каталозі." msgid "Path to main android project subdirectory, if not in root." msgstr "Шлях до основного підкаталогу андроїда, якщо не в кореневому каталозі." @@ -1132,33 +1125,32 @@ msgstr "Шлях до Android SDK (іноді встановлено в ANDROID_ #: ../fdroidserver/btlog.py msgid "Path to the git repo to use as the log" -msgstr "Шлях до git комори даних, який використовується для входу" +msgstr "Шлях до сховища git, яке використовується для входу" #: ../fdroidserver/init.py msgid "Path to the keystore for the repo signing key" -msgstr "Шлях до сховища ключа для підписного ключа комори даних" +msgstr "Шлях до сховища ключа для підписного ключа сховища" #: ../fdroidserver/dscanner.py -#, fuzzy msgid "Prepare Drozer to run a scan" -msgstr "Підготувати drozer для запуску сканування" +msgstr "Підготувати Drozer до початку сканування" msgid "Prepare drozer to run a scan" msgstr "Підготувати drozer для запуску сканування" #: ../fdroidserver/nightly.py msgid "Print the secret variable to the terminal for easy copy/paste" -msgstr "" +msgstr "Вивести таємну змінну до термінала для легкого копіювання/вставлення" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Problem with description of {appid}: {error}" -msgstr "" +msgstr "Проблема з описом {appid}: {error}" #: ../fdroidserver/common.py #, python-brace-format msgid "Problem with xml at '{path}'" -msgstr "" +msgstr "Проблема з xml у '{path}'" #: ../fdroidserver/checkupdates.py msgid "Process auto-updates" @@ -1167,17 +1159,16 @@ msgstr "Процес автоматичних оновлень" #: ../fdroidserver/publish.py ../fdroidserver/update.py #, python-brace-format msgid "Processing {apkfilename}" -msgstr "" +msgstr "Обробка {apkfilename}" #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py #, python-brace-format msgid "Processing {appid}" -msgstr "" +msgstr "Обробка {appid}" #: ../fdroidserver/update.py -#, fuzzy msgid "Produce human-readable XML/JSON for index files" -msgstr "Створити зручний для сприйняття index.xml" +msgstr "Створити доступний для читання людиною XML/JSON для індексування файлів" #: ../fdroidserver/update.py msgid "Produce human-readable index.xml" @@ -1189,21 +1180,21 @@ msgstr "URL-адреса проекту для імпорту." #: ../fdroidserver/lint.py msgid "Punctuation should be avoided" -msgstr "" +msgstr "Слід уникати пунктуації" #: ../fdroidserver/btlog.py msgid "Push the log to this git remote repository" msgstr "Натисніть вхід цього віддаленого сховища git" #: ../fdroidserver/server.py ../fdroidserver/upload.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Pushing binary transparency log to {url}" -msgstr "Оновити бінарний журнал прозорості для {url}" +msgstr "Оновити двійковий журнал прозорості для {url}" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" -msgstr "" +msgstr "Оприлюднення до {url}" #: ../fdroid msgid "Quickly start a new repository" @@ -1216,24 +1207,24 @@ msgstr "Прочитайте всі файли метаданих і вийді #: ../fdroidserver/common.py #, python-brace-format msgid "Reading '{config_file}'" -msgstr "" +msgstr "Читання '{config_file}'" #: ../fdroidserver/common.py #, python-brace-format msgid "Reading minSdkVersion failed: \"{apkfilename}\"" -msgstr "" +msgstr "Не вдалося прочитати minSdkVersion: \"{apkfilename}\"" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/common.py #, python-brace-format msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" -msgstr "" +msgstr "Помилка packageName/versionCode/versionName, APK недійсне: '{apkfilename}'" #: ../fdroidserver/update.py #, python-brace-format msgid "Reading {apkfilename} from cache" -msgstr "" +msgstr "Читання {apkfilename} з кешу" #: ../fdroidserver/stats.py msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." @@ -1241,7 +1232,7 @@ msgstr "Перерахуйте сукупну статистику - викор #: ../fdroidserver/common.py msgid "Removing specified files" -msgstr "" +msgstr "Вилучення вказаних файлів" #: ../fdroidserver/update.py msgid "Rename APK files that do not match package.name_123.apk" @@ -1258,7 +1249,7 @@ msgstr "Перезавантажте та створіть новий серве #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" -msgstr "" +msgstr "Повторне підписання {apkfilename} з наданим debug.keystore" #: ../fdroidserver/update.py msgid "Resize all the icons exceeding the max pixel size and exit" @@ -1279,16 +1270,16 @@ msgstr "Переписати в певний формат: " #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Rewriting '{appid}'" -msgstr "" +msgstr "Перезапис '{appid}'" #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Rewriting '{appid}' to '{path}'" -msgstr "" +msgstr "Перезапис '{appid}' на '{path}'" #: ../fdroidserver/checkupdates.py msgid "Run on git repo that has uncommitted changes" -msgstr "" +msgstr "Запустити на git сховище, яке не подало зміни" #: ../fdroidserver/lint.py msgid "Run rewritemeta to fix formatting" @@ -1296,12 +1287,12 @@ msgstr "Запустити rewritemeta виправити форматуванн #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" -msgstr "" +msgstr "Запуск першого проходу з вимкненою перевіркою MD5" #: ../fdroidserver/mirror.py #, python-brace-format msgid "Running wget in {path}" -msgstr "" +msgstr "Запуск wget у {path}" #: ../fdroidserver/dscanner.py msgid "Scan only the latest version of each package" @@ -1314,46 +1305,45 @@ msgstr "Сканування вихідного коду пакета" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Scanner found {count} problems in {appid}:" -msgstr "" +msgstr "Зчитувач знайшов {count} проблеми в {appid}:" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Scanner found {count} problems in {appid}:{versionCode}:" -msgstr "" +msgstr "Зчитувач знайшов {count} проблеми в {appid}: {versionCode}:" #: ../fdroidserver/build.py msgid "Scanner found {} problem" msgid_plural "Scanner found {} problems" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "Знайдено {} проблему" +msgstr[1] "Знайдено {} проблеми" +msgstr[2] "Знайдено {} проблем" #: ../fdroidserver/common.py msgid "Set clock to that time using:" -msgstr "" +msgstr "Встановіть годинник на цей час, використовуючи:" #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" -msgstr "" +msgstr "Встановити обмеження відкритого файлу на {integer}" #: ../fdroid msgid "Set up an app build for a nightly build repo" -msgstr "" +msgstr "Налаштувати застосунок для збірки сховища в нічний час" #: ../fdroidserver/build.py msgid "Setting open file limit failed: " -msgstr "" +msgstr "Не вдалося встановити обмеження кількості одночасно відкритих файлів: " #: ../fdroidserver/build.py #, python-brace-format msgid "Setting {0} sec timeout for this build" -msgstr "" +msgstr "Час очікування для цієї збірки становить {0}" #: ../fdroidserver/build.py -#, fuzzy msgid "Setup an emulator, install the APK on it and perform a Drozer scan" -msgstr "Налаштуйте емулятор, встановіть apk на нього та виконайте drozer сканування" +msgstr "Налаштуйте емулятор, встановіть на нього APK та виконайте сканування з Drozer" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Налаштуйте емулятор, встановіть apk на нього та виконайте drozer сканування" @@ -1373,31 +1363,31 @@ msgstr "Пропустити сканування вихідного коду д #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping '{apkfilename}' with invalid signature!" -msgstr "" +msgstr "Недійсний підпис '{apkfilename}', пропускаємо!" #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping index generation for {appid}" -msgstr "" +msgstr "Пропуск створення індексу для {appid}" #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping {apkfilename} with invalid signature!" -msgstr "" +msgstr "Недійсний підпис {apkfilename}, пропускаємо!" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Skipping {appid}: disabled" -msgstr "" +msgstr "Пропуск {appid}: вимкнено" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Skipping {appid}: no builds specified" -msgstr "" +msgstr "Пропуск {appid}: жодних збірок не вказано" #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" -msgstr "Вкажіть локальну теку, аби синхронізувати комору даних у" +msgstr "Вкажіть локальну теку, аби синхронізувати сховище у" #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" @@ -1409,106 +1399,105 @@ msgstr "Вкажіть, що ми працюємо на сервері ство #: ../fdroidserver/nightly.py msgid "Specify which debug keystore file to use." -msgstr "" +msgstr "Вкажіть, який файл зневадження сховища ключів застосовувати." #: ../fdroidserver/common.py msgid "Spew out even more information than normal" -msgstr "Випишіть ще більше інформації, ніж звичайно" +msgstr "Випишіть ще більше даних, ніж звичайно" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Striping mystery signature from {apkfilename}" -msgstr "Не вдалося завантажити підписи для '{apkfilename}': {error}" +msgstr "Видалення невідомого підпису для {apkfilename}" #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" -msgstr "" +msgstr "Опис '%s' — це лише назва застосунку" #: ../fdroidserver/lint.py #, python-brace-format msgid "Summary of length {length} is over the {limit} char limit" -msgstr "" +msgstr "Довжина опису {length} перевищує обмеження {limit} знаків" #: ../fdroidserver/common.py #, python-brace-format msgid "System clock is older than date in {path}!" -msgstr "" +msgstr "Системний годинник відстає від date в {path}!" #: ../fdroidserver/build.py msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." -msgstr "Режим тесту - надсилайте випуск тільки в каталог tmp, і завжди створюйте, навіть якщо випуск вже існує." +msgstr "Тестовий режим - надсилайте випуск лише в каталозі tmp і завжди створюйте його, навіть якщо випуск вже існує." #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py #, python-brace-format msgid "The OBB version code must come after \"{name}.\":" -msgstr "" +msgstr "Код версії OBB повинен надходити після \"{name}.\":" #: ../fdroidserver/btlog.py msgid "The base URL for the repo to log (default: https://f-droid.org)" -msgstr "Базова URL-адреса для входу до комори даних (усталено: https://f-droid.org)" +msgstr "Базова URL-адреса для входу до сховища (усталено: https://f-droid.org)" #: ../fdroidserver/mirror.py msgid "The directory to write the mirror to" -msgstr "" +msgstr "Каталог для запису дзеркала" #: ../fdroidserver/nightly.py msgid "The file to be included in the repo (path or glob)" -msgstr "" +msgstr "Файл, який слід включити до сховища (шлях чи шаблон шляху)" #: ../fdroidserver/server.py -#, fuzzy msgid "The only commands currently supported are 'init' and 'update'" -msgstr "команда виконати, 'init' або 'update'" +msgstr "Підтримуються лише команди 'init' або 'update'" #: ../fdroidserver/index.py msgid "The repository's fingerprint does not match." -msgstr "" +msgstr "Цифровий відбиток сховища не збігається." #: ../fdroidserver/common.py msgid "The repository's index could not be verified." -msgstr "" +msgstr "Не вдалося перевірити індекс сховища." #: ../fdroidserver/server.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" -msgstr "" +msgstr "Кореневої теки local_copy_dir \"{path}\" не існує!" #: ../fdroidserver/publish.py msgid "There is a keyalias collision - publishing halted" -msgstr "" +msgstr "Відбулося зіткнення keyalias ключів - припинення оприлюднення" #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" -msgstr "Комора даних вже має локальні метадані: %s" +msgstr "Сховище вже має локальні метадані: %s" #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" -msgstr "" +msgstr "Для використання awsbucket, awssecretkey та awsaccesskeyid також слід налаштувати config.py!" #: ../fdroidserver/lint.py msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "" +msgstr "Режим перевірки оновлень встановлено, але схоже, що ще не запущено перевірку" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" -msgstr "" +msgstr "Скорочувачі URL-адрес не варто використовувати" #: ../fdroidserver/metadata.py msgid "URL title is just the URL, use brackets: [URL]" -msgstr "" +msgstr "Заголовок URL - це лише текст URL, користуйтеся дужками: [URL]" #: ../fdroidserver/lint.py #, python-brace-format msgid "URL {url} in Description: {error}" -msgstr "" +msgstr "URL {url} в описі: {error}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" -msgstr "" +msgstr "Несподіваний текст у тому ж рядку, що і {field} у {linedesc}" #: ../fdroid msgid "Unknown exception found!" @@ -1518,12 +1507,12 @@ msgstr "Виявлено невідому виняткову ситуацію!" #: ../fdroidserver/lint.py #, python-brace-format msgid "Unknown file '{filename}' in build '{versionName}'" -msgstr "" +msgstr "Невідомий файл '{filename}' в збірці '{versionName}'" #: ../fdroidserver/metadata.py #, python-format msgid "Unknown metadata format: %s" -msgstr "" +msgstr "Невідомий формат метаданих: %s" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1532,85 +1521,85 @@ msgstr "Створення скелетів файлів метаданих: {pa #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " -msgstr "" +msgstr "Невідома версія aapt, може спричинити складнощі: " #: ../fdroidserver/lint.py msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" -msgstr "" +msgstr "Неправильне посилання - використовуйте [http://foo.bar текст посилання] чи [http://foo.bar]" #: ../fdroidserver/lint.py msgid "Unnecessary leading space" -msgstr "" +msgstr "Непотрібна прогалина на початку рядка" #: ../fdroidserver/lint.py msgid "Unnecessary trailing space" -msgstr "" +msgstr "Зайва прогалина в кінці" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unrecognised app field '{fieldname}' in '{path}'" -msgstr "" +msgstr "Нерозпізнане поле застосунку '{fieldname}' в '{path}'" #: ../fdroidserver/metadata.py msgid "Unrecognised app field: " -msgstr "" +msgstr "Нерозпізнане поле застосунку: " #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unrecognised build flag '{build_flag}' in '{path}'" -msgstr "" +msgstr "Нерозпізнаний прапорець збірки '{build_flag}' у '{path}'" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unrecognised field '{field}' in {linedesc}" -msgstr "" +msgstr "Нерозпізнане поле '{field}' у {linedesc}" #: ../fdroidserver/update.py #, python-brace-format msgid "Unsupported file type \"{extension}\" for repo graphic" -msgstr "Файловий тип не підтримується \"{extension}\" для графіки комори даних" +msgstr "Файловий тип не підтримується \"{extension}\" для сховища графіки" #: ../fdroidserver/update.py #, python-brace-format msgid "Unsupported graphics file found: {path}" -msgstr "" +msgstr "Знайдено непідтримуване зображення: {path}" #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Unsupported metadata format, use: --to [{supported}]" -msgstr "" +msgstr "Непідтримуваний формат метаданих, використовуйте: --to [{supported}]" #: ../fdroidserver/metadata.py msgid "Unterminated ]" -msgstr "" +msgstr "Пропущено дужку - ]" #: ../fdroidserver/metadata.py msgid "Unterminated ]]" -msgstr "" +msgstr "Пропущено подвійну дужку - ]]" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unterminated build in {name}" -msgstr "" +msgstr "Невстановлена збірка в {name}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unterminated continuation in {name}" -msgstr "" +msgstr "Незавершене продовження рядка у {name}" #: ../fdroidserver/lint.py #, python-format msgid "Unused extlib at %s" -msgstr "" +msgstr "Невикористаний extlib у %s" #: ../fdroidserver/lint.py #, python-format msgid "Unused file at %s" -msgstr "" +msgstr "Невикористаний файл у %s" #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" -msgstr "" +msgstr "Назву застосунку для перевірки оновлень встановлено на відомий id застосунку - його можна буде вилучити" #: ../fdroid msgid "Update repo information for new packages" @@ -1631,17 +1620,17 @@ msgstr "Оновити вікі" #: ../fdroidserver/checkupdates.py #, python-brace-format msgid "UpdateCheckData has invalid URL: {url}" -msgstr "" +msgstr "UpdateCheckData має недійсну URL-адресу: {url}" #: ../fdroidserver/lint.py #, python-brace-format msgid "UpdateCheckData must use HTTPS URL: {url}" -msgstr "" +msgstr "UpdateCheckData має використовувати URL-адресу HTTPS: {url}" #: ../fdroidserver/lint.py #, python-brace-format msgid "UpdateCheckData not a valid URL: {url}" -msgstr "" +msgstr "UpdateCheckData не є дійсною URL-адресою: {url}" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1656,20 +1645,19 @@ msgstr "Використання: %s\n" #: ../fdroidserver/lint.py msgid "Use /HEAD instead of /master to point at a file in the default branch" -msgstr "" +msgstr "Використовуйте /HEAD замість /master для вказання на файл типовій гілці" #: ../fdroidserver/update.py msgid "Use `fdroid update -c` to create it." -msgstr "" +msgstr "Використовуйте `fdroid update -c`, щоб створити файли метаданих." #: ../fdroidserver/build.py msgid "Use build server" msgstr "Використовуйте сервер створення" #: ../fdroidserver/update.py -#, fuzzy msgid "Use date from APK instead of current time for newly added APKs" -msgstr "Використовуйте дату з apk, замість поточного часу для нових доданих apks" +msgstr "Використовуйте дату з APK замість поточного часу для нових доданих APK" msgid "Use date from apk instead of current time for newly added apks" msgstr "Використовуйте дату з apk, замість поточного часу для нових доданих apks" @@ -1677,26 +1665,26 @@ msgstr "Використовуйте дату з apk, замість поточ #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." -msgstr "" +msgstr "Використання \"{path}\" для налаштування s3cmd." #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" -msgstr "" +msgstr "Не варто перевіряти APK за допомогою jarsigner Java! Користуйтеся apksigner" #: ../fdroidserver/common.py #, python-brace-format msgid "Using androguard from \"{path}\"" -msgstr "" +msgstr "Використання androguard від \"{path}\"" #: ../fdroidserver/init.py #, python-brace-format msgid "Using existing keystore \"{path}\"" -msgstr "" +msgstr "Застосування наявного сховища ключів \"{path}\"" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" -msgstr "" +msgstr "Використовувати s3cmd для синхронізації з: {url}" #: ../fdroid msgid "Valid commands are:" @@ -1704,7 +1692,7 @@ msgstr "Дійсні команди:" #: ../fdroidserver/verify.py msgid "Verify against locally cached copy rather than redownloading." -msgstr "" +msgstr "Перевіряти, за допомогою локальної кешованої копії замість повторного завантаження." #: ../fdroid msgid "Verify the integrity of downloaded packages" @@ -1712,7 +1700,7 @@ msgstr "Перевірте цілісність завантажених пак #: ../fdroidserver/index.py msgid "Verifying index signature:" -msgstr "" +msgstr "Перевірка підпису індексу:" #: ../fdroid msgid "Warn about possible metadata errors" @@ -1726,23 +1714,22 @@ msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Distiguished Name' використовується при створенні ключів" #: ../fdroidserver/init.py -#, fuzzy msgid "X.509 'Distinguished Name' used when generating keys" -msgstr "X.509 'Distiguished Name' використовується при створенні ключів" +msgstr "X.509 'Distiguished Name' використовується під час створення ключів" #: ../fdroidserver/common.py msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" -msgstr "" +msgstr "За допомогою ANDROID_HOME можна встановити шлях до SDK, тобто:" #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" -msgstr "" +msgstr "додавання IdentityFile до {path}" #: ../fdroidserver/update.py #, python-brace-format msgid "adding to {name}: {path}" -msgstr "" +msgstr "додавання до {name}: {path}" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -1757,32 +1744,29 @@ msgid "ambiguous option: %s (%s?)" msgstr "неоднозначний параметр: %s (%s?)" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py -#, fuzzy msgid "applicationId in the form APPID" -msgstr "app-id у формі APPID" +msgstr "applicationId у формі APPID" #: ../fdroidserver/checkupdates.py -#, fuzzy msgid "applicationId to check for updates" -msgstr "app-id для перевірки наявність оновлень" +msgstr "applicationId для перевірки наявності оновлень" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/dscanner.py ../fdroidserver/build.py #: ../fdroidserver/scanner.py ../fdroidserver/install.py -#, fuzzy msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" -msgstr "app-id з необов'язковою версією коду у формі APPID[:VERCODE]" +msgstr "applicationId з необов'язковим versionCode у формі APPID[:VERCODE]" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "argument \"-\" with mode %r" -msgstr "" +msgstr "аргумент \"-\" в режимі %r" #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" -msgstr "" +msgstr "спроба відкритого з'єднання ssh для перевірки ключа розгортання:" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -1793,22 +1777,22 @@ msgstr "не може відкрити '%s': %s" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" -msgstr "" +msgstr "не може мати кілька аргументів підпарсера" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "cannot merge actions - two groups are named %r" -msgstr "" +msgstr "не може об'єднати дії - дві групи мають ім'я %r" #: ../fdroidserver/nightly.py msgid "cannot publish update, did you set the deploy key?" -msgstr "" +msgstr "не вдалося оприлюднити оновлення. Ви встановили ключ розгортання?" #: ../fdroidserver/nightly.py #, python-brace-format msgid "cloning {url}" -msgstr "" +msgstr "клонування {url}" #: ../fdroidserver/server.py msgid "command to execute, either 'init' or 'update'" @@ -1817,171 +1801,167 @@ msgstr "команда виконати, 'init' або 'update'" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" -msgstr "" +msgstr "complex" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "суперечний рядок параметра: %s" +msgstr[1] "суперечних рядка параметра: %s" +msgstr[2] "суперечних рядків параметра: %s" #: ../fdroidserver/nightly.py #, python-brace-format msgid "copying {apkfilename} into {path}" -msgstr "" +msgstr "копіювання {apkfilename} у {path}" #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" -msgstr "" +msgstr "створено {path}" #: ../fdroidserver/update.py #, python-brace-format msgid "deleting: repo/{apkfilename}" -msgstr "видалення: комора даних/{apkfilename}" +msgstr "видалення: сховище/{apkfilename}" #: ../fdroidserver/common.py #, python-brace-format msgid "deployed build logs to '{path}'" -msgstr "" +msgstr "розгорнуто журнали збірки до '{path}'" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" -msgstr "" +msgstr "dest= потрібен для таких варіантів, як %r" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "очікується %s аргумент" +msgstr[1] "очікується %s аргументи" +msgstr[2] "очікується %s аргументів" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "expected at least one argument" -msgstr "" +msgstr "очікується хоча б один аргумент" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "expected at most one argument" -msgstr "" +msgstr "очікується не більше одного аргументу" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "expected one argument" -msgstr "" +msgstr "очікується один аргумент" #: ../fdroidserver/common.py #, python-brace-format msgid "failed deploying build logs to '{path}'" -msgstr "" +msgstr "не вдалося розгорнути журнали збірки до '{path}'" #: ../fdroid -#, fuzzy msgid "fdroid [-h|--help|--version] []" -msgstr "використання: fdroid [-h|--help|--version] <команда> [<аргументи>]" +msgstr "fdroid [-h|--help|--version] <команда> [<аргументи>]" #: ../fdroid -#, fuzzy msgid "fdroid [] [-h|--help|--version|]" -msgstr "використання: fdroid [-h|--help|--version] <команда> [<аргументи>]" +msgstr "fdroid [<команда>] [-h|--help|--version|<аргументи>]" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "floating-point" -msgstr "" +msgstr "з комою, що плаває" #: ../fdroidserver/metadata.py msgid "force errors to be warnings, or ignore" msgstr "примусити попереджувати помилки, або ігнорувати" #: ../fdroidserver/metadata.py -#, fuzzy msgid "force metadata errors (default) to be warnings, or to be ignored." -msgstr "примусити попереджувати помилки, або ігнорувати" +msgstr "показувати помилки метаданих (типово), як попередження, або нехтувати ними." #: ../fdroidserver/common.py -#, fuzzy msgid "git svn clone failed" -msgstr "Очистити Git невдалося" +msgstr "Не вдалося клонувати git svn" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "ignored explicit argument %r" -msgstr "" +msgstr "нехтується явний аргумент %r" #: ../fdroidserver/index.py msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" -msgstr "" +msgstr "index-v1 повинен мати підпис, використовуйте `fdroid signindex`, щоб створити його!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "integer" -msgstr "" +msgstr "ціле число" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "invalid %(type)s value: %(value)r" -msgstr "" +msgstr "недійсне %(type)s значення: %(value)r" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" -msgstr "" +msgstr "неправильний вибір: %(value)r (варто обрати з %(choices)s)" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "invalid conflict_resolution value: %r" -msgstr "" +msgstr "недійсне значення conflict_resolution: %r" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" -msgstr "" +msgstr "неправильний рядок параметра %(option)r: повинен починатися зі знаку %(prefix_chars)r" #: ../fdroidserver/server.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" -msgstr "" +msgstr "local_copy_dir мусить закінчуватися на \"fdroid\", ймовірно, малося на увазі: \"{path}\"" #: ../fdroidserver/server.py msgid "local_copy_dir must be an absolute path!" -msgstr "" +msgstr "local_copy_dir мусить бути абсолютним шляхом!" #: ../fdroidserver/server.py msgid "local_copy_dir must be directory, not a file!" -msgstr "" +msgstr "local_copy_dir мусить бути текою, не файлом!" #: ../fdroidserver/index.py #, python-format msgid "mirror '%s' does not end with 'fdroid'!" -msgstr "" +msgstr "дзеркало '%s' не закінчується на 'fdroid'!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "mutually exclusive arguments must be optional" -msgstr "" +msgstr "взаємозаперечні аргументи повинні бути необов'язковими" #: ../fdroidserver/mirror.py #, python-brace-format msgid "no \"icon\" in {appid}" -msgstr "" +msgstr "не має \"icon\" у {appid}" #: ../fdroidserver/signatures.py msgid "no APK supplied" -msgstr "" +msgstr "APK не надано" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1990,48 +1970,47 @@ msgid "no such option: %s" msgstr "такого параметру немає: %s" #: ../fdroid -#, fuzzy msgid "no version info found!" -msgstr "Виявлено невідому виняткову ситуацію!" +msgstr "не вдалося визначити версію!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "not allowed with argument %s" -msgstr "" +msgstr "не дозволено з аргументом %s" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "one of the arguments %s is required" -msgstr "" +msgstr "потрібен один з аргументів %s" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "only accepts strings, lists, and tuples" -msgstr "" +msgstr "приймає лише рядки, списки та кортежі" #: ../fdroidserver/install.py #, python-format msgid "option %s: If you really want to install all the signed apps, use --all" -msgstr "" +msgstr "параметр %s: Якщо ви дійсно хочете встановити всі підписані застосунки, використовуйте --all" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format msgid "option %s: invalid %s value: %r" -msgstr "" +msgstr "параметр %s: недійсне %s значення: %r" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format msgid "option %s: invalid choice: %r (choose from %s)" -msgstr "" +msgstr "для параметра %s: неправильний вибір: %r (вибрати з %s)" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py #, python-format msgid "option -%s not recognized" -msgstr "параметр -%s не визнано" +msgstr "параметр -%s не розпізнано" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py @@ -2071,7 +2050,7 @@ msgstr "необов'язкові аргументи" #: ../fdroidserver/nightly.py #, python-brace-format msgid "overwriting existing {path}" -msgstr "" +msgstr "перезаписування наявного шляху {path}" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2081,17 +2060,17 @@ msgstr "позиційні аргументи" #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" -msgstr "" +msgstr "відмовитись від завантаження через небезпечне з'єднання HTTP (користати HTTPS чи вказати --no-https-check): {apkfilename}" #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" -msgstr "" +msgstr "відмовитись від завантаження через незахищене з'єднання http (користати https чи вказати --no-https-check): {apkfilename}" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" -msgstr "" +msgstr "s3cmd синхронізувати індекси з {path} до {url} та видалити" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2106,29 +2085,29 @@ msgstr "показати довідку та вийти" #: ../fdroidserver/signatures.py msgid "signed APK, either a file-path or HTTPS URL." -msgstr "" +msgstr "підписаний APK файл, шлях до файлу або URL-адреса HTTPS)." #: ../fdroidserver/common.py msgid "skip deploying full build logs: log content is empty" -msgstr "" +msgstr "пропустити розгортання усіх журналів збірки: журнал порожній" #: ../fdroidserver/common.py msgid "skip deploying full build logs: not enabled in config" -msgstr "" +msgstr "пропустити розгортання усіх журналів збірки: не увімкнено під час налаштування" #: ../fdroidserver/update.py #, python-brace-format msgid "skipping source tarball: {path}" -msgstr "" +msgstr "пропустити для архіву з джерелом: {path}" #: ../fdroidserver/lint.py msgid "srclibs missing name and/or @" -msgstr "" +msgstr "srclibs відсутнє ім’я та/чи @" #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" -msgstr "" +msgstr "надане значення часової позначки '{timestamp}' не є часовою міткою Unix" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2146,7 +2125,7 @@ msgstr "неочікуваний рядок параметрів: %s" #: /usr/lib/python3.7/argparse.py #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" -msgstr "" +msgstr "невідомий парсер %(parser_name)r (варто вибрати: %(choices)s)" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2171,115 +2150,115 @@ msgstr "використання: fdroid [-h|--help|--version] <команда> #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" -msgstr "" +msgstr "Apache libcloud: синхронізація з {url}" #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" msgid_plural "{0} apps, {1} key aliases" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "{0} застосунок, {1} alias ключів" +msgstr[1] "{0} застосунки, {1} alias ключів" +msgstr[2] "{0} застосунків, {1} {1} alias ключів" #: ../fdroidserver/update.py #, python-brace-format msgid "{apkfilename} ({appid}) has no metadata!" -msgstr "" +msgstr "{apkfilename} ({appid}) не має метаданих!" #: ../fdroidserver/update.py #, python-brace-format msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" -msgstr "" +msgstr "{apkfilename} має декілька {name} файлів, схоже на використання проблеми безпеки Master Key!" #: ../fdroidserver/update.py #, python-brace-format msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " -msgstr "" +msgstr "AndroidManifest.xml застосунка {apkfilename} має неправильну дату: " #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." -msgstr "" +msgstr "{appid} не має назви! Використовуватимуться назви пакунку." #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Android Package Name!" -msgstr "" +msgstr "{appid} з {path} є недійсною назвою пакунка Android!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" -msgstr "" +msgstr "{appid} з {path} є недійсною назвою пакунка Java!" #: ../fdroidserver/mirror.py #, python-brace-format msgid "{appid} is missing {name}" -msgstr "" +msgstr "У {appid} немає {name}" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/lint.py #, python-brace-format msgid "{appid}: Unknown extlib {path} in build '{versionName}'" -msgstr "" +msgstr "{appid}: Невідомий extlib {path} у збірці '{versionName}'" #: ../fdroidserver/scanner.py #, python-brace-format msgid "{appid}: no builds specified, running on current source state" -msgstr "" +msgstr "{appid}: жодних збірок не вказано, працює у поточному стані джерела" #: ../fdroidserver/lint.py #, python-brace-format msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" -msgstr "" +msgstr "{appid}: {field} повинен бути '{type}', а не '{fieldtype}!'" #: ../fdroidserver/lint.py #, python-brace-format msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" -msgstr "" +msgstr "{appid}: {field} повинно бути '{type}', а не '{fieldtype}'!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" -msgstr "" +msgstr "{field} не припинено в {name}" #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." -msgstr "" +msgstr "{name} \"{path}\" не існує! Виправте його в config.py." #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" -msgstr "" +msgstr "{path} не існує! Створіть його, запустивши:" #: ../fdroidserver/update.py #, python-brace-format msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" -msgstr "" +msgstr "{path}: недійсний підпис \"{pattern}\". Виглядає підозріло і схоже на спробу порушення безпеки Janus exploit!" #: ../fdroidserver/update.py #, python-brace-format msgid "{path} is zero size!" -msgstr "" +msgstr "{path} не має розміру!" #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" -msgstr "" +msgstr "{url} не закінчується на \"fdroid\", перевірте шлях URL!" #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "{} не вдалося створити" +msgstr[1] "{} не вдалося створити" +msgstr[2] "{} не вдалося створити" #: ../fdroidserver/build.py msgid "{} build succeeded" msgid_plural "{} builds succeeded" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "{} зібрано успішно" +msgstr[1] "{} зібрано успішно" +msgstr[2] "{} зібрано успішно" #~ msgid "Interactively ask about things that need updating." #~ msgstr "Інтерактивно запитайте про речі, які потребують оновлення." From 40dc54506dfe73c5c7ad8909d0edc4afca7b25ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Marcelo=20Alvarenga?= Date: Thu, 1 Oct 2020 11:00:44 +0200 Subject: [PATCH 0508/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Portu?= =?UTF-8?q?guese=20(Brazil)=20(pt=5FBR)=20by=20Andr=C3=A9=20Marcelo=20Alva?= =?UTF-8?q?renga=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (477 of 477 strings) Co-authored-by: André Marcelo Alvarenga Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translation: F-Droid/F-Droid Server --- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 27 ++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index b4c33c41..228b5982 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # Wellington Terumi Uemura , 2020. +# André Marcelo Alvarenga , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-03 03:55+0000\n" -"Last-Translator: Wellington Terumi Uemura \n" +"PO-Revision-Date: 2020-05-16 20:31+0000\n" +"Last-Translator: André Marcelo Alvarenga \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\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 4.0-dev\n" +"X-Generator: Weblate 4.1-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -718,7 +719,7 @@ msgstr "Encontrado versões de códigos inválidas para alguns aplicativos" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" -msgstr "Encontrados vários ficheiros de metadados para {appid}" +msgstr "Encontrados vários arquivos de metadados para {appid}" #: ../fdroidserver/index.py msgid "Found multiple signing certificates for repository." @@ -1441,7 +1442,7 @@ msgstr "O diretório para escrever o espelho para" #: ../fdroidserver/nightly.py msgid "The file to be included in the repo (path or glob)" -msgstr "O ficherio a ser incluído no repo (caminho ou glob)" +msgstr "O arquivo a ser incluído no repositório (caminho ou glob)" #: ../fdroidserver/server.py msgid "The only commands currently supported are 'init' and 'update'" @@ -1497,13 +1498,13 @@ msgstr "Texto inesperado na mesma linha como {field} em {linedesc}" #: ../fdroid msgid "Unknown exception found!" -msgstr "Uma exceção desconhecida foi encrontrada!" +msgstr "Exceção desconhecida encontrada!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/lint.py #, python-brace-format msgid "Unknown file '{filename}' in build '{versionName}'" -msgstr "Ficheiro desconhecido '{filename}' na compilação '{versionName}'" +msgstr "Arquivo desconhecido '{filename}' na compilação '{versionName}'" #: ../fdroidserver/metadata.py #, python-format @@ -1553,12 +1554,12 @@ msgstr "Campo '{field}' não reconhecido em {linedesc}" #: ../fdroidserver/update.py #, python-brace-format msgid "Unsupported file type \"{extension}\" for repo graphic" -msgstr "Tipo de ficheiro \"{extension}\" não suportado para o gráfico de repo" +msgstr "Tipo de arquivo \"{extension}\" não suportado para o gráfico de repo" #: ../fdroidserver/update.py #, python-brace-format msgid "Unsupported graphics file found: {path}" -msgstr "Ficheiro gráfico não suportado encontrado: {path}" +msgstr "Arquivo gráfico não suportado encontrado: {path}" #: ../fdroidserver/rewritemeta.py #, python-brace-format @@ -1591,7 +1592,7 @@ msgstr "Extlib não utilizado em %s" #: ../fdroidserver/lint.py #, python-format msgid "Unused file at %s" -msgstr "Ficheiro não utilizado em %s" +msgstr "Arquivo não utilizado em %s" #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" @@ -1641,7 +1642,7 @@ msgstr "Uso: %s\n" #: ../fdroidserver/lint.py msgid "Use /HEAD instead of /master to point at a file in the default branch" -msgstr "Use /HEAD em vez de /master para apontar em um ficheiro na ramificação predefinida" +msgstr "Use /HEAD em vez de /master para apontar em um arquivo na ramificação predefinida" #: ../fdroidserver/update.py msgid "Use `fdroid update -c` to create it." @@ -1936,7 +1937,7 @@ msgstr "local_copy_dir deve ser um caminho absoluto!" #: ../fdroidserver/server.py msgid "local_copy_dir must be directory, not a file!" -msgstr "local_copy_dir deve ser directory, não um ficheiro!" +msgstr "local_copy_dir deve ser directory, não um arquivo!" #: ../fdroidserver/index.py #, python-format @@ -2197,7 +2198,7 @@ msgstr "{appid}: extlib {path} desconhecido na compilação '{versionName}'" #: ../fdroidserver/scanner.py #, python-brace-format msgid "{appid}: no builds specified, running on current source state" -msgstr "{appid}: nehnuma compilação especificada, em execução no estado de origem atual" +msgstr "{appid}: nenhuma compilação especificada, em execução no estado de origem atual" #: ../fdroidserver/lint.py #, python-brace-format From 73c95062303404ab769e680c8c68300686d98117 Mon Sep 17 00:00:00 2001 From: Wellington Terumi Uemura Date: Thu, 1 Oct 2020 11:00:44 +0200 Subject: [PATCH 0509/2775] Translated using Weblate: Portuguese (Brazil) (pt_BR) by Wellington Terumi Uemura Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Wellington Terumi Uemura Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translation: F-Droid/F-Droid Server --- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 228b5982..693ab09d 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-05-16 20:31+0000\n" -"Last-Translator: André Marcelo Alvarenga \n" +"PO-Revision-Date: 2020-05-27 06:45+0000\n" +"Last-Translator: Wellington Terumi Uemura \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -384,7 +384,7 @@ msgstr "Limpar todos os containers e então sair" #: ../fdroidserver/update.py msgid "Clean update - don't uses caches, reprocess all APKs" -msgstr "Atualização limpa - não usa cache, reprocessa todos os APKs" +msgstr "Atualização limpa - não utiliza o cache, reprocessa todos os APKs" #: ../fdroidserver/import.py msgid "Comma separated list of categories." @@ -1596,7 +1596,7 @@ msgstr "Arquivo não utilizado em %s" #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" -msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" +msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" #: ../fdroid msgid "Update repo information for new packages" From 2660585695d1deaf3bfba2774d408d0b90520c4d Mon Sep 17 00:00:00 2001 From: Lucas Brizzi Date: Thu, 1 Oct 2020 11:00:45 +0200 Subject: [PATCH 0510/2775] Translated using Weblate: French (fr) by Lucas Brizzi Currently translated at 70.4% (336 of 477 strings) Co-authored-by: Lucas Brizzi Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 6f87e2f4..f826db6d 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -6,13 +6,14 @@ # Jeannette L , 2020. # Nathan , 2020. # Virgile L. , 2020. +# Lucas Brizzi , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-05-13 22:41+0000\n" -"Last-Translator: Virgile L. \n" +"PO-Revision-Date: 2020-06-02 11:58+0000\n" +"Last-Translator: Lucas Brizzi \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1259,7 +1260,7 @@ msgstr "Redimensionner toutes les icônes excédant la taille maximale en pixels #: ../fdroidserver/common.py msgid "Restrict output to warnings and errors" -msgstr "Restreindre les résultats aux avertissements et erreurs" +msgstr "Limiter la sortie aux avertissements et aux erreurs" #: ../fdroid msgid "Rewrite all the metadata files" @@ -1277,11 +1278,11 @@ msgstr "Réécriture de « {appid} »" #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Rewriting '{appid}' to '{path}'" -msgstr "" +msgstr "Réécriture de '{appid}' dans '{path}'" #: ../fdroidserver/checkupdates.py msgid "Run on git repo that has uncommitted changes" -msgstr "" +msgstr "Exécuter sur le dépôt git qui a des modifications non validées" #: ../fdroidserver/lint.py msgid "Run rewritemeta to fix formatting" @@ -1289,7 +1290,7 @@ msgstr "Exécuter rewritemeta pour corriger le formatage" #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" -msgstr "" +msgstr "Exécution de la première passe avec la vérification MD5 désactivée" #: ../fdroidserver/mirror.py #, python-brace-format @@ -1307,7 +1308,7 @@ msgstr "Scanner le code source d'un paquet" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Scanner found {count} problems in {appid}:" -msgstr "" +msgstr "Le scan a détecté {count} problèmes dans {appid} :" #: ../fdroidserver/scanner.py #, python-brace-format From 8b7fa48deefb27b2b19b790b7a94f85e5c94a714 Mon Sep 17 00:00:00 2001 From: Trey Yang Date: Thu, 1 Oct 2020 11:00:45 +0200 Subject: [PATCH 0511/2775] Translated using Weblate: Chinese (Simplified) (zh_Hans) by Trey Yang Currently translated at 31.6% (151 of 477 strings) Co-authored-by: Trey Yang Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hans/ Translation: F-Droid/F-Droid Server --- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 120 +++++++++++---------- 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index 0ad2d463..29ed8924 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -2,26 +2,29 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # ERDwaYbR , 2020. +# Trey Yang , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-18 02:37+0000\n" -"Last-Translator: ERDwaYbR \n" +"PO-Revision-Date: 2020-06-10 10:04+0000\n" +"Last-Translator: Trey Yang \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.0.2-dev\n" +"X-Generator: Weblate 4.1-dev\n" #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +"\n" +"SSH 公钥被用来作为布署密钥:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -29,43 +32,45 @@ msgid "" "\n" "{path} encoded for the DEBUG_KEYSTORE secret variable:" msgstr "" +"\n" +"编给DEBUG_KEYSTORE秘密变量的{path}:" #: ../fdroidserver/lint.py #, python-format msgid "\"%s/\" has no matching metadata file!" -msgstr "" +msgstr "\"%s/\" 没有匹配的元数据文件!" #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" -msgstr "" +msgstr "\"{path}\" 包含过时的 {name} ({version})" #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains recent {name} ({version})" -msgstr "" +msgstr "\"{path}\" 包含近期的 {name} ({version})" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" -msgstr "" +msgstr "\"{path}\"存在,但未安装 s3cmd!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" -msgstr "" +msgstr "\"{path}\" 不是可接受的格式, 需转换成 : {formats}" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format msgid "%(option)s option requires %(number)d argument" msgid_plural "%(option)s option requires %(number)d arguments" -msgstr[0] "" +msgstr[0] "%(option)s 选项需要 %(number)d 个参数" #: ../fdroidserver/mirror.py #, python-format msgid "%(prog)s [options] url" -msgstr "" +msgstr "%(prog)s [选项] url" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -76,7 +81,7 @@ msgstr "%(prog)s: 错误: %(message)s\n" #: ../fdroidserver/scanner.py #, python-format msgid "%d problems found" -msgstr "" +msgstr "发现 %d 个问题" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -92,38 +97,38 @@ msgstr "%r 不是可调用的" #: ../fdroidserver/lint.py #, python-format msgid "%s is not an accepted build field" -msgstr "" +msgstr "%s 不是可接受的构建字段" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format msgid "%s option does not take a value" -msgstr "" +msgstr "%s 选项不采用值" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keypass' not found in config.py!" -msgstr "" +msgstr "config.py中找不到'keypass'!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" -msgstr "" +msgstr "config.py中找不到'keypass'!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystorepass' not found in config.py!" -msgstr "" +msgstr "config.py中找不到'keystorepass'!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'repo_keyalias' not found in config.py!" -msgstr "" +msgstr "config.py中找不到'repo_keyalias'!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "'required' is an invalid argument for positionals" -msgstr "" +msgstr "'required'是无效的位置参数" #: ../fdroidserver/common.py msgid "'sdk_path' not set in 'config.py'!" -msgstr "" +msgstr "未在“ config.py”中设置“ sdk_path”!" #. Translators: "build-tools" is the file name of a package from #. Google, it is part of the Android SDK. So it probably shouldn't be @@ -131,42 +136,42 @@ msgstr "" #: ../fdroidserver/common.py #, python-brace-format msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" -msgstr "" +msgstr "'{aapt}'太旧,fdroid需要build-tools-23.0.0或更高版本!" #: ../fdroidserver/common.py #, python-brace-format msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" -msgstr "" +msgstr "'{aapt}'太旧,fdroid需要build-tools- {version}或更高版本!" #: ../fdroidserver/install.py #, python-brace-format msgid "'{apkfilename}' is already installed on {dev}." -msgstr "" +msgstr "'{apkfilename}'已安装在{dev}上。" #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" -msgstr "" +msgstr "{linedesc}中的'{field}'已过时,请参阅文档以获取当前字段:" #: ../fdroidserver/common.py #, python-brace-format msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" -msgstr "" +msgstr "“ {field}”将随机排列!如果顺序很重要,请使用()或[]括号!" #: ../fdroidserver/common.py #, python-brace-format msgid "'{path}' failed to execute!" -msgstr "" +msgstr "'{path}'执行失败!" #: ../fdroidserver/metadata.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" -msgstr "" +msgstr "'{value}'在{appid}中不是有效的{field}。正则表达式模式:{pattern}" #: ../fdroidserver/checkupdates.py #, python-brace-format msgid "...checkupdate failed for {appid} : {error}" -msgstr "" +msgstr "... {appid}的checkupdate失败:{error}" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -175,39 +180,37 @@ msgstr ".__call__() 未定义" #: ../fdroidserver/metadata.py msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." -msgstr "" +msgstr "不支持.fdroid.txt!转换为.fdroid.yml或.fdroid.json。" #: ../fdroidserver/lint.py msgid "/issues is missing" -msgstr "" +msgstr "/问题丢失" #: ../fdroidserver/mirror.py msgid "A URL is required as an argument!" -msgstr "" +msgstr "需要有URL为参数!" #: ../fdroid -#, fuzzy msgid "Add PGP signatures using GnuPG for packages in repo" -msgstr "添加包 gpg 签名至资源库" +msgstr "添加 gpg 签名至资源库软件包" #: ../fdroid msgid "Add a new application from its source code" msgstr "从源码添加新的应用程序" #: ../fdroidserver/update.py -#, fuzzy msgid "Add a repo signing key to an unsigned repo" -msgstr "在密钥存储中创建资源库签名密钥" +msgstr "给未签署的资源库添加一个资源库签署密匙" #: ../fdroidserver/update.py #, fuzzy msgid "Add skeleton metadata files for APKs that are missing them" -msgstr "创建缺少的主干元数据文件" +msgstr "为缺少它们的 APK 添加骨架元数据文件" #: ../fdroidserver/update.py #, python-brace-format msgid "Adding new repo for only {name}" -msgstr "" +msgstr "仅为 {name} 添加新资源库" #: ../fdroidserver/init.py msgid "Alias of the repo signing key in the keystore" @@ -219,7 +222,7 @@ msgstr "可让运行初始导入时指定不同修订(或 git 分支)" #: ../fdroidserver/mirror.py msgid "Also mirror the full archive section" -msgstr "" +msgstr "同时对存档部分完整镜像" #: ../fdroidserver/lint.py msgid "Also warn about formatting issues, like rewritemeta -l" @@ -228,21 +231,21 @@ msgstr "同时提示格式问题,如 rewritemeta -l" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" -msgstr "" +msgstr "Android SDK‘{path}’未安装‘{dirname}’!" #: ../fdroidserver/common.py msgid "Android SDK not found!" -msgstr "" +msgstr "未找到 Android SDK!" #: ../fdroidserver/common.py #, python-brace-format msgid "Android SDK path '{path}' does not exist!" -msgstr "" +msgstr "Android SDK路径“ {path}”不存在!" #: ../fdroidserver/common.py #, python-brace-format msgid "Android SDK path '{path}' is not a directory!" -msgstr "" +msgstr "Android SDK路径'{path}'不是目录!" #. Translators: "build-tools" is the file name of a package from #. Google, it is part of the Android SDK. So it probably shouldn't be @@ -250,25 +253,25 @@ msgstr "" #: ../fdroidserver/common.py #, python-brace-format msgid "Android build-tools path '{path}' does not exist!" -msgstr "" +msgstr "Android构建工具路径“ {path}”不存在!" #: ../fdroidserver/update.py msgid "AndroidManifest.xml has no date" -msgstr "" +msgstr "AndroidManifest.xml没有日期" #: ../fdroidserver/lint.py #, python-brace-format msgid "App is in '{repo}' but has a link to {url}" -msgstr "" +msgstr "应用程序在\"{repo}\",但有一个链接到{url}" #: ../fdroidserver/lint.py msgid "Appending .git is not necessary" -msgstr "" +msgstr "不需要附加.git" #: ../fdroidserver/update.py #, python-brace-format msgid "Archiving {apkfilename} with invalid signature!" -msgstr "" +msgstr "正使用无效签名归档{apkfilename}!" #: ../fdroidserver/mirror.py msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" @@ -1944,9 +1947,8 @@ msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir必须为绝对路径!" #: ../fdroidserver/server.py -#, fuzzy msgid "local_copy_dir must be directory, not a file!" -msgstr "local_copy_dir为目录,不是档案!" +msgstr "local_copy_dir必须是目录,不能是文件!" #: ../fdroidserver/index.py #, python-format @@ -1971,7 +1973,7 @@ msgstr "" #: /usr/lib/python3.7/optparse.py #, python-format msgid "no such option: %s" -msgstr "" +msgstr "没有此选项:%s" #: ../fdroid #, fuzzy @@ -2027,13 +2029,13 @@ msgstr "命令 -%s 需要参数" #: /usr/lib/python3.7/getopt.py #, python-format msgid "option --%s must not have an argument" -msgstr "" +msgstr "选项 --%s 不能有引数" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py #, python-format msgid "option --%s not a unique prefix" -msgstr "" +msgstr "选项 --%s 不是独特的前缀" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py @@ -2045,7 +2047,7 @@ msgstr "无法识别选项 -%s" #: /usr/lib/python3.7/getopt.py #, python-format msgid "option --%s requires argument" -msgstr "" +msgstr "选项 --%s 需要引数" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2060,7 +2062,7 @@ msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "positional arguments" -msgstr "" +msgstr "位置引数" #: ../fdroidserver/signatures.py #, python-brace-format @@ -2118,13 +2120,13 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "the following arguments are required: %s" -msgstr "" +msgstr "必须有此下引数:%s" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "unexpected option string: %s" -msgstr "" +msgstr "意料之外的选项字符串:%s" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2136,12 +2138,12 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "unrecognized arguments: %s" -msgstr "" +msgstr "未识别的引数:%s" #: ../fdroidserver/common.py #, python-brace-format msgid "unsafe permissions on '{config_file}' (should be 0600)!" -msgstr "" +msgstr "{config_file}有不安全的许可(应该是0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid #: /usr/lib/python3.7/argparse.py @@ -2155,7 +2157,7 @@ msgstr "用法:fdroid [-h|--help|--version] []" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" -msgstr "" +msgstr "正在用Apache libcloud同步{url}" #: ../fdroidserver/publish.py #, python-brace-format From a6ad0c239b20dba855ccdb851d60de6e452ff6e7 Mon Sep 17 00:00:00 2001 From: Jose Date: Thu, 1 Oct 2020 11:00:46 +0200 Subject: [PATCH 0512/2775] Translated using Weblate: French (fr) by Jose Currently translated at 70.6% (337 of 477 strings) Co-authored-by: Jose Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index f826db6d..4db00d4a 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -7,13 +7,14 @@ # Nathan , 2020. # Virgile L. , 2020. # Lucas Brizzi , 2020. +# Jose , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-06-02 11:58+0000\n" -"Last-Translator: Lucas Brizzi \n" +"PO-Revision-Date: 2020-06-13 11:03+0000\n" +"Last-Translator: Jose \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1132,7 +1133,7 @@ msgstr "Chemin vers un dépôt git à utiliser comme journal" #: ../fdroidserver/init.py msgid "Path to the keystore for the repo signing key" -msgstr "" +msgstr "Chemin vers le keystore pour la clé de signature du dépôt" #: ../fdroidserver/dscanner.py msgid "Prepare Drozer to run a scan" From 7ec51a250d887b85577b07384fb688cc9a22da6e Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 1 Oct 2020 11:00:46 +0200 Subject: [PATCH 0513/2775] Translated using Weblate: Chinese (Traditional) (zh_Hant) by Jeff Huang Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Jeff Huang Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hant/ Translation: F-Droid/F-Droid Server --- locale/zh_Hant/LC_MESSAGES/fdroidserver.po | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index 70ea80d0..9c1358ba 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. -# FIRST AUTHOR , YEAR. -# +# Jeff Huang , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2019-01-31 13:32+0000\n" -"Last-Translator: ezjerry liao \n" +"PO-Revision-Date: 2020-06-28 04:34+0000\n" +"Last-Translator: Jeff Huang \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.5-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -150,7 +149,7 @@ msgstr "'{apkfilename}' 已安裝在 {dev} 上。" #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" -msgstr "" +msgstr "在 {linedesc} 中的 '{field}' 已過時,檢視文件以取得目前的欄位:" #: ../fdroidserver/common.py #, python-brace-format From 4ab7087d9175f75491647b303f1725be69afac41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximiliano=20Casta=C3=B1=C3=B3n?= Date: Thu, 1 Oct 2020 11:00:46 +0200 Subject: [PATCH 0514/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Spani?= =?UTF-8?q?sh=20(es)=20by=20Maximiliano=20Casta=C3=B1=C3=B3n=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 66.8% (319 of 477 strings) Co-authored-by: Maximiliano Castañón Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es/ Translation: F-Droid/F-Droid Server --- locale/es/LC_MESSAGES/fdroidserver.po | 41 +++++++++++++-------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index ccbba8e2..91eb47d3 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -1,22 +1,21 @@ # 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 , YEAR. -# +# Maximiliano Castañón , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2019-01-18 07:20+0000\n" -"Last-Translator: Allan Nordhøy \n" +"PO-Revision-Date: 2020-06-28 04:34+0000\n" +"Last-Translator: Maximiliano Castañón \n" "Language-Team: Spanish \n" "Language: es\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 3.4-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -1193,7 +1192,7 @@ msgstr "Publicar el registro de transparencia binario en {url}" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" -msgstr "" +msgstr "Empujando a {url}" #: ../fdroid msgid "Quickly start a new repository" @@ -1211,14 +1210,14 @@ msgstr "" #: ../fdroidserver/common.py #, python-brace-format msgid "Reading minSdkVersion failed: \"{apkfilename}\"" -msgstr "" +msgstr "Falló lectura de minSdkVersion: \"{apkfilename}\"" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/common.py #, python-brace-format msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" -msgstr "" +msgstr "Falló lectura de packageName/versionCode/versionName, APK inválida: '{apkfilename}'" #: ../fdroidserver/update.py #, python-brace-format @@ -1231,7 +1230,7 @@ msgstr "Recalcular agregación de estados - usar cuando se hacen cambios que inv #: ../fdroidserver/common.py msgid "Removing specified files" -msgstr "" +msgstr "Removiendo archivos especificados" #: ../fdroidserver/update.py msgid "Rename APK files that do not match package.name_123.apk" @@ -1269,7 +1268,7 @@ msgstr "Reescribir a un formato específico: " #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Rewriting '{appid}'" -msgstr "" +msgstr "Reescribiendo '{appid}'" #: ../fdroidserver/rewritemeta.py #, python-brace-format @@ -1291,7 +1290,7 @@ msgstr "" #: ../fdroidserver/mirror.py #, python-brace-format msgid "Running wget in {path}" -msgstr "" +msgstr "Ejecutando wget en {path}" #: ../fdroidserver/dscanner.py msgid "Scan only the latest version of each package" @@ -1314,8 +1313,8 @@ msgstr "" #: ../fdroidserver/build.py msgid "Scanner found {} problem" msgid_plural "Scanner found {} problems" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "El escáner encontró {} problema" +msgstr[1] "El escáner encontró {} problemas" #: ../fdroidserver/common.py msgid "Set clock to that time using:" @@ -1332,7 +1331,7 @@ msgstr "" #: ../fdroidserver/build.py msgid "Setting open file limit failed: " -msgstr "" +msgstr "Configuración fallida de límite de apertura de archivo: " #: ../fdroidserver/build.py #, python-brace-format @@ -1341,7 +1340,7 @@ msgstr "" #: ../fdroidserver/build.py msgid "Setup an emulator, install the APK on it and perform a Drozer scan" -msgstr "Establecer un emulador, instalar la APK en él y realizar un escaneo con \"Drozer\"" +msgstr "Establecer un emulador, instalar la APK en el y realizar un escaneo con \"Drozer\"" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Configurar un emulador, instalar la aplicación APK en él y realizar una \"Drozer\" scan" @@ -1376,7 +1375,7 @@ msgstr "" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Skipping {appid}: disabled" -msgstr "" +msgstr "Saltando {appid}: desactivado" #: ../fdroidserver/scanner.py #, python-brace-format @@ -1411,7 +1410,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" -msgstr "" +msgstr "Resúmen '%s' es sólo el nombre de la app" #: ../fdroidserver/lint.py #, python-brace-format @@ -1435,7 +1434,7 @@ msgstr "" #: ../fdroidserver/btlog.py msgid "The base URL for the repo to log (default: https://f-droid.org)" -msgstr "El URL base para el registro del repositorio (default: https://f-droid.org)" +msgstr "El URL base para el registro del repositorio (por defecto: https://f-droid.org)" #: ../fdroidserver/mirror.py msgid "The directory to write the mirror to" @@ -1451,7 +1450,7 @@ msgstr "Los únicos comandos soportados son 'init' y 'update'" #: ../fdroidserver/index.py msgid "The repository's fingerprint does not match." -msgstr "" +msgstr "La huella digital del repositorio no coincide." #: ../fdroidserver/common.py msgid "The repository's index could not be verified." @@ -1469,7 +1468,7 @@ msgstr "" #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" -msgstr "" +msgstr "Este repo ya tiene metadatos locales: %s" #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" @@ -1481,7 +1480,7 @@ msgstr "" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" -msgstr "" +msgstr "Acortadores de URL no deben ser utilizados" #: ../fdroidserver/metadata.py msgid "URL title is just the URL, use brackets: [URL]" From 84559c0572262a6710a0edd08bf5b6eb44e20102 Mon Sep 17 00:00:00 2001 From: WaldiS Date: Thu, 1 Oct 2020 11:00:47 +0200 Subject: [PATCH 0515/2775] Translated using Weblate: Polish (pl) by WaldiS Currently translated at 100.0% (477 of 477 strings) Co-authored-by: WaldiS Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pl/ Translation: F-Droid/F-Droid Server --- locale/pl/LC_MESSAGES/fdroidserver.po | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index a6399a4b..a097c25d 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# +# WaldiS , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2019-01-31 20:25+0000\n" -"Last-Translator: WaldiS \n" +"PO-Revision-Date: 2020-07-02 20:41+0000\n" +"Last-Translator: WaldiS \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 3.5-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -275,7 +274,7 @@ msgstr "Archiwizacja {apkfilename} z nieprawidłowym podpisem!" #: ../fdroidserver/mirror.py msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" -msgstr "Podstawowy adres URL do dublowania, może zawierać klucz podpisywania indeksu za pomocą ciągu zapytania: ?fingerprint=" +msgstr "Bazowy adres URL do serwera lustrzanego, może zawierać klucz do podpisywania indeksu za pomocą łańcucha zapytania: ?fingerprint=" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/lint.py From 1de8cab935c234d178133bd970ac9a8f565c8527 Mon Sep 17 00:00:00 2001 From: taiyuan <1006333969@qq.com> Date: Thu, 1 Oct 2020 11:00:47 +0200 Subject: [PATCH 0516/2775] Translated using Weblate: Chinese (Simplified) (zh_Hans) by taiyuan <1006333969@qq.com> Currently translated at 31.6% (151 of 477 strings) Co-authored-by: taiyuan <1006333969@qq.com> Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hans/ Translation: F-Droid/F-Droid Server --- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index 29ed8924..bc3376eb 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -3,20 +3,21 @@ # This file is distributed under the same license as the PACKAGE package. # ERDwaYbR , 2020. # Trey Yang , 2020. +# taiyuan <1006333969@qq.com>, 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-06-10 10:04+0000\n" -"Last-Translator: Trey Yang \n" +"PO-Revision-Date: 2020-07-04 12:07+0000\n" +"Last-Translator: taiyuan <1006333969@qq.com>\n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.1-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -2029,7 +2030,7 @@ msgstr "命令 -%s 需要参数" #: /usr/lib/python3.7/getopt.py #, python-format msgid "option --%s must not have an argument" -msgstr "选项 --%s 不能有引数" +msgstr "选项 --%s 不能有参数" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py @@ -2047,7 +2048,7 @@ msgstr "无法识别选项 -%s" #: /usr/lib/python3.7/getopt.py #, python-format msgid "option --%s requires argument" -msgstr "选项 --%s 需要引数" +msgstr "选项 --%s 需要参数" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2062,7 +2063,7 @@ msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "positional arguments" -msgstr "位置引数" +msgstr "位置参数" #: ../fdroidserver/signatures.py #, python-brace-format @@ -2120,7 +2121,7 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "the following arguments are required: %s" -msgstr "必须有此下引数:%s" +msgstr "必须有此下参数:%s" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2138,12 +2139,12 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "unrecognized arguments: %s" -msgstr "未识别的引数:%s" +msgstr "未识别的参数:%s" #: ../fdroidserver/common.py #, python-brace-format msgid "unsafe permissions on '{config_file}' (should be 0600)!" -msgstr "{config_file}有不安全的许可(应该是0600)!" +msgstr "{config_file}有不安全的权限(应该是0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid #: /usr/lib/python3.7/argparse.py From cdaf19d4c846fae5b82151b6a179480ea4423a19 Mon Sep 17 00:00:00 2001 From: DGO Date: Thu, 1 Oct 2020 11:00:48 +0200 Subject: [PATCH 0517/2775] Translated using Weblate: French (fr) by DGO Currently translated at 72.1% (344 of 477 strings) Co-authored-by: DGO Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 4db00d4a..93f2cd2a 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -8,20 +8,21 @@ # Virgile L. , 2020. # Lucas Brizzi , 2020. # Jose , 2020. +# DGO , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-06-13 11:03+0000\n" -"Last-Translator: Jose \n" +"PO-Revision-Date: 2020-07-04 12:07+0000\n" +"Last-Translator: DGO \n" "Language-Team: French \n" "Language: fr\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 4.1-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -1196,9 +1197,9 @@ msgid "Pushing binary transparency log to {url}" msgstr "" #: ../fdroidserver/server.py ../fdroidserver/upload.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "Pushing to {url}" -msgstr "" +msgstr "Pousser vers {url}" #: ../fdroid msgid "Quickly start a new repository" @@ -1216,14 +1217,14 @@ msgstr "Lecture de '{config_file}'" #: ../fdroidserver/common.py #, python-brace-format msgid "Reading minSdkVersion failed: \"{apkfilename}\"" -msgstr "" +msgstr "Lecture de minSdkVersion échouée: \"{apkfilename}\"" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/common.py #, python-brace-format msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" -msgstr "" +msgstr "Lecture de packageName/versionCode/versionName échouée, APK invalide: '{apkfilename}'" #: ../fdroidserver/update.py #, python-brace-format @@ -1236,7 +1237,7 @@ msgstr "" #: ../fdroidserver/common.py msgid "Removing specified files" -msgstr "" +msgstr "Suppression des fichiers spécifiés" #: ../fdroidserver/update.py msgid "Rename APK files that do not match package.name_123.apk" @@ -1253,7 +1254,7 @@ msgstr "" #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" -msgstr "" +msgstr "Re-signature de {apkfilename} avec le debug.keystore fournit" #: ../fdroidserver/update.py msgid "Resize all the icons exceeding the max pixel size and exit" @@ -1314,7 +1315,7 @@ msgstr "Le scan a détecté {count} problèmes dans {appid} :" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Scanner found {count} problems in {appid}:{versionCode}:" -msgstr "" +msgstr "Le scanner a trouvé {count} problèmes dans {appid}:{versionCode}:" #: ../fdroidserver/build.py msgid "Scanner found {} problem" @@ -1329,7 +1330,7 @@ msgstr "Réglez l'horloge à cette heure à l'aide de :" #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" -msgstr "" +msgstr "Définition de la limite de fichiers ouverts à {integer}" #: ../fdroid msgid "Set up an app build for a nightly build repo" From bd7d29cea131b98806fd8914696c2cd3c5b547ec Mon Sep 17 00:00:00 2001 From: Yannick A Date: Thu, 1 Oct 2020 11:00:48 +0200 Subject: [PATCH 0518/2775] Translated using Weblate: French (fr) by Yannick A. Currently translated at 72.3% (345 of 477 strings) Translated using Weblate: French (fr) by Yannick A. Currently translated at 72.1% (344 of 477 strings) Co-authored-by: Yannick A Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 93f2cd2a..e6b86ac4 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -9,13 +9,14 @@ # Lucas Brizzi , 2020. # Jose , 2020. # DGO , 2020. +# Yannick A. , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-07-04 12:07+0000\n" -"Last-Translator: DGO \n" +"PO-Revision-Date: 2020-07-07 02:50+0000\n" +"Last-Translator: Yannick A. \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1145,7 +1146,7 @@ msgstr "Préparer Drozer pour lancer un scanne" #: ../fdroidserver/nightly.py msgid "Print the secret variable to the terminal for easy copy/paste" -msgstr "" +msgstr "Afficher la variable secrète dans le terminal pour un copier/coller facilité" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1244,12 +1245,13 @@ msgid "Rename APK files that do not match package.name_123.apk" msgstr "Renomme les fichiers APK dont le nom ne ressemble pas à nom.paquet_123.apk" #: ../fdroidserver/update.py +#, fuzzy msgid "Report on build data status" -msgstr "" +msgstr "Rapport sur l'état des données de construction" #: ../fdroidserver/build.py msgid "Reset and create a brand new build server, even if the existing one appears to be ok." -msgstr "" +msgstr "Réinitialiser et créer un tout nouveau serveur de construction, même si le serveur existant semble correct." #: ../fdroidserver/nightly.py #, python-brace-format @@ -1346,8 +1348,9 @@ msgid "Setting {0} sec timeout for this build" msgstr "" #: ../fdroidserver/build.py +#, fuzzy msgid "Setup an emulator, install the APK on it and perform a Drozer scan" -msgstr "" +msgstr "Installez un émulateur, installez l'APK dessus et effectuez un scan Drozer" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" From 05477dcb3c2830690d614d087c28e4be0b6e4650 Mon Sep 17 00:00:00 2001 From: gardenapple Date: Thu, 1 Oct 2020 11:00:48 +0200 Subject: [PATCH 0519/2775] Translated using Weblate: Russian (ru) by gardenapple Currently translated at 100.0% (477 of 477 strings) Co-authored-by: gardenapple Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 4a795b7f..71a8dc60 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -4,20 +4,21 @@ # Mingun , 2020. # anonymous , 2020. # Andrey , 2020. +# gardenapple , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-08 02:31+0000\n" -"Last-Translator: Golubev Alexander \n" +"PO-Revision-Date: 2020-07-08 21:41+0000\n" +"Last-Translator: gardenapple \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.0-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -66,9 +67,9 @@ msgstr "формат пути \"{path}\" не принимается, преоб #, python-format msgid "%(option)s option requires %(number)d argument" msgid_plural "%(option)s option requires %(number)d arguments" -msgstr[0] "Параметру %(option)s нужен аргумент %(number)d" -msgstr[1] "Параметру %(option)s нужно несколько аргументов %(number)d" -msgstr[2] "Параметру %(option)s нужны аргументы %(number)d" +msgstr[0] "Параметр %(option)s требует %(number)d аргумент" +msgstr[1] "Параметр %(option)s требует %(number)d аргумента" +msgstr[2] "Параметр %(option)s требует %(number)d аргументов" #: ../fdroidserver/mirror.py #, python-format @@ -216,7 +217,7 @@ msgstr "Добавление нового репозитория только д #: ../fdroidserver/init.py msgid "Alias of the repo signing key in the keystore" -msgstr "Алиас для ключа для подписи репозитория в хранилище ключей" +msgstr "Алиас для ключа для подписи репозитория в хранилище ключей" #: ../fdroidserver/import.py msgid "Allows a different revision (or git branch) to be specified for the initial import" @@ -304,7 +305,7 @@ msgstr "Билд подготовлен командой `fdroid import`, пер #: ../fdroidserver/checkupdates.py msgid "Build metadata git repo has uncommited changes!" -msgstr "В репозитории с метаданными билда есть несохраненные изменения!" +msgstr "В репозитории с метаданными билдов есть незакоммиченные изменения!" #: ../fdroidserver/build.py msgid "Build only the latest version of each package" @@ -603,7 +604,9 @@ msgstr "У флага сборки в {linedesc} нет значения" msgid "" "Enter the path to the Android SDK (%s) here:\n" "> " -msgstr "Укажите путь к Android SDK (%s): " +msgstr "" +"Укажите путь к Android SDK (%s): \n" +"> " #: ../fdroidserver/server.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py @@ -1261,7 +1264,7 @@ msgstr "Показывать в выводе только предупрежде #: ../fdroid msgid "Rewrite all the metadata files" -msgstr "Перезаписать все метаданные" +msgstr "Перезаписать все метаданные" #: ../fdroidserver/rewritemeta.py msgid "Rewrite to a specific format: " @@ -1275,7 +1278,7 @@ msgstr "Перезапись '{appid}'" #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Rewriting '{appid}' to '{path}'" -msgstr "Перезапись '{appid}' в '{path}'" +msgstr "Перезапись '{appid}' в '{path}'" #: ../fdroidserver/checkupdates.py msgid "Run on git repo that has uncommitted changes" From 2907eb2cdf33f9d2e3ba62129bc83d4c91da69df Mon Sep 17 00:00:00 2001 From: DGO Date: Thu, 1 Oct 2020 11:00:49 +0200 Subject: [PATCH 0520/2775] Translated using Weblate: French (fr) by DGO Currently translated at 73.5% (351 of 477 strings) Co-authored-by: DGO Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index e6b86ac4..7187f8e6 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -15,8 +15,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-07-07 02:50+0000\n" -"Last-Translator: Yannick A. \n" +"PO-Revision-Date: 2020-07-14 08:11+0000\n" +"Last-Translator: DGO \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1340,7 +1340,7 @@ msgstr "" #: ../fdroidserver/build.py msgid "Setting open file limit failed: " -msgstr "" +msgstr "Définition de la limite du nombre de fichiers ouverts en échec:" #: ../fdroidserver/build.py #, python-brace-format From 9409cee0ee6f207ecc5ecf2a02e0058af65ee825 Mon Sep 17 00:00:00 2001 From: Renaud Perrai Date: Thu, 1 Oct 2020 11:00:49 +0200 Subject: [PATCH 0521/2775] Translated using Weblate: French (fr) by Renaud Perrai Currently translated at 74.4% (355 of 477 strings) Translated using Weblate: French (fr) by Renaud Perrai Currently translated at 73.5% (351 of 477 strings) Co-authored-by: Renaud Perrai Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 7187f8e6..aeee05a6 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -10,13 +10,14 @@ # Jose , 2020. # DGO , 2020. # Yannick A. , 2020. +# Renaud Perrai , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-07-14 08:11+0000\n" -"Last-Translator: DGO \n" +"PO-Revision-Date: 2020-07-14 13:03+0000\n" +"Last-Translator: Renaud Perrai \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1195,12 +1196,12 @@ msgstr "Envoyer les logs dans ce dépôt git distant" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" -msgstr "" +msgstr "Envoyer les logs de transparence de la compilation vers {url}" #: ../fdroidserver/server.py ../fdroidserver/upload.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Pushing to {url}" -msgstr "Pousser vers {url}" +msgstr "Envoyer vers {url}" #: ../fdroid msgid "Quickly start a new repository" @@ -1218,14 +1219,14 @@ msgstr "Lecture de '{config_file}'" #: ../fdroidserver/common.py #, python-brace-format msgid "Reading minSdkVersion failed: \"{apkfilename}\"" -msgstr "Lecture de minSdkVersion échouée: \"{apkfilename}\"" +msgstr "La lecture de minSdkVersion a échoué : \"{apkfilename}\"" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/common.py #, python-brace-format msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" -msgstr "Lecture de packageName/versionCode/versionName échouée, APK invalide: '{apkfilename}'" +msgstr "La lecture de packageName/versionCode/versionName a échoué, APK invalide : '{apkfilename}'" #: ../fdroidserver/update.py #, python-brace-format @@ -1234,7 +1235,7 @@ msgstr "Lecture de {apkfilename} à partir du cache" #: ../fdroidserver/stats.py msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." -msgstr "" +msgstr "Recalculer les statistiques agrégées - à utiliser quand les modifications faites peuvent invalider les anciennes données en cache." #: ../fdroidserver/common.py msgid "Removing specified files" @@ -1245,7 +1246,6 @@ msgid "Rename APK files that do not match package.name_123.apk" msgstr "Renomme les fichiers APK dont le nom ne ressemble pas à nom.paquet_123.apk" #: ../fdroidserver/update.py -#, fuzzy msgid "Report on build data status" msgstr "Rapport sur l'état des données de construction" @@ -1317,7 +1317,7 @@ msgstr "Le scan a détecté {count} problèmes dans {appid} :" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Scanner found {count} problems in {appid}:{versionCode}:" -msgstr "Le scanner a trouvé {count} problèmes dans {appid}:{versionCode}:" +msgstr "Le scanner a trouvé {count} problèmes dans {appid} :{versionCode} :" #: ../fdroidserver/build.py msgid "Scanner found {} problem" @@ -1336,11 +1336,11 @@ msgstr "Définition de la limite de fichiers ouverts à {integer}" #: ../fdroid msgid "Set up an app build for a nightly build repo" -msgstr "" +msgstr "Programmer une compilation de l'application pour le dépôt des versions de test" #: ../fdroidserver/build.py msgid "Setting open file limit failed: " -msgstr "Définition de la limite du nombre de fichiers ouverts en échec:" +msgstr "Définir la limite d'échec du nombre de fichiers ouvert : " #: ../fdroidserver/build.py #, python-brace-format @@ -1370,22 +1370,22 @@ msgstr "" #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping '{apkfilename}' with invalid signature!" -msgstr "" +msgstr "Sauter '{apkfilename}' avec une signature non valide !" #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping index generation for {appid}" -msgstr "" +msgstr "Sauter la génération de l'index pour {appid}" #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping {apkfilename} with invalid signature!" -msgstr "" +msgstr "Sauter {apkfilename} avec une signature non valide !" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Skipping {appid}: disabled" -msgstr "" +msgstr "Sauter {appid} : désactivé" #: ../fdroidserver/scanner.py #, python-brace-format @@ -1444,7 +1444,7 @@ msgstr "" #: ../fdroidserver/btlog.py msgid "The base URL for the repo to log (default: https://f-droid.org)" -msgstr "URL de base du dépôt à journaliser (par défaut: https://f-droid.org)" +msgstr "URL de base du dépôt à journaliser (par défaut : https://f-droid.org)" #: ../fdroidserver/mirror.py msgid "The directory to write the mirror to" From 6652692298a3de9eda8270cede0736f0979ea439 Mon Sep 17 00:00:00 2001 From: rational Date: Thu, 1 Oct 2020 11:00:49 +0200 Subject: [PATCH 0522/2775] Translated using Weblate: French (fr) by rational Currently translated at 74.4% (355 of 477 strings) Co-authored-by: rational Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index aeee05a6..b33fa1d1 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -11,13 +11,14 @@ # DGO , 2020. # Yannick A. , 2020. # Renaud Perrai , 2020. +# rational , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-07-14 13:03+0000\n" -"Last-Translator: Renaud Perrai \n" +"PO-Revision-Date: 2020-07-14 17:29+0000\n" +"Last-Translator: rational \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1370,22 +1371,22 @@ msgstr "" #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping '{apkfilename}' with invalid signature!" -msgstr "Sauter '{apkfilename}' avec une signature non valide !" +msgstr "Omission de '{apkfilename}' qui a une signature non valide !" #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping index generation for {appid}" -msgstr "Sauter la génération de l'index pour {appid}" +msgstr "Omission de la génération de l'index pour {appid}" #: ../fdroidserver/update.py #, python-brace-format msgid "Skipping {apkfilename} with invalid signature!" -msgstr "Sauter {apkfilename} avec une signature non valide !" +msgstr "Omission de {apkfilename} qui a une signature non valide !" #: ../fdroidserver/scanner.py #, python-brace-format msgid "Skipping {appid}: disabled" -msgstr "Sauter {appid} : désactivé" +msgstr "Omission de {appid} : désactivé" #: ../fdroidserver/scanner.py #, python-brace-format From 82c69afce3257aee9990e1a1e10a1ceaf8c3897f Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 1 Oct 2020 11:00:50 +0200 Subject: [PATCH 0523/2775] Translated using Weblate: Chinese (Simplified) (zh_Hans) by Eric Currently translated at 37.1% (177 of 477 strings) Co-authored-by: Eric Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hans/ Translation: F-Droid/F-Droid Server --- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 83 +++++++++------------- 1 file changed, 32 insertions(+), 51 deletions(-) diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index bc3376eb..171a7eee 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -4,13 +4,14 @@ # ERDwaYbR , 2020. # Trey Yang , 2020. # taiyuan <1006333969@qq.com>, 2020. +# Eric , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-07-04 12:07+0000\n" -"Last-Translator: taiyuan <1006333969@qq.com>\n" +"PO-Revision-Date: 2020-07-16 09:41+0000\n" +"Last-Translator: Eric \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" @@ -165,9 +166,9 @@ msgid "'{path}' failed to execute!" msgstr "'{path}'执行失败!" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" -msgstr "'{value}'在{appid}中不是有效的{field}。正则表达式模式:{pattern}" +msgstr "'{value}'不是{appid}的一个有效{field}。正则表达式模式:{pattern}" #: ../fdroidserver/checkupdates.py #, python-brace-format @@ -204,9 +205,8 @@ msgid "Add a repo signing key to an unsigned repo" msgstr "给未签署的资源库添加一个资源库签署密匙" #: ../fdroidserver/update.py -#, fuzzy msgid "Add skeleton metadata files for APKs that are missing them" -msgstr "为缺少它们的 APK 添加骨架元数据文件" +msgstr "为缺少骨架元数据文件的 APK 添加这些文件" #: ../fdroidserver/update.py #, python-brace-format @@ -384,9 +384,8 @@ msgid "Clean up all containers and then exit" msgstr "清除所有容器,然后退出" #: ../fdroidserver/update.py -#, fuzzy msgid "Clean update - don't uses caches, reprocess all APKs" -msgstr "清除更新:不用缓存,重新处理全部 apk" +msgstr "干净更新- 不用缓存,重新处理全部 APK文件" #: ../fdroidserver/import.py msgid "Comma separated list of categories." @@ -631,9 +630,8 @@ msgid "Failed resizing {path}: {error}" msgstr "" #: ../fdroidserver/publish.py -#, fuzzy msgid "Failed to align application" -msgstr "编译全部可用应用程序" +msgstr "未能匹配应用程序" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -664,9 +662,8 @@ msgid "Failed to sign application" msgstr "" #: ../fdroidserver/common.py -#, fuzzy msgid "Failed to zipalign application" -msgstr "编译全部可用应用程序" +msgstr "未能归档对齐(zipalign)应用程序" #: ../fdroidserver/build.py #, python-brace-format @@ -717,9 +714,9 @@ msgid "Found invalid versionCodes for some apps" msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found multiple metadata files for {appid}" -msgstr "创建缺少的主干元数据文件" +msgstr "找到多个{appid}的元数据文件" #: ../fdroidserver/index.py msgid "Found multiple signing certificates for repository." @@ -740,9 +737,9 @@ msgid "Found non-file at %s" msgstr "" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Generated skeleton metadata for {appid}" -msgstr "创建缺少的主干元数据文件" +msgstr "生成了{appid}的骨架元数据" #: ../fdroidserver/common.py #, python-format @@ -911,9 +908,8 @@ msgid "Javascript in HTML src attributes" msgstr "" #: ../fdroidserver/init.py -#, fuzzy msgid "Keystore for signing key:\t" -msgstr "资源库签名密钥的密钥存储(keystore)路径" +msgstr "签名密钥的密钥库:\t" #: ../fdroidserver/lint.py #, python-brace-format @@ -1112,9 +1108,8 @@ msgid "Password required with username" msgstr "" #: ../fdroidserver/import.py -#, fuzzy msgid "Path to main Android project subdirectory, if not in root." -msgstr "如果不是位于根目录,路径为 android 主项目的子目录。" +msgstr "主Android项目子目录的路径(如果不是根目录)." msgid "Path to main android project subdirectory, if not in root." msgstr "如果不是位于根目录,路径为 android 主项目的子目录。" @@ -1132,9 +1127,8 @@ msgid "Path to the keystore for the repo signing key" msgstr "资源库签名密钥的密钥存储(keystore)路径" #: ../fdroidserver/dscanner.py -#, fuzzy msgid "Prepare Drozer to run a scan" -msgstr "准备运行 drozer 扫描" +msgstr "准备Drozer进行扫描" msgid "Prepare drozer to run a scan" msgstr "准备运行 drozer 扫描" @@ -1168,9 +1162,8 @@ msgid "Processing {appid}" msgstr "" #: ../fdroidserver/update.py -#, fuzzy msgid "Produce human-readable XML/JSON for index files" -msgstr "生成用户可读的 index.xml" +msgstr "为索引文件生成人类可读的XML/JSON" #: ../fdroidserver/update.py msgid "Produce human-readable index.xml" @@ -1189,9 +1182,9 @@ msgid "Push the log to this git remote repository" msgstr "拖送日志至 git 远程资源库" #: ../fdroidserver/server.py ../fdroidserver/upload.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Pushing binary transparency log to {url}" -msgstr "更新 URL 的二进制透明度日志" +msgstr "正推送二进制文件透明日志到{url}" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -1229,9 +1222,8 @@ msgid "Reading {apkfilename} from cache" msgstr "" #: ../fdroidserver/stats.py -#, fuzzy msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." -msgstr "重新计算聚合统计信息(发生更改时使用) " +msgstr "重新计算聚合统计数据-当已经做出更改而导致旧的缓存数据无效时使用。" #: ../fdroidserver/common.py msgid "Removing specified files" @@ -1285,9 +1277,8 @@ msgid "Run on git repo that has uncommitted changes" msgstr "" #: ../fdroidserver/lint.py -#, fuzzy msgid "Run rewritemeta to fix formatting" -msgstr "重写为特定格式: " +msgstr "运行“重写元数据”(rewritemeta)修复格式" #: ../fdroidserver/server.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" @@ -1344,9 +1335,8 @@ msgid "Setting {0} sec timeout for this build" msgstr "" #: ../fdroidserver/build.py -#, fuzzy msgid "Setup an emulator, install the APK on it and perform a Drozer scan" -msgstr "设置一个模拟器,然后在其中安装 apk 并执行 drozer 扫描" +msgstr "设置一个模拟器,在其中安装APK并执行Drozer扫描" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "设置一个模拟器,然后在其中安装 apk 并执行 drozer 扫描" @@ -1451,9 +1441,8 @@ msgid "The file to be included in the repo (path or glob)" msgstr "" #: ../fdroidserver/server.py -#, fuzzy msgid "The only commands currently supported are 'init' and 'update'" -msgstr "执行命令:init 或 update" +msgstr "当前支持的命令只有'init'和'update'" #: ../fdroidserver/index.py msgid "The repository's fingerprint does not match." @@ -1519,9 +1508,9 @@ msgid "Unknown metadata format: %s" msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path}" -msgstr "创建缺少的主干元数据文件" +msgstr "未知元数据格式:{path}" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1627,9 +1616,9 @@ msgid "UpdateCheckData has invalid URL: {url}" msgstr "" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "UpdateCheckData must use HTTPS URL: {url}" -msgstr "UpdateCheckData must use HTTPS URL: {url}" +msgstr "UpdateCheckData必须使用HTTPS URL:{url}" #: ../fdroidserver/lint.py #, python-brace-format @@ -1718,9 +1707,8 @@ msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 生成密钥时所用的“可分辨名称”" #: ../fdroidserver/init.py -#, fuzzy msgid "X.509 'Distinguished Name' used when generating keys" -msgstr "X.509 生成密钥时所用的“可分辨名称”" +msgstr "生成密钥时使用了X.509 ‘可识别名’" #: ../fdroidserver/common.py msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" @@ -1749,22 +1737,19 @@ msgid "ambiguous option: %s (%s?)" msgstr "不明确的选项:%s(%s?)" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py -#, fuzzy msgid "applicationId in the form APPID" msgstr "app-id,格式:APPID" #: ../fdroidserver/checkupdates.py -#, fuzzy msgid "applicationId to check for updates" -msgstr "app-id,用于检查更新" +msgstr "检查更新的applicationId" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/dscanner.py ../fdroidserver/build.py #: ../fdroidserver/scanner.py ../fdroidserver/install.py -#, fuzzy msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" -msgstr "带有可选项 versionCode 的 app-id,格式:APPID[:VERCODE]" +msgstr "带有可选 versionCode 的 app-id,格式:APPID[:VERCODE]" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -1872,12 +1857,10 @@ msgid "failed deploying build logs to '{path}'" msgstr "" #: ../fdroid -#, fuzzy msgid "fdroid [-h|--help|--version] []" msgstr "用法:fdroid [-h|--help|--version] []" #: ../fdroid -#, fuzzy msgid "fdroid [] [-h|--help|--version|]" msgstr "用法:fdroid [-h|--help|--version] []" @@ -1891,9 +1874,8 @@ msgid "force errors to be warnings, or ignore" msgstr "强制错误提示警告或忽略" #: ../fdroidserver/metadata.py -#, fuzzy msgid "force metadata errors (default) to be warnings, or to be ignored." -msgstr "强制错误提示警告或忽略" +msgstr "强制元数据错误(默认)为警告,或忽略。" #: ../fdroidserver/common.py msgid "git svn clone failed" @@ -1977,9 +1959,8 @@ msgid "no such option: %s" msgstr "没有此选项:%s" #: ../fdroid -#, fuzzy msgid "no version info found!" -msgstr "发生未知异常!" +msgstr "没有找到版本信息!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py From befece948e29cd6a59f6e70f8b24dba755ecd1c2 Mon Sep 17 00:00:00 2001 From: Luca Zambarda Date: Thu, 1 Oct 2020 11:00:50 +0200 Subject: [PATCH 0524/2775] Translated using Weblate: Italian (it) by Luca Zambarda Currently translated at 36.8% (176 of 477 strings) Co-authored-by: Luca Zambarda Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/it/ Translation: F-Droid/F-Droid Server --- locale/it/LC_MESSAGES/fdroidserver.po | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index b862ad56..c7e7e882 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -2,20 +2,21 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # random r , 2020. +# Luca Zambarda , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-04-11 13:36+0000\n" -"Last-Translator: random r \n" +"PO-Revision-Date: 2020-07-18 09:41+0000\n" +"Last-Translator: Luca Zambarda \n" "Language-Team: Italian \n" "Language: it\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 4.0-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -221,7 +222,7 @@ msgstr "Permetti di specificare una revisione (o branch git) diversa per l'impor #: ../fdroidserver/mirror.py msgid "Also mirror the full archive section" -msgstr "" +msgstr "Esegui il mirroring anche per l'intera sezione archivi" #: ../fdroidserver/lint.py msgid "Also warn about formatting issues, like rewritemeta -l" @@ -274,7 +275,7 @@ msgstr "Archiviando {apkfilename} con una firma invalida!" #: ../fdroidserver/mirror.py msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" -msgstr "" +msgstr "Indirizzo URL base per il mirror, può includere la chiave di firma dell'indice utilizzando la query string: ?fingerprint=" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/lint.py @@ -1132,7 +1133,7 @@ msgid "Prepare Drozer to run a scan" msgstr "" msgid "Prepare drozer to run a scan" -msgstr "" +msgstr "Preparare drozer per eseguire una scansione" #: ../fdroidserver/nightly.py msgid "Print the secret variable to the terminal for easy copy/paste" @@ -1679,7 +1680,7 @@ msgstr "" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" -msgstr "" +msgstr "Utilizzando s3cmd per sincronizzare con: {url}" #: ../fdroid msgid "Valid commands are:" @@ -1927,11 +1928,11 @@ msgstr "" #: ../fdroidserver/server.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" -msgstr "" +msgstr "local_copy_dir not finisce con \"fdroid\", forse intendevi: \"{path}\"" #: ../fdroidserver/server.py msgid "local_copy_dir must be an absolute path!" -msgstr "" +msgstr "local_copy_dir deve essere un percorso assoluto!" #: ../fdroidserver/server.py msgid "local_copy_dir must be directory, not a file!" @@ -2143,7 +2144,7 @@ msgstr "utilizzo: fdroid [-h|--help|--version] []" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" -msgstr "" +msgstr "utilizzando Apache libcloud per sincronizzare con {url}" #: ../fdroidserver/publish.py #, python-brace-format From 18c19d578d7d45a329f8a01a864ae3e10f4b4f65 Mon Sep 17 00:00:00 2001 From: ssantos Date: Thu, 1 Oct 2020 11:00:50 +0200 Subject: [PATCH 0525/2775] Translated using Weblate: Portuguese (Portugal) (pt_PT) by ssantos Currently translated at 100.0% (477 of 477 strings) Translated using Weblate: Portuguese (Portugal) (pt_PT) by ssantos Currently translated at 100.0% (477 of 477 strings) Translated using Weblate: Portuguese (Portugal) (pt_PT) by ssantos Currently translated at 100.0% (477 of 477 strings) Co-authored-by: ssantos Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_PT/ Translation: F-Droid/F-Droid Server --- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 77 ++++++++++++------------ 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index ffdcd72a..4392963c 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -2,20 +2,21 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Manuela Silva , 2020. +# ssantos , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-05-13 22:41+0000\n" -"Last-Translator: Manuela Silva \n" +"PO-Revision-Date: 2020-08-15 21:32+0000\n" +"Last-Translator: ssantos \n" "Language-Team: Portuguese (Portugal) \n" "Language: pt_PT\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 4.1-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -166,7 +167,7 @@ msgstr "'{path}' falhou ao executar!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" -msgstr "'{value}' não é um {field} válido em {appid}. Padrão Regex: {pattern}" +msgstr "'{value}' não é um {field} válido em {appid}. Modelo regex: {pattern}" #: ../fdroidserver/checkupdates.py #, python-brace-format @@ -221,7 +222,7 @@ msgstr "Permite que uma revisão diferente (ou árvore do git) seja especificada #: ../fdroidserver/mirror.py msgid "Also mirror the full archive section" -msgstr "Também espelhar o arquivo completo da seção" +msgstr "Também espelhar o ficheiro completo da secção" #: ../fdroidserver/lint.py msgid "Also warn about formatting issues, like rewritemeta -l" @@ -261,7 +262,7 @@ msgstr "AndroidManifest.xml não tem data" #: ../fdroidserver/lint.py #, python-brace-format msgid "App is in '{repo}' but has a link to {url}" -msgstr "O App está em '{repo}' mas tem um link para {url}" +msgstr "A App está em '{repo}' mas tem uma hiperligação para {url}" #: ../fdroidserver/lint.py msgid "Appending .git is not necessary" @@ -293,7 +294,7 @@ msgstr "Construir pacote através da fonte" #: ../fdroidserver/build.py msgid "Build all applications available" -msgstr "Compilar todos aplicativos disponíveis" +msgstr "Compilar todos as aplicações disponíveis" #: ../fdroidserver/lint.py msgid "Build generated by `fdroid import` - remove disable line once ready" @@ -341,7 +342,7 @@ msgstr "Não é possível ler \"{path}\"!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Cannot resolve app id {appid}" -msgstr "Não é possível resolver o ID do aplicativo {appid}" +msgstr "Não é possível resolver o ID da app {appid}" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -433,7 +434,7 @@ msgstr "Cobardemente recusando substituir a configuração da chave de assinatur #: ../fdroidserver/update.py msgid "Create a repo signing key in a keystore" -msgstr "Criar uma chave de assinatura do repositório em uma keystore" +msgstr "Criar uma chave de assinatura do repositório numa keystore" #: ../fdroidserver/update.py msgid "Create skeleton metadata files that are missing" @@ -496,7 +497,7 @@ msgstr "Apagando o ficheiro desconhecido: {path}" #: ../fdroidserver/lint.py #, python-format msgid "Description '%s' is just the app's summary" -msgstr "Descrição '%s' é apenas o resumo do aplicativo" +msgstr "Descrição '%s' é apenas o resumo da app" #: ../fdroidserver/lint.py msgid "Description has a duplicate line" @@ -552,7 +553,7 @@ msgstr "Descarregar espelhos completos de repos pequenos" #: ../fdroidserver/stats.py msgid "Download logs we don't have" -msgstr "Baixar os registros de alterações que nós não temos" +msgstr "Descarregar os registos que nós não temos" #: ../fdroidserver/common.py msgid "Downloading the repository already failed once, not trying again." @@ -571,7 +572,7 @@ msgstr "Receita de compilação duplicada encontrada para versionCode {versionCo #: ../fdroidserver/lint.py #, python-brace-format msgid "Duplicate link in '{field}': {url}" -msgstr "Link duplicado em '{field}': {url}" +msgstr "Ligação duplicada em '{field}': {url}" #: ../fdroid msgid "Dynamically scan APKs post build" @@ -662,11 +663,11 @@ msgstr "Falha ao instalar '{apkfilename}' em {dev}: {error}" #: ../fdroidserver/publish.py ../fdroidserver/common.py msgid "Failed to sign application" -msgstr "Falha ao assinar o aplicativo" +msgstr "Falha ao assinar a app" #: ../fdroidserver/common.py msgid "Failed to zipalign application" -msgstr "Falha no zipaligning do aplicativo" +msgstr "Falha no zipaligning a app" #: ../fdroidserver/build.py #, python-brace-format @@ -695,7 +696,7 @@ msgstr "Tags HTML proibidos" #: ../fdroidserver/build.py msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." -msgstr "Forçar a compilação de aplicativos desativados e continuar independentemente de problemas de escaneamento. Apenas permitido no modo de teste." +msgstr "Forçar a compilação de apps desativados e continuar independentemente de problemas de escaneamento. Apenas permitido no modo de teste." #: ../fdroidserver/build.py #, python-brace-format @@ -714,7 +715,7 @@ msgstr "appids inválidos encontrados em argumentos" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Found invalid versionCodes for some apps" -msgstr "versionCodes inválidos encontrados para alguns aplicativos" +msgstr "versionCodes inválidos encontrados para algumas apps" #: ../fdroidserver/metadata.py #, python-brace-format @@ -801,11 +802,11 @@ msgstr "Inicializando submódulos" #: ../fdroidserver/install.py msgid "Install all signed applications available" -msgstr "Instalar todos os aplicativos assinados disponíveis" +msgstr "Instalar todas as aplicações assinadas disponíveis" #: ../fdroid msgid "Install built packages on devices" -msgstr "Instalação dos pacotes compilados no dispositivo" +msgstr "Instalação dos pacotes compilados no aparelho" #: ../fdroidserver/install.py #, python-format @@ -856,7 +857,7 @@ msgstr "Etiqueta de licença \"%s\" inválida! Use apenas etiquetas de https://s #: ../fdroidserver/lint.py msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" -msgstr "Link inválido - use [http://foo.bar Título do link] ou [http://foo.bar]" +msgstr "Hiperligação inválida - use [http://foo.bar Título do link] ou [http://foo.bar]" #: ../fdroidserver/metadata.py #, python-format @@ -900,11 +901,11 @@ msgstr "Assinatura JAR verificada: {path}" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" -msgstr "Java JDK não encontrado! Instalar no local padrão ou definir java_paths!" +msgstr "O Java JDK não foi encontrado! Instalar no local predefinido ou definir java_paths!" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" -msgstr "Java jarsigner não encontrado! Instalar no local padrão ou definir java_paths!" +msgstr "Java jarsigner não encontrado! Instale no local predefinido ou define java_paths!" #: ../fdroidserver/lint.py msgid "Javascript in HTML src attributes" @@ -966,7 +967,7 @@ msgstr "Nenhum projeto Android ou Kivy poderia ser encontrado. Especificar --sub #: ../fdroidserver/install.py msgid "No attached devices found" -msgstr "Nenhum dispositivo anexado encontrado" +msgstr "Nenhum aparelho anexado encontrado" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1077,7 +1078,7 @@ msgstr "Apenas mostrar diferenças com a Play Store" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" -msgstr "Processar apenas aplicativos com atualizações automáticas" +msgstr "Processar apenas apps com atualizações automáticas" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1094,7 +1095,7 @@ msgstr "Licença geral do projeto." #: ../fdroidserver/dscanner.py msgid "Override path for repo APKs (default: ./repo)" -msgstr "Substituir o caminho para os APKs do repositório (padrão: ./repo)" +msgstr "Substituir o caminho para os APKs do repositório (predefinição: ./repo)" #: ../fdroidserver/index.py #, python-brace-format @@ -1108,7 +1109,7 @@ msgstr "Analisando o manifesto em '{path}'" #: ../fdroidserver/common.py msgid "Password required with username" -msgstr "Palavra-passe necessária com o nome de usuário" +msgstr "Palavra-passe necessária com o nome de utilizador" #: ../fdroidserver/import.py msgid "Path to main Android project subdirectory, if not in root." @@ -1347,7 +1348,7 @@ msgstr "Configure um emulador, instale o apk nele e execute um scan do drozer" #: ../fdroid msgid "Sign and place packages in the repo" -msgstr "Assinar e colocar os pacotes no repositório" +msgstr "Assinar e pôr os pacotes no repositório" #: ../fdroid msgid "Sign indexes created using update --nosign" @@ -1355,7 +1356,7 @@ msgstr "Assinar os índices criados com o uso de update --nosign" #: ../fdroidserver/build.py msgid "Skip scanning the source code for binaries and other problems" -msgstr "Pular o escaneamento do código fonte atrás de binários e outros problemas" +msgstr "Pular o escaneamento do código-fonte atrás de binários e outros problemas" #: ../fdroidserver/update.py #, python-brace-format @@ -1434,7 +1435,7 @@ msgstr "O código de versão OBB deve estar após \"{name}.\":" #: ../fdroidserver/btlog.py msgid "The base URL for the repo to log (default: https://f-droid.org)" -msgstr "O URL base para o registro de mudanças do repositório (padrão: https://f-droid.org)" +msgstr "O URL base para o registro de mudanças do repositório (predefinição: https://f-droid.org)" #: ../fdroidserver/mirror.py msgid "The directory to write the mirror to" @@ -1522,7 +1523,7 @@ msgstr "Versão desconhecida do aapt, pode causar problemas: " #: ../fdroidserver/lint.py msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" -msgstr "Link des-link-ado - use [http://foo.bar Título do link] ou [http://foo.bar]" +msgstr "Ligação des-lig-ada - use [http://foo.bar Título do link] ou [http://foo.bar]" #: ../fdroidserver/lint.py msgid "Unnecessary leading space" @@ -1642,7 +1643,7 @@ msgstr "Utilização: %s\n" #: ../fdroidserver/lint.py msgid "Use /HEAD instead of /master to point at a file in the default branch" -msgstr "Use /HEAD em vez de /master para apontar em um ficheiro na ramificação predefinida" +msgstr "Use /HEAD em vez de /master para apontar num ficheiro na ramificação predefinida" #: ../fdroidserver/update.py msgid "Use `fdroid update -c` to create it." @@ -1693,7 +1694,7 @@ msgstr "Verifique a cópia em cache local em vez de redescarregando." #: ../fdroid msgid "Verify the integrity of downloaded packages" -msgstr "Verifique a integridade dos pacotes baixados" +msgstr "Verifique a integridade dos pacotes descarregados" #: ../fdroidserver/index.py msgid "Verifying index signature:" @@ -1716,7 +1717,7 @@ msgstr "X.509 'Distiguished Name' usado na geração de chaves" #: ../fdroidserver/common.py msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" -msgstr "Você pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou seja:" +msgstr "Pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou seja:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -1784,7 +1785,7 @@ msgstr "não é possível unir ações - dois grupos são denominados %r" #: ../fdroidserver/nightly.py msgid "cannot publish update, did you set the deploy key?" -msgstr "não é possível publicar a atualização, você definiu a chave de implantação?" +msgstr "não é possível publicar a atualização, definiu a chave de implantação?" #: ../fdroidserver/nightly.py #, python-brace-format @@ -1929,7 +1930,7 @@ msgstr "Opção cadeia %(option)r inválida: deve começar com o caractere %(pre #: ../fdroidserver/server.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" -msgstr "local_copy_dir não termina com \"fdroid\", talvez você quis: \"{path}\"" +msgstr "local_copy_dir não termina com \"fdroid\", talvez quis: \"{path}\"" #: ../fdroidserver/server.py msgid "local_copy_dir must be an absolute path!" @@ -1987,7 +1988,7 @@ msgstr "apenas aceita cadeias, listas e tuplos" #: ../fdroidserver/install.py #, python-format msgid "option %s: If you really want to install all the signed apps, use --all" -msgstr "opção %s: se você realmente deseja instalar todas as apps assinadas, use --all" +msgstr "opção %s: se realmente deseja instalar todas as apps assinadas, use --all" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2084,7 +2085,7 @@ msgstr "mostrar esta ajuda e sair" #: ../fdroidserver/signatures.py msgid "signed APK, either a file-path or HTTPS URL." -msgstr "APK assinado, seja um caminho de arquivo ou um URL HTTPS." +msgstr "APK assinado, seja um caminho de ficheiro ou um URL HTTPS." #: ../fdroidserver/common.py msgid "skip deploying full build logs: log content is empty" @@ -2166,7 +2167,7 @@ msgstr "{apkfilename} ({appid}) não tem metadados!" #: ../fdroidserver/update.py #, python-brace-format msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" -msgstr "{apkfilename} tem vários arquivos {name} que, parece explorar a Master Key!" +msgstr "{apkfilename} tem vários ficheiros {name} que, parece explorar a Master Key!" #: ../fdroidserver/update.py #, python-brace-format @@ -2232,7 +2233,7 @@ msgstr "{path} não existe! Crie-o executando:" #: ../fdroidserver/update.py #, python-brace-format msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" -msgstr "{path} tem uma má assinatura de arquivo \"{pattern}\", um exploração Janus é possível!" +msgstr "{path} tem uma má assinatura de ficheiro \"{pattern}\", um exploração Janus é possível!" #: ../fdroidserver/update.py #, python-brace-format From 51a449e71e27af15582fbac722a6c68f6484933e Mon Sep 17 00:00:00 2001 From: Juraj Liso Date: Thu, 1 Oct 2020 11:00:51 +0200 Subject: [PATCH 0526/2775] Added translation using Weblate: Slovak (sk) by Juraj Liso Co-authored-by: Juraj Liso --- locale/sk/LC_MESSAGES/fdroidserver.po | 2251 +++++++++++++++++++++++++ 1 file changed, 2251 insertions(+) create mode 100644 locale/sk/LC_MESSAGES/fdroidserver.po diff --git a/locale/sk/LC_MESSAGES/fdroidserver.po b/locale/sk/LC_MESSAGES/fdroidserver.po new file mode 100644 index 00000000..ff887d67 --- /dev/null +++ b/locale/sk/LC_MESSAGES/fdroidserver.po @@ -0,0 +1,2251 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# Juraj Liso , 2020. +msgid "" +msgstr "" +"Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" +"Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" +"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH Public Key to be used as Deploy Key:" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "" +"\n" +"{path} encoded for the DEBUG_KEYSTORE secret variable:" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "\"%s/\" has no matching metadata file!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains outdated {name} ({version})" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains recent {name} ({version})" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "\"{path}\" exists but s3cmd is not installed!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "\"{path}\" is not an accepted format, convert to: {formats}" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%(option)s option requires %(number)d argument" +msgid_plural "%(option)s option requires %(number)d arguments" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../fdroidserver/mirror.py +#, python-format +msgid "%(prog)s [options] url" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%(prog)s: error: %(message)s\n" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "%d problems found" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "%prog [options]" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%r is not callable" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "%s is not an accepted build field" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%s option does not take a value" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keypass' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystore' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystorepass' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'repo_keyalias' not found in config.py!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "'required' is an invalid argument for positionals" +msgstr "" + +#: ../fdroidserver/common.py +msgid "'sdk_path' not set in 'config.py'!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "'{apkfilename}' is already installed on {dev}." +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{path}' failed to execute!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "...checkupdate failed for {appid} : {error}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid ".__call__() not defined" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "/issues is missing" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "A URL is required as an argument!" +msgstr "" + +#: ../fdroid +msgid "Add PGP signatures using GnuPG for packages in repo" +msgstr "" + +#: ../fdroid +msgid "Add a new application from its source code" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Add a repo signing key to an unsigned repo" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Add skeleton metadata files for APKs that are missing them" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Adding new repo for only {name}" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Alias of the repo signing key in the keystore" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Allows a different revision (or git branch) to be specified for the initial import" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Also mirror the full archive section" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Also warn about formatting issues, like rewritemeta -l" +msgstr "" + +#: ../fdroidserver/common.py ../fdroidserver/build.py +#, python-brace-format +msgid "Android SDK '{path}' does not have '{dirname}' installed!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Android SDK not found!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' is not a directory!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android build-tools path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "AndroidManifest.xml has no date" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "App is in '{repo}' but has a link to {url}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Appending .git is not necessary" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Archiving {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in srclib '{srclib}'" +msgstr "" + +#: ../fdroid +msgid "Build a package from source" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build all applications available" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Build generated by `fdroid import` - remove disable line once ready" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Build metadata git repo has uncommited changes!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build only the latest version of each package" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "Built repo based in \"%s\" with this config:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Can't build due to {} error while scanning" +msgid_plural "Can't build due to {} errors while scanning" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find a packageName for {path}!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find an appid for {path}!" +msgstr "" + +#: ../fdroidserver/vmtools.py +#, python-brace-format +msgid "Cannot read \"{path}\"!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot resolve app id {appid}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Cannot use --list and --to at the same time" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Categories '%s' is not valid" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Categories are not set" +msgstr "" + +#: ../fdroid +msgid "Check for updates to applications" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean after all scans have finished" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean before the scans start and rebuild the container" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean up all containers and then exit" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Clean update - don't uses caches, reprocess all APKs" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Comma separated list of categories." +msgstr "" + +#: ../fdroid +#, c-format, python-format +msgid "Command '%s' not recognised.\n" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not find '{command}' on your system" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not find {path} to remove it" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Could not open apk file for analysis" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/import.py +msgid "Couldn't find latest version code" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/import.py +msgid "Couldn't find latest version name" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find package ID" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Cowardily refusing to overwrite existing signing key setup!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create a repo signing key in a keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create skeleton metadata files that are missing" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Created new container \"{name}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Creating log directory" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating new S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Creating output directory" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Creating signed index with this key (SHA256):" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/verify.py +#: ../fdroidserver/publish.py +msgid "Creating temporary directory" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Creating unsigned index in preparation for signing" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "DEBUG_KEYSTORE is not set or the value is incomplete" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Delete APKs and/or OBBs without metadata from the repo" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Deleting unknown file: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description '%s' is just the app's summary" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Description has a duplicate line" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description has a list (%s) but it isn't bulleted (*) nor numbered (#)" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Description of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not deploy the new files to the repo" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Do not include \"{path}\" in URL!" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Do not prompt for Android SDK path, just fail" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not remove the private keys generated from the keystore" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't create a source tarball, useful when testing a build" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Don't do anything logs-related" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't refresh the repository, useful when testing a build with no internet connection" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/upload.py +msgid "Don't use rsync checksums" +msgstr "" + +#: ../fdroid +msgid "Download complete mirrors of small repos" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Download logs we don't have" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Downloading the repository already failed once, not trying again." +msgstr "" + +#: ../fdroidserver/verify.py +#, python-brace-format +msgid "Downloading {url} failed. {error}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Duplicate build recipe found for versionCode {versionCode} in {linedesc}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Duplicate link in '{field}': {url}" +msgstr "" + +#: ../fdroid +msgid "Dynamically scan APKs post build" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "" +"ERROR: this command should never be used to mirror f-droid.org!\n" +"A full mirror of f-droid.org requires more than 200GB." +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "ERROR: unsupported CI type, patches welcome!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Empty build flag at {linedesc}" +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"Enter the path to the Android SDK (%s) here:\n" +"> " +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/upload.py +#, python-format +msgid "Error while attempting to publish log: %s" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Error while getting repo address" +msgstr "" + +#: ../fdroid +msgid "Extract signatures from APKs" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Failed fetching signatures for '{apkfilename}': {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed reading {path}: {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed resizing {path}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Failed to align application" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Failed to create S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to get APK manifest information" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, deleting {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, skipping {path}" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Failed to install '{apkfilename}' on {dev}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/common.py +msgid "Failed to sign application" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to zipalign application" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Fetched buildserverid from VM: {buildserverid}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py +#: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "Finished" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID flag" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Forbidden HTML tags" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Force halting build after {0} sec timeout!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Found invalid appids in arguments" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Found invalid versionCodes for some apps" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Found multiple metadata files for {appid}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found multiple signing certificates for repository." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found multiple signing certificates in {path}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found no signing certificates for repository." +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Found non-file at %s" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Generated skeleton metadata for {appid}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git checkout of '%s' failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git clean failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git fetch failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git remote set-head failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git reset failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule sync failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule update failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "HTTPS must be used with Subversion URLs!" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Ignoring package without metadata: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Ignoring stale cache data for {apkfilename}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Ignoring {ext} file at '{path}'" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Include APKs that are signed with disabled algorithms like MD5" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Initialising submodules" +msgstr "" + +#: ../fdroidserver/install.py +msgid "Install all signed applications available" +msgstr "" + +#: ../fdroid +msgid "Install built packages on devices" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s…" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}…" +msgstr "" + +#: ../fdroid +msgid "Interact with the repo HTTP server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Invalid APK" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid VercodeOperation: {field}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid boolean '%s'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build flag at {line} in {linedesc}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build format: {value} in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid bulleted list" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid metadata in %s:%d" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Invalid metadata in: " +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Invalid name for published file: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid package name {0}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid redirect to non-HTTPS: {before} -> {after} " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature failed to verify: {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature verified: {path}" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#: ../fdroidserver/mirror.py +msgid "Java JDK not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Java jarsigner not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Javascript in HTML src attributes" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Keystore for signing key:\t" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the LiberapayID flag" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "List files that would be reformatted" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Locale included in f-droid.org URL" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Make the build stop on exceptions" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Malformed repository mirrors." +msgstr "" + +#: ../fdroidserver/server.py +msgid "Malformed serverwebroot line:" +msgstr "" + +#: ../fdroidserver/gpgsign.py +msgid "Missing output directory" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Name '%s' is just the auto name - remove it" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No 'config.py' found, using defaults." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No Android SDK found!" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No android or kivy project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No attached devices found" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "No commit specified for {versionName} in {linedesc}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "No fingerprint in URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No git submodules available" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No information found." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is Free Software" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is for Android" +msgstr "" + +#: ../fdroidserver/server.py +msgid "No option set! Edit your config.py to set at least one of these:" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No packages specified" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "No signed apk available for %s" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No signed output directory - nothing to do" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "No signing certificates found in {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "No such package: %s" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No such versionCode {versionCode} for app {appid}" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +msgid "No unsigned directory - nothing to do" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Nothing to do" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Nothing to do for {appid}." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Now set these in config.py:" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "OBB file has newer versionCode({integer}) than any APK:" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB filename must start with \"main.\" or \"patch.\":" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB's packagename does not match a supported APK:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Old APK signature failed to verify: {path}" +msgstr "" + +#: ../fdroid +msgid "Old, deprecated name for fdroid deploy" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Only PNG and JPEG are supported for graphics, found: {path}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only print differences with the Play Store" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only process apps with auto-updates" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Options" +msgstr "" + +#: ../fdroidserver/verify.py +msgid "Output JSON report to file named after APK." +msgstr "" + +#: ../fdroidserver/import.py +msgid "Overall license of the project." +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Override path for repo APKs (default: ./repo)" +msgstr "" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Parsing manifest at '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Password required with username" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Path to main Android project subdirectory, if not in root." +msgstr "" + +msgid "Path to main android project subdirectory, if not in root." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Path to the git repo to use as the log" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the keystore for the repo signing key" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Prepare Drozer to run a scan" +msgstr "" + +msgid "Prepare drozer to run a scan" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Print the secret variable to the terminal for easy copy/paste" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Problem with description of {appid}: {error}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Problem with xml at '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Process auto-updates" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#, python-brace-format +msgid "Processing {apkfilename}" +msgstr "" + +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#, python-brace-format +msgid "Processing {appid}" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable XML/JSON for index files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable index.xml" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Project URL to import from." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Punctuation should be avoided" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Push the log to this git remote repository" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing binary transparency log to {url}" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing to {url}" +msgstr "" + +#: ../fdroid +msgid "Quickly start a new repository" +msgstr "" + +#: ../fdroid +msgid "Read all the metadata files and exit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading '{config_file}'" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading minSdkVersion failed: \"{apkfilename}\"" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Reading {apkfilename} from cache" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Removing specified files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Rename APK files that do not match package.name_123.apk" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Report on build data status" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Reset and create a brand new build server, even if the existing one appears to be ok." +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Resigning {apkfilename} with provided debug.keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Resize all the icons exceeding the max pixel size and exit" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Restrict output to warnings and errors" +msgstr "" + +#: ../fdroid +msgid "Rewrite all the metadata files" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Rewrite to a specific format: " +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}'" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}' to '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Run on git repo that has uncommitted changes" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Run rewritemeta to fix formatting" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Running first pass with MD5 checking disabled" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Running wget in {path}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Scan only the latest version of each package" +msgstr "" + +#: ../fdroid +msgid "Scan the source code of a package" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:{versionCode}:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Scanner found {} problem" +msgid_plural "Scanner found {} problems" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../fdroidserver/common.py +msgid "Set clock to that time using:" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Set open file limit to {integer}" +msgstr "" + +#: ../fdroid +msgid "Set up an app build for a nightly build repo" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setting open file limit failed: " +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Setting {0} sec timeout for this build" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setup an emulator, install the APK on it and perform a Drozer scan" +msgstr "" + +msgid "Setup an emulator, install the apk on it and perform a drozer scan" +msgstr "" + +#: ../fdroid +msgid "Sign and place packages in the repo" +msgstr "" + +#: ../fdroid +msgid "Sign indexes created using update --nosign" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Skip scanning the source code for binaries and other problems" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping '{apkfilename}' with invalid signature!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping index generation for {appid}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: disabled" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: no builds specified" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify a local folder to sync the repo to" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify an identity file to provide to SSH for rsyncing" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Specify that we're running on the build server" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Specify which debug keystore file to use." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Spew out even more information than normal" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Striping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Summary '%s' is just the app's name" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Summary of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "System clock is older than date in {path}!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "The OBB version code must come after \"{name}.\":" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "The base URL for the repo to log (default: https://f-droid.org)" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "The directory to write the mirror to" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "The file to be included in the repo (path or glob)" +msgstr "" + +#: ../fdroidserver/server.py +msgid "The only commands currently supported are 'init' and 'update'" +msgstr "" + +#: ../fdroidserver/index.py +msgid "The repository's fingerprint does not match." +msgstr "" + +#: ../fdroidserver/common.py +msgid "The repository's index could not be verified." +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "The root dir for local_copy_dir \"{path}\" does not exist!" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "There is a keyalias collision - publishing halted" +msgstr "" + +#: ../fdroidserver/import.py +#, python-format +msgid "This repo already has local metadata: %s" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "URL shorteners should not be used" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "URL title is just the URL, use brackets: [URL]" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "URL {url} in Description: {error}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unexpected text on same line as {field} in {linedesc}" +msgstr "" + +#: ../fdroid +msgid "Unknown exception found!" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Unknown file '{filename}' in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Unknown metadata format: %s" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path}" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Unknown version of aapt, might cause problems: " +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary leading space" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary trailing space" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised app field '{fieldname}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unrecognised app field: " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised build flag '{build_flag}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised field '{field}' in {linedesc}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported file type \"{extension}\" for repo graphic" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported graphics file found: {path}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Unsupported metadata format, use: --to [{supported}]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated build in {name}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated continuation in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused extlib at %s" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused file at %s" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Update Check Name is set to the known app id - it can be removed" +msgstr "" + +#: ../fdroid +msgid "Update repo information for new packages" +msgstr "" + +#: ../fdroid +msgid "Update the binary transparency log for a URL" +msgstr "" + +#: ../fdroid +msgid "Update the stats of the repo" +msgstr "" + +#: ../fdroidserver/update.py ../fdroidserver/build.py +msgid "Update the wiki" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "UpdateCheckData has invalid URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must use HTTPS URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData not a valid URL: {url}" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Usage" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "Usage: %s\n" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Use /HEAD instead of /master to point at a file in the default branch" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use `fdroid update -c` to create it." +msgstr "" + +#: ../fdroidserver/build.py +msgid "Use build server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use date from APK instead of current time for newly added APKs" +msgstr "" + +msgid "Use date from apk instead of current time for newly added apks" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Using androguard from \"{path}\"" +msgstr "" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Using existing keystore \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using s3cmd to sync with: {url}" +msgstr "" + +#: ../fdroid +msgid "Valid commands are:" +msgstr "" + +#: ../fdroidserver/verify.py +msgid "Verify against locally cached copy rather than redownloading." +msgstr "" + +#: ../fdroid +msgid "Verify the integrity of downloaded packages" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Verifying index signature:" +msgstr "" + +#: ../fdroid +msgid "Warn about possible metadata errors" +msgstr "" + +#: ../fdroidserver/update.py +msgid "When configured for signed indexes, create only unsigned indexes at this stage" +msgstr "" + +msgid "X.509 'Distiguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/init.py +msgid "X.509 'Distinguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/common.py +msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "adding IdentityFile to {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "adding to {name}: {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ambiguous option: %(option)s could match %(matches)s" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "ambiguous option: %s (%s?)" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +msgid "applicationId in the form APPID" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "applicationId to check for updates" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/dscanner.py ../fdroidserver/build.py +#: ../fdroidserver/scanner.py ../fdroidserver/install.py +msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "argument \"-\" with mode %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "attempting bare ssh connection to test deploy key:" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "can't open '%s': %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "cannot have multiple subparser arguments" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "cannot merge actions - two groups are named %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "cannot publish update, did you set the deploy key?" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "cloning {url}" +msgstr "" + +#: ../fdroidserver/server.py +msgid "command to execute, either 'init' or 'update'" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "complex" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "conflicting option string: %s" +msgid_plural "conflicting option strings: %s" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "copying {apkfilename} into {path}" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "created {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "deleting: repo/{apkfilename}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed build logs to '{path}'" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "dest= is required for options like %r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "expected %s argument" +msgid_plural "expected %s arguments" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at least one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at most one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected one argument" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "failed deploying build logs to '{path}'" +msgstr "" + +#: ../fdroid +msgid "fdroid [-h|--help|--version] []" +msgstr "" + +#: ../fdroid +msgid "fdroid [] [-h|--help|--version|]" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "floating-point" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force errors to be warnings, or ignore" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force metadata errors (default) to be warnings, or to be ignored." +msgstr "" + +#: ../fdroidserver/common.py +msgid "git svn clone failed" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ignored explicit argument %r" +msgstr "" + +#: ../fdroidserver/index.py +msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "integer" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid %(type)s value: %(value)r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid choice: %(value)r (choose from %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid conflict_resolution value: %r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be an absolute path!" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be directory, not a file!" +msgstr "" + +#: ../fdroidserver/index.py +#, python-format +msgid "mirror '%s' does not end with 'fdroid'!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "mutually exclusive arguments must be optional" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "no \"icon\" in {appid}" +msgstr "" + +#: ../fdroidserver/signatures.py +msgid "no APK supplied" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "no such option: %s" +msgstr "" + +#: ../fdroid +msgid "no version info found!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "not allowed with argument %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "one of the arguments %s is required" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "only accepts strings, lists, and tuples" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "option %s: If you really want to install all the signed apps, use --all" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid %s value: %r" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid choice: %r (choose from %s)" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s not recognized" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s requires argument" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s must not have an argument" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not a unique prefix" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not recognized" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s requires argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "optional arguments" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "overwriting existing {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "positional arguments" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "s3cmd sync indexes {path} to {url} and delete" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "show program's version number and exit" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.5/optparse.py +#: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py +msgid "show this help message and exit" +msgstr "" + +#: ../fdroidserver/signatures.py +msgid "signed APK, either a file-path or HTTPS URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: log content is empty" +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: not enabled in config" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "skipping source tarball: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "srclibs missing name and/or @" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "the following arguments are required: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unexpected option string: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unknown parser %(parser_name)r (choices: %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unrecognized arguments: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "unsafe permissions on '{config_file}' (should be 0600)!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid +#: /usr/lib/python3.7/argparse.py +msgid "usage: " +msgstr "" + +#: ../fdroid +msgid "usage: fdroid [-h|--help|--version] []" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "using Apache libcloud to sync with {url}" +msgstr "" + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "{0} app, {1} key aliases" +msgid_plural "{0} apps, {1} key aliases" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} ({appid}) has no metadata!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using package name instead." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android Package Name!" +msgstr "" + +#: ../fdroidserver/metadata.py ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Java Package Name!" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{appid} is missing {name}" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: Unknown extlib {path} in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "{appid}: no builds specified, running on current source state" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{field} not terminated in {name}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{name} \"{path}\" does not exist! Correct it in config.py." +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "{path} does not exist! Create it by running:" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} is zero size!" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{url} does not end with \"fdroid\", check the URL path!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "{} build failed" +msgid_plural "{} builds failed" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../fdroidserver/build.py +msgid "{} build succeeded" +msgid_plural "{} builds succeeded" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" From 976cd0aa03aba79be43ba6c44cbf9d08bfeaead1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Thu, 1 Oct 2020 11:00:51 +0200 Subject: [PATCH 0527/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l=20(nb=5FNO)=20by=20Allan=20Nordh=C3=B8y=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 66.6% (318 of 477 strings) Co-authored-by: Allan Nordhøy Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/nb_NO/ Translation: F-Droid/F-Droid Server --- locale/nb_NO/LC_MESSAGES/fdroidserver.po | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index 7e97df1c..3e57a123 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -1,13 +1,12 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. -# FIRST AUTHOR , YEAR. -# +# Allan Nordhøy , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-74-ga380b9f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2019-01-29 07:59+0000\n" +"PO-Revision-Date: 2020-08-15 21:32+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" "Language: nb_NO\n" @@ -15,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.5-dev\n" +"X-Generator: Weblate 4.2-dev\n" #: ../fdroidserver/nightly.py #, fuzzy @@ -1451,9 +1450,9 @@ msgid "Spew out even more information than normal" msgstr "Gulp opp enda mer info enn normalt" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Striping mystery signature from {apkfilename}" -msgstr "Klarte ikke å hente signaturer for '{apkfilename}': {error}" +msgstr "Stripper mystisk signatur fra {apkfilename}" #: ../fdroidserver/lint.py #, fuzzy, python-format @@ -1586,20 +1585,18 @@ msgid "Unnecessary trailing space" msgstr "Unødvendig etterfølgende mellomrom" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Unrecognised field '{field}' in {linedesc}" +#, python-brace-format msgid "Unrecognised app field '{fieldname}' in '{path}'" -msgstr "Ugjenkjent felt \"{field}\" i {linedesc}" +msgstr "Ugjenkjent felt «{fieldname}» i «{path}»" #: ../fdroidserver/metadata.py msgid "Unrecognised app field: " msgstr "Ugjenkjent programfelt: " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Unrecognised field '{field}' in {linedesc}" +#, python-brace-format msgid "Unrecognised build flag '{build_flag}' in '{path}'" -msgstr "Ugjenkjent felt \"{field}\" i {linedesc}" +msgstr "Ugjenkjent felt «{build_flag}» i «{path}»" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1875,7 +1872,7 @@ msgstr[1] "konflikterende valgstrenger: %s" #: ../fdroidserver/nightly.py #, fuzzy, python-brace-format msgid "copying {apkfilename} into {path}" -msgstr "Behandler {apkfilename}" +msgstr "kopierer {apkfilename} inn i {path}" #: ../fdroidserver/nightly.py #, python-brace-format From 4343dbb90aa0f1a4562fe3c5957ebee100891f80 Mon Sep 17 00:00:00 2001 From: Hinaloe Date: Thu, 1 Oct 2020 11:00:52 +0200 Subject: [PATCH 0528/2775] Translated using Weblate: Japanese (ja) by Hinaloe Currently translated at 1.6% (8 of 477 strings) Co-authored-by: Hinaloe Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ja/ Translation: F-Droid/F-Droid Server --- locale/ja/LC_MESSAGES/fdroidserver.po | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/locale/ja/LC_MESSAGES/fdroidserver.po b/locale/ja/LC_MESSAGES/fdroidserver.po index b62d4e4d..e8521511 100644 --- a/locale/ja/LC_MESSAGES/fdroidserver.po +++ b/locale/ja/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,20 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# +# Hinaloe , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-224-g4b0ade7\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2020-09-02 16:10+0000\n" +"Last-Translator: Hinaloe \n" +"Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -75,7 +75,7 @@ msgstr "" #: ../fdroidserver/scanner.py #, python-format msgid "%d problems found" -msgstr "" +msgstr "%d個の問題が見つかりました" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -130,17 +130,17 @@ msgstr "" #: ../fdroidserver/common.py #, python-brace-format msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" -msgstr "" +msgstr "'{aapt}' は古すぎます、froid は build-tools-23.0.0 またはそれ以降が必要です!" #: ../fdroidserver/common.py #, python-brace-format msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" -msgstr "" +msgstr "'{aapt}' は古すぎます、froid は build-tools-{version} またはそれ以降が必要です!" #: ../fdroidserver/install.py #, python-brace-format msgid "'{apkfilename}' is already installed on {dev}." -msgstr "" +msgstr "'{apkfilename}'はすでに{dev}にインストールされています。" #: ../fdroidserver/metadata.py #, python-brace-format @@ -238,7 +238,7 @@ msgstr "" #: ../fdroidserver/common.py #, python-brace-format msgid "Android SDK path '{path}' is not a directory!" -msgstr "" +msgstr "Android SDK パス '{path}' はディレクトリではありません!" #. Translators: "build-tools" is the file name of a package from #. Google, it is part of the Android SDK. So it probably shouldn't be @@ -1915,15 +1915,15 @@ msgstr "" #: ../fdroidserver/server.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" -msgstr "" +msgstr "local_copy_dir は「froid」で終わっていません、もしかして: 「{path}」" #: ../fdroidserver/server.py msgid "local_copy_dir must be an absolute path!" -msgstr "" +msgstr "local_copy_dir は絶対パスの必要があります!" #: ../fdroidserver/server.py msgid "local_copy_dir must be directory, not a file!" -msgstr "" +msgstr "local_copy_dir はファイルではなくディレクトリにする必要があります!" #: ../fdroidserver/index.py #, python-format From 569e33bc2a160b18857accf3765b3b9f9314d71b Mon Sep 17 00:00:00 2001 From: IvanDan Date: Thu, 1 Oct 2020 11:00:52 +0200 Subject: [PATCH 0529/2775] Translated using Weblate: Italian (it) by IvanDan Currently translated at 39.6% (189 of 477 strings) Co-authored-by: IvanDan Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/it/ Translation: F-Droid/F-Droid Server --- locale/it/LC_MESSAGES/fdroidserver.po | 33 +++++++++++++++------------ 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index c7e7e882..552c8633 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -3,20 +3,21 @@ # This file is distributed under the same license as the PACKAGE package. # random r , 2020. # Luca Zambarda , 2020. +# IvanDan , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-07-18 09:41+0000\n" -"Last-Translator: Luca Zambarda \n" +"PO-Revision-Date: 2020-09-19 17:03+0000\n" +"Last-Translator: IvanDan \n" "Language-Team: Italian \n" "Language: it\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 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -515,7 +516,7 @@ msgstr "La descrizione di lunghezza {length} supera il limite di {limit} caratte #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" -msgstr "" +msgstr "Non distribuire i nuovi file nel repository" #: ../fdroidserver/mirror.py #, python-brace-format @@ -528,7 +529,7 @@ msgstr "Non chiedere il path di Android SDK, esci subito con un errore" #: ../fdroidserver/nightly.py msgid "Do not remove the private keys generated from the keystore" -msgstr "" +msgstr "Non rimuovere le chiavi private generate dal keystore" #: ../fdroidserver/build.py msgid "Don't create a source tarball, useful when testing a build" @@ -583,6 +584,8 @@ msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" "A full mirror of f-droid.org requires more than 200GB." msgstr "" +"ERRORE: questo comando non deve mai essere utilizzato per il mirror f-droid.org!\n" +"L’intero mirror di f-droid.org richiede più di 200GB." #: ../fdroidserver/nightly.py msgid "ERROR: unsupported CI type, patches welcome!" @@ -591,7 +594,7 @@ msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Empty build flag at {linedesc}" -msgstr "" +msgstr "Flag build vuoto a {linedesc}" #: ../fdroidserver/init.py #, python-format @@ -619,45 +622,45 @@ msgstr "Estrai le firme dagli APK" #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" -msgstr "" +msgstr "Impossibile recuperare le firme per '{apkfilename}': {error}" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed reading {path}: {error}" -msgstr "" +msgstr "Impossibile leggere {path}: {error}" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed resizing {path}: {error}" -msgstr "" +msgstr "Impossibile ridimensionare {path}: {error}" #: ../fdroidserver/publish.py msgid "Failed to align application" -msgstr "" +msgstr "Impossibile allineare l’applicazione" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" -msgstr "" +msgstr "Impossibile creare il bucket S3: {url}" #: ../fdroidserver/common.py msgid "Failed to get APK manifest information" -msgstr "" +msgstr "Impossibile ottenere informazioni del manifest dell’APK" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed to get apk information, deleting {path}" -msgstr "" +msgstr "Impossibile ottenere informazioni dell’apk, eliminando {path}" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed to get apk information, skipping {path}" -msgstr "" +msgstr "Impossibile ottenere informazioni dell’apk, saltando {path}" #: ../fdroidserver/install.py #, python-brace-format msgid "Failed to install '{apkfilename}' on {dev}: {error}" -msgstr "" +msgstr "Impossibile installare '{apkfilename}' su {dev}: {error}" #: ../fdroidserver/publish.py ../fdroidserver/common.py msgid "Failed to sign application" From 9c5cd28ea6968422b0332fe6550f950b8ac29a60 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 1 Oct 2020 11:00:53 +0200 Subject: [PATCH 0530/2775] Translated using Weblate: German (de) by Fynn Godau Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Fynn Godau Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/de/ Translation: F-Droid/F-Droid Server --- locale/de/LC_MESSAGES/fdroidserver.po | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index e4283e25..849f49d3 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # Oliver , 2020. +# Fynn Godau , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-03-28 20:09+0000\n" -"Last-Translator: Oliver \n" +"PO-Revision-Date: 2020-09-23 14:57+0000\n" +"Last-Translator: Fynn Godau \n" "Language-Team: German \n" "Language: de\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 4.0-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -2107,7 +2108,7 @@ msgstr "gelieferter Zeitstempelwert '{timestamp}' ist kein Unix-Zeitstempel" #: /usr/lib/python3.7/argparse.py #, python-format msgid "the following arguments are required: %s" -msgstr "die Folgenden Argumente sind erforderlich: %s" +msgstr "die Folgenden Argumente sind erforderlich: %s" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py From abc6d5339eafdeabceaca4a1ec9f33a226846568 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 11:00:54 +0200 Subject: [PATCH 0531/2775] fix failing checks in Weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translated using Weblate: Norwegian Bokmål (nb_NO) by Hans-Christoph Steiner Currently translated at 66.8% (319 of 477 strings) Translated using Weblate: French (fr) by Hans-Christoph Steiner Currently translated at 74.4% (355 of 477 strings) Translated using Weblate: Kabyle (kab) by Hans-Christoph Steiner Currently translated at 4.4% (21 of 477 strings) Translated using Weblate: Portuguese (Portugal) (pt_PT) by Hans-Christoph Steiner Currently translated at 100.0% (477 of 477 strings) Translated using Weblate: Portuguese (Brazil) (pt_BR) by Hans-Christoph Steiner Currently translated at 100.0% (477 of 477 strings) Translated using Weblate: Chinese (Traditional) (zh_Hant) by Hans-Christoph Steiner Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Hans-Christoph Steiner Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/kab/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_PT/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hant/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 16 ++++++++-------- locale/kab/LC_MESSAGES/fdroidserver.po | 17 +++++++---------- locale/nb_NO/LC_MESSAGES/fdroidserver.po | 20 ++++++++++---------- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 15 ++++++++------- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 19 ++++++++----------- locale/zh_Hant/LC_MESSAGES/fdroidserver.po | 17 +++++++++-------- 6 files changed, 50 insertions(+), 54 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index b33fa1d1..f520a9be 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -17,15 +17,15 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-07-14 17:29+0000\n" -"Last-Translator: rational \n" +"PO-Revision-Date: 2020-10-01 09:00+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: French \n" "Language: fr\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 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -86,7 +86,7 @@ msgstr "%(prog)s [options] url" #: /usr/lib/python3.7/argparse.py #, python-format msgid "%(prog)s: error: %(message)s\n" -msgstr "%(prog)s: erreur: %(message)s\n" +msgstr "%(prog)s : erreur : %(message)s\n" #: ../fdroidserver/scanner.py #, python-format @@ -161,7 +161,7 @@ msgstr "'{apkfilename}' est déjà installé sur '{dev}'." #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" -msgstr "'{field}' dans {linedesc} est obselète, regarder la documentation pour ces champs:" +msgstr "'{field}' dans {linedesc} est obselète, regarder la documentation pour ces champs :" #: ../fdroidserver/common.py #, python-brace-format @@ -320,7 +320,7 @@ msgstr "Compiler uniquement la dernière version de chaque paquet" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" -msgstr "Le build devrait avoir un versionName et un versionCode séparés par des virgules, et non pas \"{value}\", dans {linedesc}" +msgstr "Le build devrait avoir un versionName et un versionCode séparés par des virgules, et non pas \"{value}\", dans {linedesc}" #: ../fdroidserver/init.py #, python-format @@ -640,7 +640,7 @@ msgstr "Erreur de lecture {path} : {error}" #: ../fdroidserver/update.py #, python-brace-format msgid "Failed resizing {path}: {error}" -msgstr "Échec au redimensionement de {path}: {error}" +msgstr "Échec au redimensionement de {path} : {error}" #: ../fdroidserver/publish.py msgid "Failed to align application" @@ -2119,7 +2119,7 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "the following arguments are required: %s" -msgstr "les arguments suivants sont requis %s" +msgstr "les arguments suivants sont requis %s" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py diff --git a/locale/kab/LC_MESSAGES/fdroidserver.po b/locale/kab/LC_MESSAGES/fdroidserver.po index 951e1355..ea8ccc38 100644 --- a/locale/kab/LC_MESSAGES/fdroidserver.po +++ b/locale/kab/LC_MESSAGES/fdroidserver.po @@ -1,22 +1,20 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. -# FIRST AUTHOR , YEAR. -# -#, fuzzy +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2017-11-10 09:07+0000\n" -"Last-Translator: Muḥend Belqasem \n" +"PO-Revision-Date: 2020-10-01 09:00+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Kabyle \n" "Language: kab\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.18-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -136,9 +134,9 @@ msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" msgstr "'{aapt}' d aqbuṛ, fdroid yesra build-tools-23.0.0 neɣ amaynut!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" -msgstr "'{aapt}' d aqbuṛ, fdroid yesra build-tools-23.0.0 neɣ amaynut!" +msgstr "'{aapt}' d aqbuṛ, fdroid yesra build-tools-{version} neɣ amaynut!" #: ../fdroidserver/install.py #, python-brace-format @@ -1033,9 +1031,8 @@ msgid "Nothing to do for {appid}." msgstr "" #: ../fdroidserver/init.py -#, fuzzy msgid "Now set these in config.py:" -msgstr "'sdk_path' ur yettwasbadu ara 'config.py'!" +msgstr "" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index 3e57a123..55df985b 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # Allan Nordhøy , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-74-ga380b9f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-08-15 21:32+0000\n" -"Last-Translator: Allan Nordhøy \n" +"PO-Revision-Date: 2020-10-01 09:00+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Norwegian Bokmål \n" "Language: nb_NO\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 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py #, fuzzy @@ -37,7 +38,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-format msgid "\"%s/\" has no matching metadata file!" -msgstr "\"%s/\" har ingen samsvarende metadatafil." +msgstr "\"%s/\" har ingen samsvarende metadatafil!" #: ../fdroidserver/update.py #, python-brace-format @@ -50,9 +51,9 @@ msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" inneholder nylig {name} ({version})" #: ../fdroidserver/server.py ../fdroidserver/upload.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" -msgstr "\"{path}\" finnes, men s3cmd er ikke installert." +msgstr "\"{path}\" finnes, men s3cmd er ikke installert!" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1071,9 +1072,8 @@ msgid "Nothing to do for {appid}." msgstr "Ingenting å gjøre for {appid}." #: ../fdroidserver/init.py -#, fuzzy msgid "Now set these in config.py:" -msgstr "'sdk_path' ble ikke funnet i config.py!" +msgstr "" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -1998,11 +1998,11 @@ msgstr "local_copy_dir slutter ikke med \"fdroid\", kanskje du mente: \"{path}\" #: ../fdroidserver/server.py msgid "local_copy_dir must be an absolute path!" -msgstr "local_copy_dir må være en absolutt sti." +msgstr "local_copy_dir må være en absolutt sti!" #: ../fdroidserver/server.py msgid "local_copy_dir must be directory, not a file!" -msgstr "local_copy_dir må være ei mappe, ikke ei fil." +msgstr "local_copy_dir må være ei mappe, ikke ei fil!" #: ../fdroidserver/index.py #, fuzzy, python-format diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 693ab09d..df151aed 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -2,20 +2,21 @@ # Copyright (C) YEAR Free Software Foundation, Inc. # Wellington Terumi Uemura , 2020. # André Marcelo Alvarenga , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-05-27 06:45+0000\n" -"Last-Translator: Wellington Terumi Uemura \n" +"PO-Revision-Date: 2020-10-01 09:00+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\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 4.1-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -156,7 +157,7 @@ msgstr "O '{field}' em {linedesc} é obsoleto, veja a documentação para conhec #: ../fdroidserver/common.py #, python-brace-format msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" -msgstr "'{field}' será em ordem aleatória! Use () ou [] se a ordem for importante!" +msgstr "'{field}' será em ordem aleatória! Use () ou [] se a ordem for importante!" #: ../fdroidserver/common.py #, python-brace-format @@ -166,7 +167,7 @@ msgstr "'{path}' falhou ao executar!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" -msgstr "'{value}' não é um{field} válido em {appid}. Regex padrão: {pattern}" +msgstr "'{value}' não é um{field} válido em {appid}. Regex padrão: {pattern}" #: ../fdroidserver/checkupdates.py #, python-brace-format @@ -411,7 +412,7 @@ msgstr "Impossível encontrar {path} para removê-lo" #: ../fdroidserver/update.py msgid "Could not open apk file for analysis" -msgstr "Impossível abrir o arquivo de APK para analisá-lo" +msgstr "Impossível abrir o arquivo de APK para analisá-lo" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -1753,7 +1754,7 @@ msgstr "applicationId para verificar se há atualizações" #: ../fdroidserver/dscanner.py ../fdroidserver/build.py #: ../fdroidserver/scanner.py ../fdroidserver/install.py msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" -msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" +msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index 4392963c..84187861 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -3,20 +3,21 @@ # This file is distributed under the same license as the PACKAGE package. # Manuela Silva , 2020. # ssantos , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-08-15 21:32+0000\n" -"Last-Translator: ssantos \n" +"PO-Revision-Date: 2020-10-01 09:00+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Portuguese (Portugal) \n" "Language: pt_PT\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 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -157,7 +158,7 @@ msgstr "O '{field}' em {linedesc} é obsoleto, veja os documentos para os campos #: ../fdroidserver/common.py #, python-brace-format msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" -msgstr "'{field}' será em ordem aleatória! Use () ou [] se a ordem for importante!" +msgstr "'{field}' será em ordem aleatória! Use () ou [] se a ordem for importante!" #: ../fdroidserver/common.py #, python-brace-format @@ -1754,7 +1755,7 @@ msgstr "applicationId para verificar se há atualizações" #: ../fdroidserver/dscanner.py ../fdroidserver/build.py #: ../fdroidserver/scanner.py ../fdroidserver/install.py msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" -msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" +msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2056,16 +2057,12 @@ msgstr "argumentos posicionais" #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" -msgstr "" -"Recusado o download via conexão HTTP insegura (use HTTPS ou especifique --no-https-check): \n" -"{apkfilename}" +msgstr "Recusado o download via conexão HTTP insegura (use HTTPS ou especifique --no-https-check): {apkfilename}" #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" -msgstr "" -"Recusado o download via conexão http insegura (use https ou especifique --no-https-check): \n" -"{apkfilename}" +msgstr "Recusado o download via conexão http insegura (use https ou especifique --no-https-check): {apkfilename}" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index 9c1358ba..a8d022d6 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # Jeff Huang , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-06-28 04:34+0000\n" -"Last-Translator: Jeff Huang \n" +"PO-Revision-Date: 2020-10-01 09:00+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -338,7 +339,7 @@ msgstr "無法讀取 \"{path}\"!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Cannot resolve app id {appid}" -msgstr "無法解析 {appid} id" +msgstr "無法解析 {appid} id" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -744,7 +745,7 @@ msgstr "為 {appid} 建立缺少的骨幹中介資料檔案" #: ../fdroidserver/common.py #, python-format msgid "Git checkout of '%s' failed" -msgstr "Git '%s' 還原失敗" +msgstr "Git '%s' 還原失敗" #: ../fdroidserver/common.py msgid "Git clean failed" @@ -1476,7 +1477,7 @@ msgstr "UCM 已被設定但它似乎尚未曾執行更新檢查" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" -msgstr "不應使用 URL 縮短網址" +msgstr "不應使用 URL 縮短網址" #: ../fdroidserver/metadata.py msgid "URL title is just the URL, use brackets: [URL]" @@ -1827,7 +1828,7 @@ msgstr "已將構建記錄部署到「{path}」" #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" -msgstr "dest= 如 %r 選項為必須" +msgstr "dest= 如 %r 選項為必須" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -1993,7 +1994,7 @@ msgstr "選項 %s: 無效的 %s 值: %r" #: /usr/lib/python3.7/optparse.py #, python-format msgid "option %s: invalid choice: %r (choose from %s)" -msgstr "選項 %s: 無效選項: %r (選自 %s )" +msgstr "選項 %s: 無效選項: %r (選自 %s )" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py From e1d3de71cf0f534881715524c9e39280270ad540 Mon Sep 17 00:00:00 2001 From: riveravaldez Date: Thu, 1 Oct 2020 12:31:02 +0200 Subject: [PATCH 0532/2775] Translated using Weblate: Spanish (Argentina) (es_AR) by riveravaldez Currently translated at 17.4% (83 of 477 strings) Co-authored-by: riveravaldez Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es_AR/ Translation: F-Droid/F-Droid Server --- locale/es_AR/LC_MESSAGES/fdroidserver.po | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/locale/es_AR/LC_MESSAGES/fdroidserver.po b/locale/es_AR/LC_MESSAGES/fdroidserver.po index f0323c3d..b9a248e3 100644 --- a/locale/es_AR/LC_MESSAGES/fdroidserver.po +++ b/locale/es_AR/LC_MESSAGES/fdroidserver.po @@ -2,13 +2,14 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Hans-Christoph Steiner , 2020. +# riveravaldez , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2019-01-28 13:31+0000\n" -"PO-Revision-Date: 2020-10-01 09:00+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-10-01 10:31+0000\n" +"Last-Translator: riveravaldez \n" "Language-Team: Spanish (Argentina) \n" "Language: es_AR\n" "MIME-Version: 1.0\n" @@ -1136,7 +1137,7 @@ msgid "Prepare Drozer to run a scan" msgstr "" msgid "Prepare drozer to run a scan" -msgstr "" +msgstr "Preparar drozer para que ejecute un escaneo" #: ../fdroidserver/nightly.py msgid "Print the secret variable to the terminal for easy copy/paste" @@ -1714,7 +1715,7 @@ msgstr "Advertir sobre posibles errores en los metadatos" #: ../fdroidserver/update.py msgid "When configured for signed indexes, create only unsigned indexes at this stage" -msgstr "" +msgstr "Si está configurado para índices firmados, crear sólo índices sin firma en este punto" msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Nombre Distinguido' usado cuando se generaron las llaves" @@ -1942,17 +1943,18 @@ msgid "invalid option string %(option)r: must start with a character %(prefix_ch msgstr "" #: ../fdroidserver/server.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" -msgstr "" +msgstr "directorio_copia_local no termina en \"fdroid\", quizá quiso escribir: \"{ruta}\"" #: ../fdroidserver/server.py +#, fuzzy msgid "local_copy_dir must be an absolute path!" -msgstr "" +msgstr "directorio_copia_local ¡tiene que ser una ruta absoluta!" #: ../fdroidserver/server.py msgid "local_copy_dir must be directory, not a file!" -msgstr "" +msgstr "directorio_copia_local tiene que ser un directorio, ¡no un archivo!" #: ../fdroidserver/index.py #, python-format @@ -2161,7 +2163,7 @@ msgstr "uso: fdroid [-h|--help|--version] []" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" -msgstr "" +msgstr "usando libcloud de Apache para sincronizar con {url}" #: ../fdroidserver/publish.py #, python-brace-format From 64e170b5915166d0e953133a9d79fef9764997a3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 12:34:45 +0200 Subject: [PATCH 0533/2775] make -C locale update --- locale/bn/LC_MESSAGES/fdroidserver.po | 462 +++++++++++++++++-- locale/bo/LC_MESSAGES/fdroidserver.po | 489 ++++++++++++++++++-- locale/cs/LC_MESSAGES/fdroidserver.po | 463 +++++++++++++++++-- locale/de/LC_MESSAGES/fdroidserver.po | 495 ++++++++++++++++++-- locale/es/LC_MESSAGES/fdroidserver.po | 493 ++++++++++++++++++-- locale/es_AR/LC_MESSAGES/fdroidserver.po | 485 ++++++++++++++++++-- locale/es_MX/LC_MESSAGES/fdroidserver.po | 465 +++++++++++++++++-- locale/fa/LC_MESSAGES/fdroidserver.po | 462 +++++++++++++++++-- locale/fdroidserver.pot | 464 +++++++++++++++++-- locale/fr/LC_MESSAGES/fdroidserver.po | 499 ++++++++++++++++++-- locale/hu/LC_MESSAGES/fdroidserver.po | 465 +++++++++++++++++-- locale/it/LC_MESSAGES/fdroidserver.po | 469 +++++++++++++++++-- locale/ja/LC_MESSAGES/fdroidserver.po | 462 +++++++++++++++++-- locale/kab/LC_MESSAGES/fdroidserver.po | 462 +++++++++++++++++-- locale/ko/LC_MESSAGES/fdroidserver.po | 468 +++++++++++++++++-- locale/ml/LC_MESSAGES/fdroidserver.po | 462 +++++++++++++++++-- locale/nb_NO/LC_MESSAGES/fdroidserver.po | 475 +++++++++++++++++-- locale/pl/LC_MESSAGES/fdroidserver.po | 475 +++++++++++++++++-- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 495 ++++++++++++++++++-- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 475 +++++++++++++++++-- locale/ru/LC_MESSAGES/fdroidserver.po | 475 +++++++++++++++++-- locale/sk/LC_MESSAGES/fdroidserver.po | 462 +++++++++++++++++-- locale/sq/LC_MESSAGES/fdroidserver.po | 475 +++++++++++++++++-- locale/sv/LC_MESSAGES/fdroidserver.po | 462 +++++++++++++++++-- locale/tr/LC_MESSAGES/fdroidserver.po | 499 ++++++++++++++++++-- locale/ug/LC_MESSAGES/fdroidserver.po | 462 +++++++++++++++++-- locale/uk/LC_MESSAGES/fdroidserver.po | 501 +++++++++++++++++++-- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 489 ++++++++++++++++++-- locale/zh_Hant/LC_MESSAGES/fdroidserver.po | 495 ++++++++++++++++++-- 29 files changed, 12828 insertions(+), 977 deletions(-) diff --git a/locale/bn/LC_MESSAGES/fdroidserver.po b/locale/bn/LC_MESSAGES/fdroidserver.po index 0f4ac1f0..8af6283e 100644 --- a/locale/bn/LC_MESSAGES/fdroidserver.po +++ b/locale/bn/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -16,12 +16,28 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -34,6 +50,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -49,11 +70,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -104,6 +135,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -185,11 +220,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -222,6 +257,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -282,7 +329,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "" @@ -338,6 +390,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -356,7 +413,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -385,7 +442,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -394,11 +451,23 @@ msgstr "" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -408,6 +477,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -483,6 +561,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -507,6 +595,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -541,7 +633,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -587,6 +679,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -600,14 +697,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -669,6 +771,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -680,6 +787,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -693,11 +804,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -707,6 +827,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -730,6 +855,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -752,6 +882,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -768,6 +903,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -786,6 +940,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -794,21 +960,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -873,6 +1049,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -888,11 +1079,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -910,6 +1109,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -934,6 +1137,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -973,6 +1180,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1001,7 +1212,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1021,6 +1232,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1053,7 +1268,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1070,6 +1285,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1079,6 +1298,16 @@ msgstr "" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1092,6 +1321,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1185,11 +1419,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1248,7 +1482,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1287,7 +1521,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1311,12 +1549,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1336,11 +1578,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1398,6 +1640,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1456,6 +1703,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1469,6 +1720,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1482,12 +1737,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1507,6 +1770,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1585,19 +1853,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1620,6 +1898,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1655,6 +1943,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1674,7 +1970,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1682,7 +1978,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1690,7 +1986,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1698,6 +1999,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1709,6 +2014,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1731,6 +2040,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1752,16 +2065,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1786,6 +2112,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1804,6 +2134,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1819,12 +2162,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1857,7 +2209,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1878,6 +2230,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1955,7 +2311,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2043,6 +2399,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2053,11 +2414,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2090,6 +2459,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2125,7 +2498,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2138,6 +2511,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2201,16 +2578,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2226,11 +2618,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/bo/LC_MESSAGES/fdroidserver.po b/locale/bo/LC_MESSAGES/fdroidserver.po index 12942ab9..4aceece8 100644 --- a/locale/bo/LC_MESSAGES/fdroidserver.po +++ b/locale/bo/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2018-02-13 08:41+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Tibetan \n" @@ -17,6 +17,16 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 2.19-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -25,6 +35,15 @@ msgstr "" "\n" "SSHདམངས་ཀྱི་ལྡེ་མིག་དེ་ཕྱོགས་སྐྱོད་ལྡ་ེམིག་ལ་བེད་སྤྱོད་བྱེད།:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"SSHདམངས་ཀྱི་ལྡེ་མིག་དེ་ཕྱོགས་སྐྱོད་ལྡ་ེམིག་ལ་བེད་སྤྱོད་བྱེད།:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -39,6 +58,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" འདི་དང་མཐུན་པའི་རྒྱབ་ལྗོངས་ཡིག་ཆ་མིན་འདུག!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' འདི་{dev}.ནང་སྔོན་ཚོད་ནས་སྒྲིག་བཅུག་བྱས་ཟིན།." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -54,11 +78,21 @@ msgstr "\"{path}\" ཉེ་ཆར་{name} ({version})རྣམས་ཚུད msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}སྒྲིག་བཀོད་འདི་ངོས་ལེན་བྱེད་ཐུབ་ཀྱི་མིན་འདུག:{formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}སྒྲིག་བཀོད་འདི་ངོས་ལེན་བྱེད་ཐུབ་ཀྱི་མིན་འདུག:{formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -108,6 +142,10 @@ msgstr "%sགདམ་ཀ་ནུས་མེད་རེད་འདུག" msgid "'keypass' not found in config.py!" msgstr "'keypass' འདི་config.py ནང་རྙེད་མ་སོང་།!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore' འདི་ config.py ནང་རྙེད་མ་སོང་།!" @@ -190,11 +228,11 @@ msgstr "/གནས་དོན་བོར་བརླག་སོང་འད msgid "A URL is required as an argument!" msgstr "གདམ་ཀ། -%s 1 རྩོད་དགོས།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "PGP གྱི་མིང་རྟགས་དེ་རེ་པོ་ཐུམ་སྒྲིལ་ནང་GnuPG ཁ་སྣོན་བྱས་ནས་རེ་པོ་ནང་ལ་བཅུག" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "འབྱུང་ཁུངས་ཨང་རྟགས་ནས་མཉེན་ཆས་གསར་པ་ཁ་སྣོན་བྱེད།" @@ -227,6 +265,19 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "མ་ཟད་བཀོད་སྒྲིག་བྱས་པའི་གནད་དོན་རྣམས་ལ་ཉེན་བརྡ་སྟོན། དཔེར་ན་rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "ཨེན་ཀྲོཌ་ SDK རྙེད་མ་སོང་།!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -287,7 +338,12 @@ msgstr "ཡན་ལག '{branch}1' བཟོ་སྐྲུན་ནང་བ msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "ཡན་ལག '{branch}1'' srclib ནང་བེད་སྤྱོད་བྱེད་རྒྱུ་ཁས་ལེན་ཡོད་།'{srclib}'" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "འབྱུང་ཁུངས་ནས་ཐུམ་སྒྲིལ་བཟོས་འདུག" @@ -342,6 +398,11 @@ msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" msgid "Cannot resolve app id {appid}" msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "བེད་སྤྱོད་གཏོང་མི་ཐུབ་། --ཐོ་གཞུང་དང--དུས་མཉམ།" @@ -360,7 +421,7 @@ msgstr "སྡེ་ཚན་'%s' ཁུངས་ལྡན་མ་རེད།" msgid "Categories are not set" msgstr "སྡེ་ཚན་རྣམས་སྒྲིག་མེད།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "མཉེན་ཆས་རྣམས་གསར་བསྒྱུར་བྱས་མིན་གཟིགས་ཞིབ་གནང་དང་།" @@ -389,7 +450,7 @@ msgstr "གསར་བསྒྱུར་གཙང་བཟོ།-ཡིག་ msgid "Comma separated list of categories." msgstr "སྡེ་ཚན་སོ་སོའི་ཐོ་གཞུང་ལ་བར་མཚམས་རེ་འཇོག།." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "བཀའ་ཁྱབ་ '%s 1'ངོས་འཛིན་ཐུབ་མ་སོང་།\n" @@ -398,11 +459,25 @@ msgstr "བཀའ་ཁྱབ་ '%s 1'ངོས་འཛིན་ཐུབ་ msgid "Commit changes" msgstr "བསྒྱུར་བ་གཏོང་བར་མོས་མཐུན་ཡོད།" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "ཁྱེད་རང་གི་མ་ལག་སྒང་ལ་'{command}1' རྙེད་མ་སོང་།" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "ཐོན་རིམ་གསར་གསར་ཤོས་ཀྱི་ཨང་རྟགས་འདི་འདི་རྙེད་མ་སོང་།" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "ཐོན་རིམ་གསར་ཤོས་འདིའི་མིང་རྙེད་མ་སོང་།" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -412,6 +487,16 @@ msgstr "{path}མེད་པ་བཟོས་པ་ལ་རྙེད་མ་ msgid "Could not open apk file for analysis" msgstr "དཔྱད་ཞིབ་ཀྱི་ཆེད་དུ་apk ཡིག་ཆ་ཁ་ཕྱེས་ཐུབ་ཀྱི་མིན་འདུག" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "ཐུམ་སྒྲིལ་ངོས་འཛིན་རྙེད་སོན་བྱུང་མ་སོང་།" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -487,6 +572,16 @@ msgstr "DEBUG_KEYSTORE སྒྲིག་བཀོད་བྱེད་མིན msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "APKs དང/ཡང་ནOBBs གཉིས་ལ་རེ་པོ་ནས་འགྲེལ་ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་མེད་པ་རྣམས་སུབས།" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -511,6 +606,10 @@ msgstr "འགྲེལ་བཤད་འདི་ལ་ཐོ་གཞུང་ msgid "Description of length {length} is over the {limit} char limit" msgstr "རིང་ཐུང་གི་འགྲེལ་བཤད་ {length} {limit} ལས་བརྒལ་འདུག char limit" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -545,7 +644,7 @@ msgstr "མཛོད་ཁང་སྐྱར་སོས་མ་བྱེད། msgid "Don't use rsync checksums" msgstr "rsync ཡིག་ཚགས་བརྟག་དཔྱད་ཀྱི་གསོག་ཉར་ཁང་འདི་བེད་སྤྱོད་མ་བྱེད།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -591,6 +690,11 @@ msgstr "ནོར་འཁྲུལ།: རྒྱབ་སྐྱོར་མེ msgid "Empty build flag at {linedesc}" msgstr "{linedesc}ལ་ཡོད་པའི་བཟོ་དར་སྟོང་པ།" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -606,14 +710,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "རེ་པོ་ཁ་བྱང་ལེན་སྐབས་ནོར་སྐྱོན།: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "རེ་པོ་ཁ་བྱང་ལེན་སྐབས་ནོར་སྐྱོན།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "APKs ནས་མིང་རྟགས་ཕྱིར་སྟོན་བྱེད།" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "ཀློག་མི་ཐུབ།{path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -676,6 +785,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "'{apkfilename}' ཆེད་དུ་མིང་རྟགས་འཚོལ་བཞིན་པ།་> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -687,6 +801,11 @@ msgstr "ཚར་སོང་།" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Flattr ཞལ་འདེབས་ཐབས་ལམ་འདི་བཞིན་FlattrID flag ལ་ཐོབ་ཀྱི་ཡོད་།" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Flattr ཞལ་འདེབས་ཐབས་ལམ་འདི་བཞིན་FlattrID flag ལ་ཐོབ་ཀྱི་ཡོད་།" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -700,11 +819,20 @@ msgstr "ནུས་མེད་མཉེན་ཆས་ལ་ཐོན་སྐ msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "\"{name}\" བརྐོད་རིས་མེད་པའི་མཉེས་ཆས་ཀྱི་རྒྱབ་ལྗོངས་ཡིག་ཆ་\"{path}\"རྙེད་སོང་།!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "རྩོད་པའི་ནང་ཁུངས་ལྡན་མིན་པའི་appids རྙེད་འདུག" @@ -714,6 +842,11 @@ msgstr "རྩོད་པའི་ནང་ཁུངས་ལྡན་མིན msgid "Found invalid versionCodes for some apps" msgstr "མཉེན་ཆས་ཁ་ཤས་ཀྱི་ཁུངས་ལྡན་མིན་པའི་ཐོན་རིམ་ཨང་རྟགས་རྙེད་འདུག" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "{path}ནང་ལ་སྣ་མང་མིང་རྟགས་ཆོག་མཆན་ལག་ཁྱེར་རྙེད་སོང་།" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -737,6 +870,11 @@ msgstr "མཛོད་ཁང་ཆེད་དུ་མིང་རྟགས་ msgid "Found non-file at %s" msgstr "འདི་ལ་%s 1 ཡིག་ཆ་མིན་པ་རྙེད་སོང་།" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "{path} ནང་ལ་ {apkfilename}ཤུས་བཞིན་པ།" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -759,6 +897,11 @@ msgstr "གིཊ་འཚོལ་ཐུབ་མ་སོང་།" msgid "Git remote set-head failed" msgstr "གིཊ་རྒྱང་ཐག་སྒྲིག་འགོ་ཐུབ་མ་སོང་།" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "གིཊ་རྒྱང་ཐག་སྒྲིག་འགོ་ཐུབ་མ་སོང་།" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "གིཊ་སྐྱར་སྒྲིག་ཐུབ་མ་སོང་།" @@ -775,6 +918,25 @@ msgstr "གིཊ་ཡན་ལག་རྒྱ་ཁྱོན་གསར་བ msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "རྒྱབ་ལྗོངས་ཡིག་ཆ་མེད་པའི་ཐུམ་སྒྲིལ་ཡ་ལན་མ་བྱས། " @@ -793,6 +955,18 @@ msgstr "{ext} ཡིག་ལ་ཡ་ལན་མེད་པ་ '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "MD5ལྟ་བུའི་མཚན་རྟགས་ཡོད་པའི་APKs ནང་ཚུད།" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "ཐོག་མིའི་ཡན་ལག་རྒྱ་ཁྱོན།" @@ -801,21 +975,31 @@ msgstr "ཐོག་མིའི་ཡན་ལག་རྒྱ་ཁྱོན། msgid "Install all signed applications available" msgstr "ཡོད་བཞིན་པའི་མིང་རྟགས་བཀོད་པའི་མཉེན་ཆས་ཆ་ཚང་འགྲིག་བཅུག་བྱེད།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "ཡོ་བྱད་སྒང་གི་ཐུམ་སྒྲིལ་བཟོས་པ་རྣམས་འགྲིག་བཅུག་བྱེད།" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "སྒྲིག་བཅུག་བྱེད་བཞིན་པ།%s 1…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "སྒྲིག་བཅུག་བྱེད་བཞིན་པ།%s 1…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "'{apkfilename}' སྒྲིག་བཅུག་བྱེད་བཞིན་པ{dev}གྱི་སྒང་ལ་…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "'{apkfilename}' སྒྲིག་བཅུག་བྱེད་བཞིན་པ{dev}གྱི་སྒང་ལ་…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "རེ་པོ་HTTP ཞབས་ཞུ་འཕྲུལ་ཆས་དང་ཐུགས་ཕྲད།" @@ -880,6 +1064,21 @@ msgstr "ཁུངས་ལྡན་མིན་པའི་ཐུམ་སྒྲ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་ཀློག་ནས་ཕྱིར་ཐོན།" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -895,11 +1094,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Java JDK རྙེད་མ་སོང་།! ཚད་ལྡན་གྱི་ས་གནས་ནང་སྒྲིག་བཅུག་བྱེད་པའམ་ཡང་ན་java_paths སྒྲིག!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Java jarsigner རྙེད་མ་སོང་། !ཚད་ལྡན་གྱི་ས་གནས་ནང་སྒྲིག་བཅུག་བྱེད་པའམ་ཡང་ན་java_paths སྒྲིག!" @@ -917,6 +1124,11 @@ msgstr "མིང་རྟགས་བཀོད་པའི་ལྡེ་མི msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "ཁས་ལེན་བྱས་པའི་བེད་སྤྱོད་ཐ་མ་ '{commit}' སྦྱར་བ་འདྲ་པོ་འདུག, འོན་ཀྱང་གསར་བསྒྱུར་ཡོད་མེད་འཚོལ་བྱེད་ནི།'{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Flattr ཞལ་འདེབས་ཐབས་ལམ་འདི་བཞིན་FlattrID flag ལ་ཐོབ་ཀྱི་ཡོད་།" + #: ../fdroidserver/lint.py #, fuzzy msgid "Liberapay donation methods belong in the LiberapayID flag" @@ -942,6 +1154,10 @@ msgstr "བཟོ་ལྟ་མེད་པའི་མཛོད་ཁང་ཤ msgid "Malformed serverwebroot line:" msgstr "བཟོ་ལྟ་ཤོར་བའི་ serverwebroot line:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "ཕྱོགས་དེབ་ཐོན་སྐྱེད་བོར་བརླག" @@ -981,6 +1197,11 @@ msgid "No git submodules available" msgstr "གིཊ་ཡན་ལག་རྒྱ་ཁྱོན་མིན་འདུག" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "ཨེན་ཀྲོཌ་དང་ཡང་ན་ཀི་བི་ལས་འཆར་གང་ཡང་རྙེད་ས་མ་རེད། དམིགས་སྟོན་བྱེད་--subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "གནས་ཚུལ་རྙེད་མ་སོང་།." @@ -1009,7 +1230,7 @@ msgstr "%s 1ཆེད་དུ་མིང་རྟགས་བཀོད་པ msgid "No signed output directory - nothing to do" msgstr "མིང་རྟགས་མ་བཀོད་པའི་ཕྱོགས་དེབ་ཐོན་སྐྱེད། -བྱ་རྒྱུ་གང་ཡང་མེད།" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "{path}མིང་རྟགས་བཀོད་པའི་ཆོག་མཆན་ལག་ཁྱེར་འདིའི་ནང་རྙེད་མ་སོང་།" @@ -1029,6 +1250,10 @@ msgstr "ཐོན་རིམ་ཨང་རྟགས་དེ་འདྲ་མ msgid "No unsigned directory - nothing to do" msgstr "མིང་རྟགས་མ་བཀོད་པའི་ཕྱོགས་དེབ་མིན་འདུག-བྱ་རྒྱུ་གང་ཡང་མེད།" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "བྱ་རྒྱུ་གང་ཡང་མེད་།" @@ -1062,7 +1287,7 @@ msgstr "OBB's ཐུམ་སྒྲིལ་མིང་འདིས་APK ར msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1079,6 +1304,11 @@ msgstr "མཉེས་ཆས་གསོག་ཉར་ཁང་དང་མི msgid "Only process apps with auto-updates" msgstr "མཉེན་ཆས་ཁོ་ནར་རང་འགུལ་གསར་བསྒྱུར་བྱེད།" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Flattr ཞལ་འདེབས་ཐབས་ལམ་འདི་བཞིན་FlattrID flag ལ་ཐོབ་ཀྱི་ཡོད་།" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1088,6 +1318,16 @@ msgstr "གདམ་ཀ།" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "ལས་འཆར་འདིའི་ཁྱོན་ཡོངས་ཀྱི་ཆོག་མཆན་ལག་ཁྱེར།." @@ -1101,6 +1341,11 @@ msgstr "རེ་པོ་APKs ལམ་གྱི་སྒང་ལ་སྐྱ msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1194,11 +1439,11 @@ msgstr "{url}ཆེད་དུ་ཨང་གྲངས་ཀྱི་ཐོ་ msgid "Pushing to {url}" msgstr "{url}ཕྱོགས་ལ་འབུད་རྒྱབ་རྒྱོབ།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "མཛོད་ཁང་གསར་པ་ཞིག་མྱུར་དུ་འགོ་བཙུགས།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་ཀློག་ནས་ཕྱིར་ཐོན།" @@ -1257,7 +1502,7 @@ msgstr "པར་གྱི་རྒྱུ་ཆེ་ཆུང་ཚད་ལས msgid "Restrict output to warnings and errors" msgstr "ཡིག་ཚགས་ལ་ཉེན་བརྡ་དང་སྐྱོན་ཅན་རྣམས་དམ་བསྒྲགས་བྱེད།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་ཚང་མ་སྐྱར་ཟིན།" @@ -1296,7 +1541,11 @@ msgstr "སྐྱར་བྲིས་ཡོད་།{path}" msgid "Scan only the latest version of each package" msgstr "ཐུམ་སྒྲིལ་རེ་རེ་བའི་ཐོན་རིམ་གསར་ཤོས་གཅིག་པུ་འཚག་རྒྱབ།" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "ཐུམ་སྒྲིལ་བྱས་པའི་འབྱུང་ཁུངས་ཨང་རྟགས་འཚག་རྒྱབ" @@ -1319,12 +1568,16 @@ msgstr[0] "འཚག་རྒྱབ་ལ་སྐྱོན་རྙེད་པ msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "མཚན་མོའི་རེ་པོ་བཟོ་སྐྲུན་ཆེད་དུ་སྒྲིག་བཀོད་བྱས་པའི་མཉེན་ཆས་བཟོ་སྐྲུན།" @@ -1344,11 +1597,11 @@ msgstr "གློག་ཀླད་ལད་མོ་མཁན་ཞིག་ས msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "གློག་ཀླད་ལད་མོ་མཁན་ཞིག་སྒྲིག འདིའི་སྒང་ལ་apk ནང་འགྲིག་བཅུག་བྱེད་དུ་བཅུག་ནས་ཌོ་ཛར་འཚག་རྒྱབ་འགོ་བཙུགས་བྱེད།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "མིང་རྟགས་བཀོད་ནས་ཐུམ་སྒྲིལ་རྣམས་རེ་པོ་ནང་བཞག" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "གསར་བསྒྱུར་བེད་སྤྱོད་བྱས་ཏེ་བཟོས་པའི་མིང་རྟགས་བརྡ་སྟོན། --མིང་རྟགས་མེད།" @@ -1406,6 +1659,11 @@ msgstr "ནམ་རྒྱུན་ལས་ཀྱང་མང་བའི་ག msgid "Striping mystery signature from {apkfilename}" msgstr "{apkfilename}ཡིག་ཆ་སྦས་ཁུང་རྙིང་པ་ལ་ཡ་ལན་མ་བྱས་" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "{apkfilename}ཡིག་ཆ་སྦས་ཁུང་རྙིང་པ་ལ་ཡ་ལན་མ་བྱས་" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1464,6 +1722,10 @@ msgstr "dir གྱི་རྩ་བ་ for local_copy_dir \"{path}\" མིན msgid "There is a keyalias collision - publishing halted" msgstr "ལྡེ་མིག་གཞན་ལ་སྐྱོན་ཆ་འདུག། -པར་སྐྲུན་བཀག" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1477,6 +1739,10 @@ msgstr "awsbucket, awssecretkey དང་། awsaccesskeyid བེད་སྤ msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCMསྒྲིག་བཀོད་བྱས་ཟིན་ཡང་གསར་བསྒྱུར་འཚོལ་བ་དེ་འགོ་འཛུགས་མིན་འདུག" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "URL ཐུང་དུ་གཏོང་མཁན་ངེས་པར་དུ་བེད་སྤྱོད་བྱེད།" @@ -1490,12 +1756,21 @@ msgstr "URL འགོ་བརྗོད་དེ་URL རང་རེད་། msgid "URL {url} in Description: {error}" msgstr "URL {url} ནང་འགྲེལ་བཤད་རྒྱབ་པ་: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "ཁུངས་ལྡན་མིན་པའི་ཆོག་མཆན་ལག་ཁྱེར་སྦྱར་ \"%s 1\"! https://spdx.org/license-list ཁོ་ན་ནས་ཡིན་པ་སྦྱར་ཏེ་བེད་སྤྱོད་བྱེད་།" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "{linedesc}ནང་། {field}་ཁ་ཕྱོགས་དེ་ག་རང་ནང་རེ་བ་མ་བྱས་པའི་ཡིག་ཚགས་" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "ཆ་རྒྱུས་མེད་པའི་དམིགས་བསལ་ཞིག་རྙེད་སོང་།!" @@ -1515,6 +1790,11 @@ msgstr "ངོས་འཛིན་མ་བྱས་པའི་རྒྱབ་ msgid "Unknown metadata format: {path}" msgstr "ངོས་འཛིན་མི་ཐུབ་པའི་རྒྱབ་ལྗོངས་ཡིག་ཆའི་སྒྲིག་བཀོད། : {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "ངོས་འཛིན་མི་ཐུབ་པའི་རྒྱབ་ལྗོངས་ཡིག་ཆའི་སྒྲིག་བཀོད། : {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "aapt གྱི་ངོས་འཛིན་མ་ཐུབ་པའི་ཐོན་རིམ། དཀའ་ངལ་ཕྲད་སྲིད་པ།: " @@ -1533,7 +1813,6 @@ msgstr "དགོས་མེད་ཀྱི་རྫེས་ཤུལ་བར #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Unrecognised field '{field}' in {linedesc}" msgid "Unrecognised app field '{fieldname}' in '{path}'" msgstr "{linedesc}ནང་ངོས་འཛིན་མ་ཐུབ་པའི་རྭ་བ།{field}" @@ -1543,7 +1822,6 @@ msgstr "ངོས་འཛིན་མ་ཐུབ་པའི་མཉེན་ #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Unrecognised field '{field}' in {linedesc}" msgid "Unrecognised build flag '{build_flag}' in '{path}'" msgstr "{linedesc}ནང་ངོས་འཛིན་མ་ཐུབ་པའི་རྭ་བ།{field}" @@ -1595,19 +1873,29 @@ msgstr "བེད་སྤྱོད་མེད་པའི་ extlib at %s 1" msgid "Unused file at %s" msgstr "%s 1 དེ་ལ་བེད་སྤྱོད་མེད་པའི་ཡིག་ཆ།" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "%s 1 དེ་ལ་བེད་སྤྱོད་མེད་པའི་ཡིག་ཆ།" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "%s 1 དེ་ལ་བེད་སྤྱོད་མེད་པའི་ཡིག་ཆ།" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "མཉེན་ཆས་ཁ་བྱང་ནང་ལ་གསར་བསྒྱུར་འཚོལ་བའི་མིང་སྒྲིག་ཚར་འདུག -འདི་སུབས་ཆོག་གི་རེད།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "ཐུམ་སྒྲིལ་གསར་པའི་ཆེད་དུ་རེ་པོ་གནས་ཚུལ་གསར་བསྒྱུར་བྱེད།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "URLཆེད་དུ་ཨང་གྲངས་ཀྱི་ཐོ་གཞུང་གསར་བསྒྱུར།" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "རེ་པོའི་གྲངས་ཐོ་རྣམས་གསར་བསྒྱུར་བྱེད།" @@ -1630,6 +1918,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "སྦས་ཁུང་ནས་ {apkfilename}ཀློག་བཞིན་པ།" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1665,6 +1963,14 @@ msgstr "apk རང་གི་ཚེས་གྲངས་དེ་བེད་ msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1684,7 +1990,7 @@ msgstr "སྐྱར་བྲིས་ཡོད་།{path}" msgid "Using s3cmd to sync with: {url}" msgstr "s3cmd བེད་སྤྱོད་བྱས་ནས་: {url}1དང་མཉམ་དུ་sync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "ཁུངས་ལྡན་གྱི་བཀའ་ཁྱབ་ནི།:" @@ -1692,7 +1998,7 @@ msgstr "ཁུངས་ལྡན་གྱི་བཀའ་ཁྱབ་ནི། msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "ཕབ་ལེན་བྱས་པའི་ཐུམ་སྒྲིལ་གྱི་སྤུས་ཚད་ར་སྤྲོད།" @@ -1700,7 +2006,12 @@ msgstr "ཕབ་ལེན་བྱས་པའི་ཐུམ་སྒྲིལ msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་སྐྱོན་སྲིད་པ་རྣམས་པ་ཉེན་བརྡ་གཏོང་།" @@ -1708,6 +2019,10 @@ msgstr "ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལ msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "བརྡ་སྟོན་པའི་མིང་རྟགས་དེ་སྒྲིག་བཀོད་བྱས་ཚར་ན། གནས་སྐབས་མིང་རྟགས་མ་བཀོད་པའི་བརྡ་སྟོན་རྣམས་བཟོས།" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'ཁྱད་པར་ཅན་གྱི་མིང་' ལྡེ་མིག་བཟོས་པའི་སྐབས་ལ་བེད་སྤྱོད་བྱེད།" @@ -1719,6 +2034,10 @@ msgstr "X.509 'ཁྱད་པར་ཅན་གྱི་མིང་' ལྡེ msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "ཁྱེད་རང་གིས་ཨེན་ཀྲོཌ་མདུན་ངོས་བེད་སྤྱོད་བྱས་ནས་ཁྱེད་རང་གི་SDKའགྲོ་ལམ་སྒྲིག་བཀོད་བྱེད། དེ་ནི།:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1741,6 +2060,10 @@ msgstr "གསལ་ཁ་མེད་པའི་གདམ་ཀ: %(option)s msgid "ambiguous option: %s (%s?)" msgstr "གསལ་ཁ་མེད་པའི་གདམ་ཀ:%s 1 (%s 2?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "APPID བཀོད་པའི་ནང་གི་མཉེས་ཆས་ཁ་བྱང་།" @@ -1762,16 +2085,30 @@ msgstr "མཉེན་ཆས་ཀྱི་ངོ་བོ་དང་མཉམ msgid "argument \"-\" with mode %r" msgstr "རྩོད་པ།\"-\" འགྲོ་ལུགས་འདི་དང་མཉམ་དུ། %r 1" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "ཕྱོགས་སྐྱོད་ལྡེ་མིག་ཚོད་ལྟ་ལ་bare ssh མཐུད་ཀ་་རྒྱབ་བཞིན་པ།:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "ཕྱོགས་སྐྱོད་ལྡེ་མིག་ཚོད་ལྟ་ལ་bare ssh མཐུད་ཀ་་རྒྱབ་བཞིན་པ།:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "ཁ་ཕྱེས་ཐུབ་མ་སོང་།'%s 1': %s 2" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "{path}!གྱི་ཆེད་དུ་ཐུམ་སྒྲིལ་གྱི་མིང་རྙེད་མ་སོང་།" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1796,6 +2133,10 @@ msgstr "འདྲ་བཟོས་{url}" msgid "command to execute, either 'init' or 'update'" msgstr "ལག་བསྟར་བྱེད་རྒྱུར་བཀའ་གཏོང། ཡང་ན་'init'འམ་ཡང་ན་ 'གསར་བསྒྱུར།'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1813,6 +2154,19 @@ msgstr[0] "ཚིག་སྒྲུབ་ཀྱི་གདམ་ཀའི་ར msgid "copying {apkfilename} into {path}" msgstr "{path} ནང་ལ་ {apkfilename}ཤུས་བཞིན་པ།" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1828,12 +2182,21 @@ msgstr "སུབ་བཞིན་པ།:རེ་པོ་/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest= ནི་གདམ་ཀ་འདི་འདྲ་ལ་%r 1དགོས་པ་ཡོད།" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1865,7 +2228,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "བེད་སྤྱོད་: ཨེཕ་རོཌ་ [-h|-རོགས་པ་|--ཐོན་རིམ་] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, fuzzy msgid "fdroid [] [-h|--help|--version|]" msgstr "བེད་སྤྱོད་: ཨེཕ་རོཌ་ [-h|-རོགས་པ་|--ཐོན་རིམ་] []" @@ -1889,6 +2252,10 @@ msgstr "སྐྱོན་ཤོར་བ་ལ་ཉེན་བརྡ་ངེ msgid "git svn clone failed" msgstr "གིཊ་གཙང་བཟོ་ཐུབ་མ་སོང་།" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1966,7 +2333,7 @@ msgstr "APK མཁོ་སྤྲོད་མིན་འདུག" msgid "no such option: %s" msgstr "གདམ་ཀ་དེ་འདྲ་མིན་འདུག: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "ཆ་རྒྱུས་མེད་པའི་དམིགས་བསལ་ཞིག་རྙེད་སོང་།!" @@ -2054,6 +2421,11 @@ msgstr "སྐྱར་བྲིས་ཡོད་།{path}" msgid "positional arguments" msgstr "གནས་སྟངས་ལ་གཞིགས་པའི་རྩོད་པ།" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2064,11 +2436,19 @@ msgstr "བདེ་ཆགས་མེད་པའི་HTTPMམཐུད་ཀ msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "བེད་ཆགས་མེད་པའི་དྲྭ་རྒྱའི་ཁ་བྱང་http ནས་ཕབ་ལེན་བཀག། (use https or specify --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sync ཕྱོགས་སྟོན།{path}1 དེ་ནས {url} དང་སུབས།" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2101,6 +2481,10 @@ msgstr "tarballའབྱུང་ཁུངས་མཆོང་རྒྱག་ msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2136,7 +2520,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "'{config_file}' སྒང་གི་བདེ་ཆགས་མེད་པའི་ཆོག་མཆན་ (ངེས་པར་དུ། 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "བེད་སྤྱོད།: " @@ -2149,6 +2533,10 @@ msgstr "བེད་སྤྱོད་: ཨེཕ་རོཌ་[-h|--help|--ver msgid "using Apache libcloud to sync with {url}" msgstr "Apache libcloud བེད་སྤྱོད་བྱས་པའི་ཐོག་ {url}1དང་མཉམ་དུ་ཟླ་སྒྲིལ་གཏོང་།" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2211,16 +2599,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} སྒོ་རྒྱབ་མིན་འདུག {name}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" མིན་འདུག! config.pyནོར་བཅོས་བྱེད།." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, fuzzy, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2236,11 +2639,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "{path} ལ་ཆེ་ཆུང་མེད།!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, fuzzy, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "local_copy_dir \"fdroid\"གིས་མཇུག་སྐྱོང་མིན་འདུག་ : \"{path}1\"" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "local_copy_dir \"fdroid\"གིས་མཇུག་སྐྱོང་མིན་འདུག་ : \"{path}1\"" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2251,6 +2664,12 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} བཟོ་སྐྲུན་ལེགས་སྒྲུབ།" +#~ msgid "Android Build Tools path '{path}' does not exist!" +#~ msgstr "ཨེན་ཀྲོཌ་བཟོ་སྐྲུན་མ་ལག་ཐབས་ལམ '{path}1' མིན་འདུག!" + +#~ msgid "Clean update - don't uses caches, reprocess all apks" +#~ msgstr "གསར་བསྒྱུར་གཙང་བཟོ།-ཡིག་ཆ་གསོག་ཉར་བེད་སྤྱོ་མ་བྱེད། apks ཚང་མ་སྐྱར་སྤྱོད་བྱེད།" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "གསར་བསྒྱུར་བྱེད་དགོས་པའི་རིགས་ལ་སྦས་གསང་མེད་པའི་ཐོག་ནས་གསུངས་རོགས།." @@ -2263,12 +2682,6 @@ msgstr[0] "{} བཟོ་སྐྲུན་ལེགས་སྒྲུབ།" #~ msgid "Specify editor to use in interactive mode. Default is {path}" #~ msgstr "སྒྲིག་བཀོད་པར་དམིགས་སྟོན་བྱས་ནས་ལན་འདེབས་ཀྱི་ཚུལ་འདི་བེད་སྤྱོད་བྱེད་ སོར་བཞག་ནི་{path}" -#~ msgid "Android Build Tools path '{path}' does not exist!" -#~ msgstr "ཨེན་ཀྲོཌ་བཟོ་སྐྲུན་མ་ལག་ཐབས་ལམ '{path}1' མིན་འདུག!" - -#~ msgid "Clean update - don't uses caches, reprocess all apks" -#~ msgstr "གསར་བསྒྱུར་གཙང་བཟོ།-ཡིག་ཆ་གསོག་ཉར་བེད་སྤྱོ་མ་བྱེད། apks ཚང་མ་སྐྱར་སྤྱོད་བྱེད།" - #~ msgid "app-id in the form APPID" #~ msgstr "APPID བཀོད་པའི་ནང་གི་མཉེས་ཆས་ཁ་བྱང་།" diff --git a/locale/cs/LC_MESSAGES/fdroidserver.po b/locale/cs/LC_MESSAGES/fdroidserver.po index e7ac4c85..af51ae76 100644 --- a/locale/cs/LC_MESSAGES/fdroidserver.po +++ b/locale/cs/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2019-02-01 13:33+0000\n" "Last-Translator: Michal Čihař \n" "Language-Team: Czech \n" @@ -17,12 +17,28 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Weblate 3.5-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -35,6 +51,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -50,11 +71,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -106,6 +137,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -187,11 +222,11 @@ msgstr "/issues chybí" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -224,6 +259,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -284,7 +331,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Sestavit balíček ze zdroje" @@ -341,6 +393,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -359,7 +416,7 @@ msgstr "Kategorie „%s“ není platná" msgid "Categories are not set" msgstr "Kategorie nejsou nastavené" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -388,7 +445,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Příkaz '%s' nebyl rozpoznán.\n" @@ -397,11 +454,23 @@ msgstr "Příkaz '%s' nebyl rozpoznán.\n" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -411,6 +480,16 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Nedaří se nalézt identif. balíčku" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -486,6 +565,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -510,6 +599,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -544,7 +637,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -590,6 +683,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -603,14 +701,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -672,6 +775,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -683,6 +791,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -696,11 +808,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -710,6 +831,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -733,6 +859,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -755,6 +886,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -771,6 +907,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -789,6 +944,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -797,21 +964,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -876,6 +1053,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -891,11 +1083,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -913,6 +1113,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -937,6 +1141,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -976,6 +1184,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1004,7 +1216,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1024,6 +1236,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1056,7 +1272,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1073,6 +1289,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1082,6 +1302,16 @@ msgstr "Možnosti" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1095,6 +1325,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1188,11 +1423,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1251,7 +1486,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Přepsat všechny soubory metadat" @@ -1290,7 +1525,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1315,12 +1554,16 @@ msgstr[2] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1340,11 +1583,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1402,6 +1645,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1460,6 +1708,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1473,6 +1725,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1486,12 +1742,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Došlo k neznámé chybě!" @@ -1511,6 +1775,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1589,19 +1858,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Aktualizovat statistiky repozitáře" @@ -1624,6 +1903,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1659,6 +1948,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1678,7 +1975,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Platné příkazy jsou:" @@ -1686,7 +1983,7 @@ msgstr "Platné příkazy jsou:" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1694,7 +1991,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Varovat ohledně možných chyb metadat" @@ -1702,6 +2004,10 @@ msgstr "Varovat ohledně možných chyb metadat" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1713,6 +2019,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1735,6 +2045,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1756,16 +2070,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1790,6 +2117,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1809,6 +2140,19 @@ msgstr[2] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1824,12 +2168,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1863,7 +2216,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1884,6 +2237,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1961,7 +2318,7 @@ msgstr "" msgid "no such option: %s" msgstr "žádná taková volba: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2049,6 +2406,11 @@ msgstr "" msgid "positional arguments" msgstr "poziční argumenty" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2059,11 +2421,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2096,6 +2466,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2131,7 +2505,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "použití: " @@ -2144,6 +2518,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2208,16 +2586,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2233,11 +2626,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index 849f49d3..8894de30 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-09-23 14:57+0000\n" "Last-Translator: Fynn Godau \n" "Language-Team: German \n" @@ -17,6 +17,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -25,6 +35,15 @@ msgstr "" "\n" "Öffentlicher SSH-Schlüssel, der als Bereitstellungsschlüssel verwendet werden soll:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Öffentlicher SSH-Schlüssel, der als Bereitstellungsschlüssel verwendet werden soll:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -39,6 +58,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" besitzt keine zugehörige Metadaten-Datei!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' ist auf {dev} bereits installiert." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -54,11 +78,21 @@ msgstr "{name} ({version}) in \"{path}\" ist aktuell" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "„{path}” vorhanden, aber S3cmd ist nicht installiert!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" ist kein akzeptiertes Format, umwandeln in: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" ist kein akzeptiertes Format, umwandeln in: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -109,6 +143,10 @@ msgstr "Option %s verfügt über keinen Wert" msgid "'keypass' not found in config.py!" msgstr "„keypass” nicht in config.py vorhanden!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "„keystore” nicht in config.py vorhanden!" @@ -190,11 +228,11 @@ msgstr "/Probleme fehlen" msgid "A URL is required as an argument!" msgstr "Als Argument wird eine URL benötigt!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "GnuPG PGP-Signaturen für Programmpakete in der Paketquelle hinzufügen" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Eine neue Anwendung aus ihrem Quellcode hinzufügen" @@ -227,6 +265,19 @@ msgstr "Auch den gesamten Archivbereich spiegeln" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Auch vor Formatierungsfehler warnen, wie etwa \"rewritemeta -l\"" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Keine Android SDK gefunden!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -287,7 +338,12 @@ msgstr "Zweig „{branch}”, der als Bestätigung im Build verwendet wird „{v msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Zweig „{branch}” wird als Bestätigung in srclib verwendet „{srclib}”." -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Programmpaket aus Quellcode erstellen" @@ -343,6 +399,11 @@ msgstr "„{path}” konnte nicht gelesen werden!" msgid "Cannot resolve app id {appid}" msgstr "AppID {appid} konnte nicht aufgelöst werden" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "„{path}” konnte nicht gelesen werden!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "--list und --to können nicht gleichzeitig verwendet werden" @@ -361,7 +422,7 @@ msgstr "Kategorie »%s« ist nicht gültig" msgid "Categories are not set" msgstr "Kategorien sind nicht festgelegt" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Auf Aktualisierungen für Anwendungen prüfen" @@ -390,7 +451,7 @@ msgstr "Sauber aktualisieren - ohne Verwendung der Zwischenspeicher, alle APKs w msgid "Comma separated list of categories." msgstr "Liste der Kategorien durch Kommata getrennt." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Befehl '%s' nicht erkannt.\n" @@ -399,11 +460,25 @@ msgstr "Befehl '%s' nicht erkannt.\n" msgid "Commit changes" msgstr "Änderungen übergeben" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "„{command}” konnte auf Ihrem System nicht gefunden werden" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Neuester Versionscode konnte nicht gefunden werden" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Neuester Versionsname konnte nicht gefunden werden" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -413,6 +488,16 @@ msgstr "{path} konnte nicht gefunden werden, um ihn zu entfernen" msgid "Could not open apk file for analysis" msgstr "Konnte APK-Datei nicht für Analyse öffnen" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Konnte Paket-ID nicht finden" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -488,6 +573,16 @@ msgstr "DEBUG_KEYSTORE ist nicht festgelegt oder der Wert ist unvollständig" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "APKs und/oder OBBs ohne Metadaten aus dem Repository löschen" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -512,6 +607,10 @@ msgstr "Beschreibung enthält eine Liste (%s), ist aber weder aufgezählt (*) no msgid "Description of length {length} is over the {limit} char limit" msgstr "Beschreibung der Länge {length} ist über dem {limit}-Zeichen Limit" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Verteilen Sie die neuen Dateien nicht in das Repo" @@ -546,7 +645,7 @@ msgstr "Keine Aktualisierung des Repositorys. Nützlich, wenn ein Build ohne Int msgid "Don't use rsync checksums" msgstr "Keine rsync-Prüfsummen verwenden" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Komplette Spiegel von kleinen Repos herunterladen" @@ -594,6 +693,11 @@ msgstr "FEHLER: nicht unterstützter CI-Typ, Patches willkommen!" msgid "Empty build flag at {linedesc}" msgstr "Build-Flag bei {linedesc} leeren" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -609,14 +713,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Fehler beim Versuch, das Protokoll zu veröffentlichen: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Fehler bei der Ermittlung der Repro-Adresse" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Signaturen aus APKs extrahieren" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Lesen von {path} fehlgeschlagen: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -678,6 +787,11 @@ msgstr "BuildServerID von VM abgerufen: {buildserverid}" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "Signaturen für {apkfilename} -> {sigdir} abgerufen" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -689,6 +803,11 @@ msgstr "Fertiggestellt" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Flattr-Spendenmethoden gehören in die FlattrID-Flagge" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Flattr-Spendenmethoden gehören in die FlattrID-Flagge" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Verbotene HTML-Befehle" @@ -702,11 +821,20 @@ msgstr "Erstellung deaktivierter Apps erzwingen und ungeachtet von Scan-Probleme msgid "Force halting build after {0} sec timeout!" msgstr "Erzwingt das Anhalten des Builds nach {0} Sek. Zeitüberschreitung!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "Grafik \"{path}\" ohne Metadaten für App \"{name}\" gefunden!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "Ungültige Appids in Argumenten gefunden" @@ -716,6 +844,11 @@ msgstr "Ungültige Appids in Argumenten gefunden" msgid "Found invalid versionCodes for some apps" msgstr "Ungültige versionCodes für einige Apps gefunden" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Mehrere Signaturzertifikate in {path} gefunden" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -739,6 +872,11 @@ msgstr "Es wurden keine Signaturzertifikate für das Repository gefunden." msgid "Found non-file at %s" msgstr "Eine Nicht-Datei gefunden bei %s" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "Kopiere {apkfilename} nach {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -761,6 +899,11 @@ msgstr "Git fetch fehlgeschlagen" msgid "Git remote set-head failed" msgstr "Git remote set-head fehlgeschlagen" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git remote set-head fehlgeschlagen" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Git reset fehlgeschlagen" @@ -777,6 +920,25 @@ msgstr "Git submodule update fehlgeschlagen" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS muss bei Subversion-URLs verwendet werden!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Ignoriere Paket ohne Metadaten: " @@ -795,6 +957,18 @@ msgstr "Ignoriere die Datei {ext} bei '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "APKs einschliessen, die mit deaktivierten Algorithmen wie MD5 signiert sind" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Initialisiere Submodule" @@ -803,21 +977,31 @@ msgstr "Initialisiere Submodule" msgid "Install all signed applications available" msgstr "Alle verfügbaren, signierten Anwendungen installieren" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Erstellte Programmpakete auf Geräten installieren" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "%s installieren …" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "%s installieren …" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Installiere '{apkfilename}' auf {dev}.…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Installiere '{apkfilename}' auf {dev}.…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Mit dem HTTP-Server des Repository kommunizieren" @@ -882,6 +1066,21 @@ msgstr "Ungültiger Paketname {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Ungültige Umleitung auf Nicht-HTTTPS: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Alle Metadaten-Dateien betrachten und beenden" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -897,11 +1096,19 @@ msgstr "JAR-Signatur konnte nicht überprüft werden: {path}" msgid "JAR signature verified: {path}" msgstr "JAR-Signatur verifiziert: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Java JDK nicht gefunden! Installieren Sie es in einem Standardordner oder setzen Sie java_paths!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Java jarsigner nicht gefunden! Installieren Sie es in einem Standardordner oder setzen Sie java_paths!" @@ -919,6 +1126,11 @@ msgstr "Schlüsselspeicher für den Signierschlüssel:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "Der zuletzt verwendete Commit '{commit}' sieht aus wie ein Tag, aber der Update Check Modus ist '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Liberapay-Spendenmethoden gehören in das LiberapayID-Flag" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Liberapay-Spendenmethoden gehören in das LiberapayID-Flag" @@ -943,6 +1155,10 @@ msgstr "Fehlerhafte Repository Mirrors." msgid "Malformed serverwebroot line:" msgstr "Fehlerhafte serverwebroot Zeile:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Fehlendes Ausgabeverzeichnis" @@ -982,6 +1198,11 @@ msgid "No git submodules available" msgstr "Keine Git-Submodule verfügbar" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Es konnte kein Android- oder Kivy-Projekt gefunden werden. --subdir angeben?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Keine Informationen gefunden." @@ -1010,7 +1231,7 @@ msgstr "Keine signierte Apk für %s verfügbar" msgid "No signed output directory - nothing to do" msgstr "Kein signiertes Ausgabeverzeichnis - nichts zu tun" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "Keine Signaturzertifikate in {path} gefunden" @@ -1030,6 +1251,10 @@ msgstr "Kein Versionscode {versionCode} für App {appid}" msgid "No unsigned directory - nothing to do" msgstr "Kein unsigniertes Verzeichnis - nichts zu tun" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Keine zu erledigenden Aufgaben" @@ -1062,7 +1287,7 @@ msgstr "Der OBB-Packetname stimmt mit keinem unterstützten APK überein:" msgid "Old APK signature failed to verify: {path}" msgstr "Alte APK-Signatur konnte nicht überprüft werden: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Veralteter Name für fdroid deploy" @@ -1079,6 +1304,11 @@ msgstr "Nur Unterschiede zum Play Store ausgeben" msgid "Only process apps with auto-updates" msgstr "Nur Apps mit automatischen Aktualisierungen verarbeiten" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Flattr-Spendenmethoden gehören in die FlattrID-Flagge" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1088,6 +1318,16 @@ msgstr "Optionen" msgid "Output JSON report to file named after APK." msgstr "JSON-Bericht in eine nach der APK benannte Datei ausgeben." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Gesamt-Lizenz des Projekts." @@ -1101,6 +1341,11 @@ msgstr "Pfad für die APK-Paketquelle überschreiben (Standard: ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Überschreiben von leeren Versionsnamen in {apkfilename} aus Metadaten: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1194,11 +1439,11 @@ msgstr "Binäres Transparenz-Log nach {url} pushen" msgid "Pushing to {url}" msgstr "Pushen auf {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Schnellstart eines neuen Repositorys" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Alle Metadaten-Dateien betrachten und beenden" @@ -1257,7 +1502,7 @@ msgstr "Größe aller Symbole ändern, die die maximale Pixelgröße überschrei msgid "Restrict output to warnings and errors" msgstr "Ausgabe auf Warnungen und Fehler beschränken" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Alle Metadaten-Dateien neu schreiben" @@ -1296,7 +1541,11 @@ msgstr "Ausführen von wget in {path}" msgid "Scan only the latest version of each package" msgstr "Nur die neueste Version jedes Programmpakets durchsuchen" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Quellcode eines Programmpakets durchsuchen" @@ -1320,12 +1569,16 @@ msgstr[1] "Scanner fand {count} Probleme" msgid "Set clock to that time using:" msgstr "Einstellen der Uhr auf diese Zeit mit:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Setzen des Limits für geöffnete Dateien auf {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Ein App-Build für einen nightly Build-Repo einrichten" @@ -1345,11 +1598,11 @@ msgstr "Einen Emulator einrichten, die APK installieren und mit ihm eine Sicherh msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Einen Emulator einrichten, die APK installieren und mit ihm eine Sicherheitsprüfung (Drozer scan) durchführen" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Programmpakete in Paketquelle signieren und einstellen" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Erstellte Indizes durch Verwendung von „update --nosign“ signieren" @@ -1407,6 +1660,11 @@ msgstr "Mehr Informationen als gewöhnlich ausspucken" msgid "Striping mystery signature from {apkfilename}" msgstr "Entferne mysteriöse Signatur aus {apkfilename}" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Entferne mysteriöse Signatur aus {apkfilename}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1465,6 +1723,10 @@ msgstr "Das Wurzelverzeichnis für local_copy_dir \"{path}\" existiert nicht!" msgid "There is a keyalias collision - publishing halted" msgstr "Es gibt eine Keyalias-Kollision - Veröffentlichung gestoppt" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1478,6 +1740,10 @@ msgstr "Um awsbucket zu benutzen, müssen awssecretkey und awsaccesskeyid auch i msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCM ist gesetzt, aber es sieht so aus, als ob checkupdates noch nicht ausgeführt wurde" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "Kurz-URL-Dienste sollten nicht verwendet werden" @@ -1491,12 +1757,21 @@ msgstr "URL-Titel ist nur die URL, verwenden Sie Klammern: [URL]" msgid "URL {url} in Description: {error}" msgstr "URL {url} in der Beschreibung: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Ungültiges Lizenz-Tag \"%s\"! Verwenden Sie nur Tags von https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "Unerwarteter Text in der gleichen Zeile wie {field} in {linedesc}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Unbekannter Fehler aufgetreten!" @@ -1516,6 +1791,11 @@ msgstr "Unbekanntes Metadatenformat: %s" msgid "Unknown metadata format: {path}" msgstr "Unbekanntes Metadaten-Format: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Unbekanntes Metadaten-Format: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "Unbekannte Version von aapt, könnte Probleme verursachen: " @@ -1594,19 +1874,29 @@ msgstr "Nicht verwendete extlib bei %s" msgid "Unused file at %s" msgstr "Nicht verwendete Datei bei %s" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "Nicht verwendete Datei bei %s" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "Nicht verwendete Datei bei %s" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "Update Check Name ist auf die bekannte App-ID gesetzt - sie kann entfernt werden" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Paketquelleninformationen zu neuen Programmpaketen aktualisieren" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Binäres Transparency-Log einer URL aktualisieren" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Repository-Statistik aktualisieren" @@ -1629,6 +1919,16 @@ msgstr "UpdateCheckData muss HTTPS-URL verwenden: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData hat eine ungültige URL: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Lese {apkfilename} aus dem Cache" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1664,6 +1964,14 @@ msgstr "APK-Datum statt der aktuellen Zeit für neu hinzugefügte APKs verwenden msgid "Using \"{path}\" for configuring s3cmd." msgstr "Verwende {path} zur Konfiguration von s3cmd." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Von Java jarsigner zur Verifikation von APKs wird abgeraten! Verwenden Sie apksigner" @@ -1683,7 +1991,7 @@ msgstr "Verwende vorhandenen Schlüsselspeicher \"{path}\"" msgid "Using s3cmd to sync with: {url}" msgstr "Verwende s3cmd zum Synchronisieren mit: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Gültige Befehle sind:" @@ -1691,7 +1999,7 @@ msgstr "Gültige Befehle sind:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Vergleichen Sie mit lokal zwischengespeicherter Kopie, anstatt erneut herunterzuladen." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Integrität der heruntergeladenen Programmpakete überprüfen" @@ -1699,7 +2007,12 @@ msgstr "Integrität der heruntergeladenen Programmpakete überprüfen" msgid "Verifying index signature:" msgstr "Überprüfe die Index-Signatur:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Vor möglichen Metadaten-Fehlern warnen" @@ -1707,6 +2020,10 @@ msgstr "Vor möglichen Metadaten-Fehlern warnen" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Bei einer Konfiguration mit signierten Indizes, in dieser Phase nur unsignierte Indizes erstellen" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Angesehener Name' wenn Schlüssel generiert werden" @@ -1718,6 +2035,10 @@ msgstr "X.509 'Distinguished Name' zum Erzeugen von Schlüsseln" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "Sie können ANDROID_HOME verwenden, um den Pfad zu Ihrem SDK zu setzen, z.B.:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1740,6 +2061,10 @@ msgstr "Mehrdeutige Option: %(option)s könnte übereinstimmen mit %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "Mehrdeutige Option: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "App-ID in der Form APPID" @@ -1761,16 +2086,30 @@ msgstr "App-ID mit optionalem Versionscode in der Form APPID[:VERCODE]" msgid "argument \"-\" with mode %r" msgstr "Argument \"-\" mit Modus %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "Versuch einer reinen ssh-Verbindung, um den Deployment-Key zu testen:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "Versuch einer reinen ssh-Verbindung, um den Deployment-Key zu testen:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "„%s” konnte nicht geöffnet werden: %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "AppID für {path} konnte nicht gefunden werden!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1795,6 +2134,10 @@ msgstr "Klone {url}" msgid "command to execute, either 'init' or 'update'" msgstr "Ausführungsbefehl, entweder 'init' oder 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1813,6 +2156,19 @@ msgstr[1] "widersprüchliche Optionsangaben: %s" msgid "copying {apkfilename} into {path}" msgstr "Kopiere {apkfilename} nach {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1828,12 +2184,21 @@ msgstr "Lösche: repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "Build Logs deployed zu {path}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest= wird benötigt für Optionen wie %r" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1866,7 +2231,7 @@ msgstr "Build Logs zu '{path}' deployen fehlgeschlagen" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1887,6 +2252,10 @@ msgstr "Erzwingen, dass Metadatenfehler (Standard) als Warnung ausgegeben oder i msgid "git svn clone failed" msgstr "git svn Klonen fehlgeschlagen" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1964,7 +2333,7 @@ msgstr "Kein APK bereitgestellt" msgid "no such option: %s" msgstr "keine solche Option: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "Keine Versionsinformationen gefunden!" @@ -2052,6 +2421,11 @@ msgstr "überschreiben des vorhandenen {path}" msgid "positional arguments" msgstr "Positionsparameter" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2062,11 +2436,19 @@ msgstr "Download über ungesicherte HTTP-Verbindung verweigert (verwenden Sie HT msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "Download über ungesicherte HTTP-Verbindung verweigert (verwenden Sie HTTPS oder geben Sie --no-https-check an): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd-Sync {path} indizieren auf {url} und dann löschen" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2099,6 +2481,10 @@ msgstr "Überspringe Quell-Tarball: {path}" msgid "srclibs missing name and/or @" msgstr "Srclibs-Name fehlt und/oder @" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2134,7 +2520,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "Unsichere Berechtigungen in „{config_file}” (sollte 0600 sein)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "Syntax: " @@ -2147,6 +2533,10 @@ msgstr "Syntax: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "Verwende Apache libcloud zur Synchronisation mit {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2210,16 +2600,31 @@ msgstr "{appid}: {field} muss ein '{type}' sein, ist aber ein '{fieldtype}!'" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}: {field} muss ein '{type}' sein, ist aber ein '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} nicht in {name} beendet" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" existiert nicht! Korrigieren Sie es in der config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2235,11 +2640,21 @@ msgstr "{path} hat die schlechte Dateisignatur \"{pattern}\", möglicher Janus-E msgid "{path} is zero size!" msgstr "{path} hat Dateigröße Null!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} endet nicht mit \"fdroid\", überprüfen Sie den URL-Pfad!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} endet nicht mit \"fdroid\", überprüfen Sie den URL-Pfad!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2252,6 +2667,16 @@ msgid_plural "{} builds succeeded" msgstr[0] "Buildvorgang erfolgreich" msgstr[1] "Buildvorgänge erfolgreich" +#, fuzzy +#~ msgid "Add PGP signatures for packages in repo using GnuPG" +#~ msgstr "GPG-Signaturen für Programmpakete in der Paketquelle hinzufügen" + +#~ msgid "Add gpg signatures for packages in repo" +#~ msgstr "GPG-Signaturen für Programmpakete in der Paketquelle hinzufügen" + +#~ msgid "Clean update - don't uses caches, reprocess all apks" +#~ msgstr "Sauber - ohne Verwendung der Zwischenspeicher - aktualisieren, alle APKs wiederaufbereiten" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "Angelegenheiten, die Aktualisierungen erfordern, interaktiv abfragen." @@ -2264,16 +2689,6 @@ msgstr[1] "Buildvorgänge erfolgreich" #~ msgid "Specify editor to use in interactive mode. Default is {path}" #~ msgstr "Editor festlegen, der im interaktiven Modus verwendet werden soll. Standard ist {path}" -#, fuzzy -#~ msgid "Add PGP signatures for packages in repo using GnuPG" -#~ msgstr "GPG-Signaturen für Programmpakete in der Paketquelle hinzufügen" - -#~ msgid "Add gpg signatures for packages in repo" -#~ msgstr "GPG-Signaturen für Programmpakete in der Paketquelle hinzufügen" - -#~ msgid "Clean update - don't uses caches, reprocess all apks" -#~ msgstr "Sauber - ohne Verwendung der Zwischenspeicher - aktualisieren, alle APKs wiederaufbereiten" - #~ msgid "app-id in the form APPID" #~ msgstr "App-ID in der Form APPID" diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index 91eb47d3..96dd69ed 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-06-28 04:34+0000\n" "Last-Translator: Maximiliano Castañón \n" "Language-Team: Spanish \n" @@ -17,6 +17,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.2-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -25,6 +35,15 @@ msgstr "" "\n" "Clave pública SSH que se usará como clave de despliegue:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Clave pública SSH que se usará como clave de despliegue:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -39,6 +58,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "¡\"%s/\" no tiene su correspondiente fichero de metadatos!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' ya está instalado en {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -54,11 +78,21 @@ msgstr "\"{path}\" contiene {name} ({version}) reciente" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe pero ¡s3cmd no está instalado!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" no es un formato reconocido, convertir a: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" no es un formato reconocido, convertir a: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -109,6 +143,10 @@ msgstr "la opción %s no toma un valor" msgid "'keypass' not found in config.py!" msgstr "¡'keypass' no encontrado en config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "¡'keystore' no encontrado en config.py!" @@ -190,11 +228,11 @@ msgstr "no se encuentra /issues" msgid "A URL is required as an argument!" msgstr "¡Se requiere una URL como argumento!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Añadir las firmas PGP para los paquetes en el repositorio usando GnuPG" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Añadir una nueva aplicación desde su código fuente" @@ -227,6 +265,19 @@ msgstr "También replicar la sección completa del archivo" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "También advierta sobre problemas de formato, como r rewritemeta-l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "¡No se encontró Android SDK!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -287,7 +338,12 @@ msgstr "Rama '{branch}' usada como \"commit\" en el build '{versionName}'" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Rama '{branch}' usada como \"commit\" en srclib '{srclib}'" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Crear un paquete desde la fuente" @@ -343,6 +399,11 @@ msgstr "¡No se puede leer \"{path}\"!" msgid "Cannot resolve app id {appid}" msgstr "No se puede resolver el identificador de aplicación {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "¡No se puede leer \"{path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "No se puede usar --list y --to al mismo tiempo" @@ -361,7 +422,7 @@ msgstr "La categoría '%s' no es válida" msgid "Categories are not set" msgstr "No se han establecido categorías" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Buscar actualizaciones de aplicaciones" @@ -390,7 +451,7 @@ msgstr "Actualización limpia, no usa la caché, procesa todas las APKs" msgid "Comma separated list of categories." msgstr "Lista de categorías separadas por comas." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Comando %s no reconocido\n" @@ -399,11 +460,25 @@ msgstr "Comando %s no reconocido\n" msgid "Commit changes" msgstr "Aplicar cambios" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "No se pudo encontrar '{command}' en el sistema" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "No se ha podido encontrar el último código de versión" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "No se ha podido encontrar el último nombre de versión" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -413,6 +488,16 @@ msgstr "No se pudo encontrar {path} para eliminarlo" msgid "Could not open apk file for analysis" msgstr "No se ha podido abrir el archivo apk para analizarlo" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "No se ha podido encontrar el identificador de paquete" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -488,6 +573,16 @@ msgstr "DEBUG_KEYSTORE no está establecida o su valor es incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Borrar del repositorio archivos APK y/o OBB sin metadatos" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -512,6 +607,10 @@ msgstr "La descripción tiene una lista (%s) pero no está estructurada (*) ni n msgid "Description of length {length} is over the {limit} char limit" msgstr "La descripción de longitud {length} supera el límite de caracteres, {limit}" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -546,7 +645,7 @@ msgstr "No actualizar el repositorio, útil al probar una compilación sin conex msgid "Don't use rsync checksums" msgstr "No use rsync checksums" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Descargar réplicas completas de repositorios pequeños" @@ -594,6 +693,11 @@ msgstr "ERROR: tipo de CI no soportado, ¡se aceptan parches!" msgid "Empty build flag at {linedesc}" msgstr "Bandera de compilación vacía en {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -609,14 +713,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Error mientras se intentaba publicar el registro: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Error al obtener la dirección del repositorio" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Extraer firmas de APKs" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Fallo al leer {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -678,6 +787,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -689,6 +803,11 @@ msgstr "Terminado" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Los métodos de donación de Liberapay pertenecen a la bandera de LiberapayID" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Etiquetas HTML prohibidas" @@ -702,11 +821,20 @@ msgstr "Forzar la creación de compilaciones deshabilitadas, independientemente msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -716,6 +844,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Encontrados varios certificados de firma en {path}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -739,6 +872,11 @@ msgstr "Ningún certificado de firma encontrado para el repositorio." msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "Procesando {apkfilename}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -761,6 +899,11 @@ msgstr "Git fetch falló" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git reset falló" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Git reset falló" @@ -777,6 +920,25 @@ msgstr "La actualización del submodulo de Git falló" msgid "HTTPS must be used with Subversion URLs!" msgstr "¡Se debe usar HTTPS con URLs de Subversion!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Ignorando paquete sin metadatos: " @@ -795,6 +957,18 @@ msgstr "Ignorando archivo {ext} en '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Incluir APKs que están firmados con algoritmos deshabilitados como MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Inicializando submodules" @@ -803,21 +977,31 @@ msgstr "Inicializando submodules" msgid "Install all signed applications available" msgstr "Instalar todas las aplicaciones firmadas disponibles" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Instalar paquetes constuídos en el dispositivo" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Instalando %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Instalando %s…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Instalando '{apkfilename}' en {dev}…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Instalando '{apkfilename}' en {dev}…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interactuar con el servidor HTTP del repositorio" @@ -882,6 +1066,21 @@ msgstr "Nombre de paquete no válido {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Redirección no válida a no HTTPS: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Leer todos los archivos de metadatos y salir" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -897,11 +1096,19 @@ msgstr "No se pudo comprobar la firma JAR: {path}" msgid "JAR signature verified: {path}" msgstr "Firma JAR verificada: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "¡No se encontró Java JDK! ¡Instale en una ubicación estándar o establezca java_paths!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Java jarsigner no encontrado! Instalar en una ubicación estándar o establecer java_paths!" @@ -919,6 +1126,11 @@ msgstr "Depósito de claves para la clave de firma de repositorio:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "La última confirmación utilizada '{commit}' parece una etiqueta, pero Update Check Mode es '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Los métodos de donación de Liberapay pertenecen a la bandera de LiberapayID" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Los métodos de donación de Liberapay pertenecen a la bandera de LiberapayID" @@ -943,6 +1155,10 @@ msgstr "Réplicas de repositorio mal formadas." msgid "Malformed serverwebroot line:" msgstr "Línea serverwebroot mal formada:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Falta el directorio de salida" @@ -982,6 +1198,11 @@ msgid "No git submodules available" msgstr "No hay git submodules disponibles" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "No se ha encontrado proyecto android o kivy. ¿Especifique --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "No se encontró información." @@ -1010,7 +1231,7 @@ msgstr "No hay apk firmado disponible para %s" msgid "No signed output directory - nothing to do" msgstr "Sin directorio de salida firmado - nada que hacer" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "No se ha encontrado ningún certificado de firma en {path}" @@ -1030,6 +1251,10 @@ msgstr "No existe tal versiónCode {versionCode} para app {appid}" msgid "No unsigned directory - nothing to do" msgstr "No hay directorio sin firma - nada que hacer" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Nada que hacer" @@ -1062,7 +1287,7 @@ msgstr "El nombre de paquete de OBB no coincide con un APK soportado:" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Nombre antiguo y obsoleto de fdroid deploy" @@ -1079,6 +1304,11 @@ msgstr "Solo imprimir diferencias con el Play Store" msgid "Only process apps with auto-updates" msgstr "Solo procesar aplicaciones con actualizaciones automáticas" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Los métodos de donación de Liberapay pertenecen a la bandera de LiberapayID" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1088,6 +1318,16 @@ msgstr "Opciones" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Licencia general del proyecto." @@ -1101,6 +1341,11 @@ msgstr "Ruta de remplazo par el repositorio de APK (default: ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Sobrescribir versionName vacío en {apkfilename} con el de los metadatos: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1194,11 +1439,11 @@ msgstr "Publicar el registro de transparencia binario en {url}" msgid "Pushing to {url}" msgstr "Empujando a {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Iniciar rápidamente un nuevo repositorio" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Leer todos los archivos de metadatos y salir" @@ -1257,7 +1502,7 @@ msgstr "Cambiar el tamaño de todos los iconos que exceden el tamaño máximo de msgid "Restrict output to warnings and errors" msgstr "Restringir los resultados a advertencias y errores" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Reescribir todos los archivos de metadatos" @@ -1296,7 +1541,11 @@ msgstr "Ejecutando wget en {path}" msgid "Scan only the latest version of each package" msgstr "Escanear solo la última versión de cada paquete" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Escanear el código fuente de un paquete" @@ -1320,12 +1569,16 @@ msgstr[1] "El escáner encontró {} problemas" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1345,11 +1598,11 @@ msgstr "Establecer un emulador, instalar la APK en el y realizar un escaneo con msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Configurar un emulador, instalar la aplicación APK en él y realizar una \"Drozer\" scan" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Firmar y colocar paquetes en el repositorio" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Firmar los índices creados usando update --nosign" @@ -1407,6 +1660,11 @@ msgstr "Diseminar más información de lo normal" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Fallo al obtener firmas para '{apkfilename}': {error}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1465,6 +1723,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1478,6 +1740,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "Acortadores de URL no deben ser utilizados" @@ -1491,12 +1757,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "¡Se encontró una excepción desconocida!" @@ -1516,6 +1790,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "Formato de metadatos desconocido: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Formato de metadatos desconocido: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1594,19 +1873,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Actualizar la información del repositorio para nuevos paquetes" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Actualizar el registro de transparencia binario para una URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Actualizar las estadísticas del repositorio" @@ -1629,6 +1918,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1664,6 +1963,14 @@ msgstr "Use la fecha del «apk» en vez de la fecha actual para los nuevos «apk msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1683,7 +1990,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Los comandos válidos son:" @@ -1691,7 +1998,7 @@ msgstr "Los comandos válidos son:" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Verificar la integridad de los paquetes descargados" @@ -1699,7 +2006,12 @@ msgstr "Verificar la integridad de los paquetes descargados" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Alertar sobre posibles errores de metadatos" @@ -1707,6 +2019,10 @@ msgstr "Alertar sobre posibles errores de metadatos" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Cuando está configurado para índices firmados, crear solo índices sin signo en esta etapa" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Nombre Distintivo' (DN) usado al generar claves" @@ -1718,6 +2034,10 @@ msgstr "X.509 'Nombre Distintivo' (DN) usado al generar claves" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1740,6 +2060,10 @@ msgstr "opción ambigua: %(option)s podría corresponderse con %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "opción ambigua: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId en el formato APPID" @@ -1761,16 +2085,29 @@ msgstr "applicationId con código de versión opcional en la forma APPID [: VERC msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "no se puede abrir '%s': %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "¡No se puede encontrar un appid para {path}!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1795,6 +2132,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "Comando para ejecutar, ya sea 'init' o 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1813,6 +2154,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1828,12 +2182,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1866,7 +2229,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1887,6 +2250,10 @@ msgstr "forzar que los errores en metadatos sean avisos, o que se ignoren (valor msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1964,7 +2331,7 @@ msgstr "" msgid "no such option: %s" msgstr "no hay tal opción: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "¡no se encontró información de la versión!" @@ -2052,6 +2419,11 @@ msgstr "" msgid "positional arguments" msgstr "argumentos posicionales" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2062,11 +2434,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2099,6 +2479,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2134,7 +2518,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "permisos inseguros en '{config_file}' (¡debería ser 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "uso: " @@ -2147,6 +2531,10 @@ msgstr "Uso: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "usando Apache libcloud para sincronizar con {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2210,16 +2598,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2235,11 +2638,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2252,6 +2665,16 @@ msgid_plural "{} builds succeeded" msgstr[0] "" msgstr[1] "" +#, fuzzy +#~ msgid "Add PGP signatures for packages in repo using GnuPG" +#~ msgstr "Añadir las firmas gpg para los paquetes en el repositorio" + +#~ msgid "Add gpg signatures for packages in repo" +#~ msgstr "Añadir las firmas gpg para los paquetes en el repositorio" + +#~ msgid "Clean update - don't uses caches, reprocess all apks" +#~ msgstr "Actualización limpia, no usa caché, reprocesa todas las aplicaciones APK" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "Pregunte de forma interactiva sobre temas que necesitan una actualización." @@ -2264,16 +2687,6 @@ msgstr[1] "" #~ msgid "Specify editor to use in interactive mode. Default is {path}" #~ msgstr "Especifique el editor para utilizar en modo interactivo. Por defecto es {path}" -#, fuzzy -#~ msgid "Add PGP signatures for packages in repo using GnuPG" -#~ msgstr "Añadir las firmas gpg para los paquetes en el repositorio" - -#~ msgid "Add gpg signatures for packages in repo" -#~ msgstr "Añadir las firmas gpg para los paquetes en el repositorio" - -#~ msgid "Clean update - don't uses caches, reprocess all apks" -#~ msgstr "Actualización limpia, no usa caché, reprocesa todas las aplicaciones APK" - #~ msgid "app-id in the form APPID" #~ msgstr "APP-ID en el formato APPID" diff --git a/locale/es_AR/LC_MESSAGES/fdroidserver.po b/locale/es_AR/LC_MESSAGES/fdroidserver.po index b9a248e3..223c571d 100644 --- a/locale/es_AR/LC_MESSAGES/fdroidserver.po +++ b/locale/es_AR/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-01 10:31+0000\n" "Last-Translator: riveravaldez \n" "Language-Team: Spanish (Argentina) \n" @@ -18,12 +18,28 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -36,6 +52,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -51,11 +72,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -106,6 +137,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -187,12 +222,12 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, fuzzy msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Agregar firmas GPG a paquetes en el repositorio" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Agregar una aplicación nueva desde su código fuente" @@ -227,6 +262,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "También advertir sobre problemas de formateo, como ser rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -287,7 +334,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Compilar una paquete desde su código" @@ -343,6 +395,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -361,7 +418,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Buscar actualizaciones de las aplicaciones" @@ -391,7 +448,7 @@ msgstr "Limpiar actualización - no utiliza cachés, reprocesa todos los APK's" msgid "Comma separated list of categories." msgstr "Lista de categorías separadas por coma." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "No se reconoce el comando \"%s\".\n" @@ -400,11 +457,25 @@ msgstr "No se reconoce el comando \"%s\".\n" msgid "Commit changes" msgstr "Cometer cambios" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Empaquetado con la ultima versión de cada paquete" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Empaquetado con la ultima versión de cada paquete" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -414,6 +485,16 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Construir todas las aplicaciones disponibles" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -490,6 +571,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Borrar archivos APK y/o OBBs sin metadatos del repositorio" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -514,6 +605,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -549,7 +644,7 @@ msgstr "No refrescar el repositorio, útil cuando se esta probando la construcci msgid "Don't use rsync checksums" msgstr "No usar sumas de validación de rsync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -595,6 +690,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -608,14 +708,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -679,6 +784,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -690,6 +800,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -703,11 +817,20 @@ msgstr "Forzar la construcción de aplicaciones deshabilitadas y continuar indep msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -717,6 +840,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -740,6 +868,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -762,6 +895,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -778,6 +916,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -796,6 +953,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -804,21 +973,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "Instalar todas las aplicaciones firmadas disponibles" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Instalar paquetes compilados en dispositivos" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interactuar con el servidor HTTP del repositorio" @@ -883,6 +1062,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Leer todos los archivos de metadatos y salir" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -898,11 +1092,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -921,6 +1123,10 @@ msgstr "Ruta al almacén de claves para la llave de firmado del repositorio" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -945,6 +1151,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -984,6 +1194,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1012,7 +1226,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1032,6 +1246,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1064,7 +1282,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1081,6 +1299,10 @@ msgstr "Solo mostrar las diferencias con el Plays Store" msgid "Only process apps with auto-updates" msgstr "Solo procesar las aplicaciones que cuenten con actualizaciones automaticas" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1090,6 +1312,16 @@ msgstr "Opciones" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Licencia general del proyecto." @@ -1103,6 +1335,11 @@ msgstr "Sobrescribir la ruta de los repositorios APKs (por defecto ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1198,11 +1435,11 @@ msgstr "Actualizar el registro de transparencia binario de {url}" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Empezar rápidamente un repositorio nuevo" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Leer todos los archivos de metadatos y salir" @@ -1263,7 +1500,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "Restringir la salida solo para advertencias y errores" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Rescribir todos los archivos de metadatos" @@ -1302,7 +1539,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "Escanear solo la ultima versión de cada paquete" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Escanear en código fuente de un paquete" @@ -1326,12 +1567,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1352,11 +1597,11 @@ msgstr "Configurar un emulador, instalarle el apk y realizar el escaneo de barri msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Configurar un emulador, instalarle el apk y realizar el escaneo de barrido" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Firmar y ubicar paquetes en el repositorio" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Firmar índicescreados con \"update --nosign\"" @@ -1415,6 +1660,11 @@ msgstr "Mostrar más información que de costumbre" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1474,6 +1724,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1487,6 +1741,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1500,12 +1758,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "¡Se encontró una excepción desconocida!" @@ -1525,6 +1791,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1603,19 +1874,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Actualizar información del repositorio para paquetes nuevos" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Actualizar el registro de transparencia binario de un URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Actualizar las estadísticas del repositorio" @@ -1638,6 +1919,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1674,6 +1965,14 @@ msgstr "Utilizar la fecha del apk en vez de la actual para los apks nuevos que s msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1693,7 +1992,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Los comandos válidos son:" @@ -1701,7 +2000,7 @@ msgstr "Los comandos válidos son:" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Verificar la integridad de los paquetes descargados" @@ -1709,7 +2008,12 @@ msgstr "Verificar la integridad de los paquetes descargados" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Advertir sobre posibles errores en los metadatos" @@ -1717,6 +2021,10 @@ msgstr "Advertir sobre posibles errores en los metadatos" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Si está configurado para índices firmados, crear sólo índices sin firma en este punto" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Nombre Distinguido' usado cuando se generaron las llaves" @@ -1729,6 +2037,10 @@ msgstr "X.509 'Nombre Distinguido' usado cuando se generaron las llaves" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1751,6 +2063,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #, fuzzy msgid "applicationId in the form APPID" @@ -1775,16 +2091,29 @@ msgstr "app-id con VersionCode opcional con el formato APPID[:VERCODE]" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1809,6 +2138,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "comando a ejecutar, ya sea 'iniciar' o 'actualizar'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1827,6 +2160,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1842,12 +2188,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1881,7 +2236,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "uso: fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, fuzzy msgid "fdroid [] [-h|--help|--version|]" msgstr "uso: fdroid [-h|--help|--version] []" @@ -1903,6 +2258,10 @@ msgstr "forzar errores al ser advertencias, o ignorar." msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1981,7 +2340,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, fuzzy msgid "no version info found!" msgstr "¡Se encontró una excepción desconocida!" @@ -2070,6 +2429,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2080,11 +2444,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2117,6 +2489,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2152,7 +2528,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2165,6 +2541,10 @@ msgstr "uso: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "usando libcloud de Apache para sincronizar con {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2228,16 +2608,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2253,11 +2648,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2270,6 +2675,16 @@ msgid_plural "{} builds succeeded" msgstr[0] "" msgstr[1] "" +#, fuzzy +#~ msgid "Add PGP signatures for packages in repo using GnuPG" +#~ msgstr "Agregar firmas GPG a paquetes en el repositorio" + +#~ msgid "Add gpg signatures for packages in repo" +#~ msgstr "Agregar firmas GPG a paquetes en el repositorio" + +#~ msgid "Clean update - don't uses caches, reprocess all apks" +#~ msgstr "Limpiar actualización - no utiliza cachés, reprocesa todos los APK's" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "Preguntar de forma interactiva sobre las cosas necesarias a actualizar." @@ -2284,16 +2699,6 @@ msgstr[1] "" #~ msgid "Specify editor to use in interactive mode. Default is {path}" #~ msgstr "Especificar el editor a usar en modo interactivo. Por defecto %s" -#, fuzzy -#~ msgid "Add PGP signatures for packages in repo using GnuPG" -#~ msgstr "Agregar firmas GPG a paquetes en el repositorio" - -#~ msgid "Add gpg signatures for packages in repo" -#~ msgstr "Agregar firmas GPG a paquetes en el repositorio" - -#~ msgid "Clean update - don't uses caches, reprocess all apks" -#~ msgstr "Limpiar actualización - no utiliza cachés, reprocesa todos los APK's" - #~ msgid "app-id in the form APPID" #~ msgstr "app-id en el formato APPID" diff --git a/locale/es_MX/LC_MESSAGES/fdroidserver.po b/locale/es_MX/LC_MESSAGES/fdroidserver.po index 7981a7db..c25e861c 100644 --- a/locale/es_MX/LC_MESSAGES/fdroidserver.po +++ b/locale/es_MX/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-04-29 12:49+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Spanish (Mexico) \n" @@ -17,12 +17,28 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.0.2\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -35,6 +51,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -50,11 +71,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -105,6 +136,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -186,11 +221,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -223,6 +258,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -283,7 +330,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "" @@ -339,6 +391,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -357,7 +414,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -386,7 +443,7 @@ msgstr "Actualización limpia: no usar cachés, reprocese todos los APK" msgid "Comma separated list of categories." msgstr "Lista de categorías separadas por comas." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -395,11 +452,25 @@ msgstr "" msgid "Commit changes" msgstr "Hacer Cambios" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "No se pudo encontrar '{command}' en su sistema" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "No se pudo encontrar el código de la última versión" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "No se pudo encontrar el nombre de la última versión" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -409,6 +480,16 @@ msgstr "No se pudo encontrar {path} para eliminarlo" msgid "Could not open apk file for analysis" msgstr "No se pudo abrir el archivo apk para su análisis" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "No se pudo encontrar la ID del paquete" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -484,6 +565,16 @@ msgstr "DEBUG_KEYSTORE no está establecido o el valor está incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -508,6 +599,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -542,7 +637,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -588,6 +683,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -601,14 +701,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -670,6 +775,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -681,6 +791,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -694,11 +808,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -708,6 +831,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -731,6 +859,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -753,6 +886,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -769,6 +907,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -787,6 +944,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -795,21 +964,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -874,6 +1053,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -889,11 +1083,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -911,6 +1113,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -935,6 +1141,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -974,6 +1184,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1002,7 +1216,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1022,6 +1236,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1054,7 +1272,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1071,6 +1289,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1080,6 +1302,16 @@ msgstr "" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1093,6 +1325,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1186,11 +1423,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1249,7 +1486,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1288,7 +1525,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1312,12 +1553,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1337,11 +1582,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1399,6 +1644,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1457,6 +1707,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1470,6 +1724,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1483,12 +1741,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1508,6 +1774,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1586,19 +1857,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1621,6 +1902,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1656,6 +1947,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1675,7 +1974,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1683,7 +1982,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1691,7 +1990,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1699,6 +2003,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1710,6 +2018,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1732,6 +2044,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1753,16 +2069,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1787,6 +2116,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1805,6 +2138,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1820,12 +2166,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1858,7 +2213,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1879,6 +2234,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1956,7 +2315,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2044,6 +2403,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2054,11 +2418,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2091,6 +2463,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2126,7 +2502,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2139,6 +2515,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2202,16 +2582,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2227,11 +2622,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/fa/LC_MESSAGES/fdroidserver.po b/locale/fa/LC_MESSAGES/fdroidserver.po index 3c2c4a6d..974e4056 100644 --- a/locale/fa/LC_MESSAGES/fdroidserver.po +++ b/locale/fa/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2018-12-10 16:46+0000\n" "Last-Translator: frowzy \n" "Language-Team: Persian \n" @@ -18,12 +18,28 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 3.4-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -36,6 +52,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -51,11 +72,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -106,6 +137,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -187,11 +222,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -224,6 +259,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -284,7 +331,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "" @@ -340,6 +392,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -358,7 +415,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -387,7 +444,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -396,11 +453,23 @@ msgstr "" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -410,6 +479,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -485,6 +563,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -509,6 +597,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -543,7 +635,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -589,6 +681,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -602,14 +699,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -671,6 +773,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -682,6 +789,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -695,11 +806,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -709,6 +829,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -732,6 +857,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -754,6 +884,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -770,6 +905,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -788,6 +942,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -796,21 +962,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -875,6 +1051,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -890,11 +1081,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -912,6 +1111,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -936,6 +1139,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -975,6 +1182,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1003,7 +1214,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1023,6 +1234,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1055,7 +1270,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1072,6 +1287,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1081,6 +1300,16 @@ msgstr "انتخاب‌ها" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1094,6 +1323,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1187,11 +1421,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1250,7 +1484,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1289,7 +1523,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1313,12 +1551,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1338,11 +1580,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1400,6 +1642,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1458,6 +1705,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1471,6 +1722,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1484,12 +1739,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1509,6 +1772,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1587,19 +1855,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1622,6 +1900,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1657,6 +1945,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1676,7 +1972,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1684,7 +1980,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1692,7 +1988,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1700,6 +2001,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1711,6 +2016,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1733,6 +2042,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1754,16 +2067,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1788,6 +2114,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1806,6 +2136,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1821,12 +2164,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1859,7 +2211,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1880,6 +2232,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1957,7 +2313,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2045,6 +2401,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2055,11 +2416,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2092,6 +2461,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2127,7 +2500,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2140,6 +2513,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2203,16 +2580,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2228,11 +2620,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/fdroidserver.pot b/locale/fdroidserver.pot index ea158736..7c621b18 100644 --- a/locale/fdroidserver.pot +++ b/locale/fdroidserver.pot @@ -5,9 +5,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" +"Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,12 +17,28 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -35,6 +51,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -50,11 +71,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -105,6 +136,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -186,11 +221,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -223,6 +258,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -283,7 +330,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "" @@ -339,6 +391,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -357,7 +414,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -386,7 +443,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -395,11 +452,23 @@ msgstr "" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -409,6 +478,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -484,6 +562,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -508,6 +596,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -542,7 +634,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -588,6 +680,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -601,14 +698,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -670,6 +772,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -681,6 +788,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -694,11 +805,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -708,6 +828,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -731,6 +856,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -753,6 +883,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -769,6 +904,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -787,6 +941,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -795,21 +961,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -874,6 +1050,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -889,11 +1080,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -911,6 +1110,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -935,6 +1138,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -974,6 +1181,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1002,7 +1213,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1022,6 +1233,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1054,7 +1269,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1071,6 +1286,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1080,6 +1299,16 @@ msgstr "" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1093,6 +1322,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1186,11 +1420,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1249,7 +1483,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1288,7 +1522,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1312,12 +1550,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1337,11 +1579,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1399,6 +1641,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1457,6 +1704,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1470,6 +1721,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1483,12 +1738,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1508,6 +1771,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1586,19 +1854,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1621,6 +1899,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1656,6 +1944,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1675,7 +1971,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1683,7 +1979,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1691,7 +1987,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1699,6 +2000,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1710,6 +2015,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1732,6 +2041,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1753,16 +2066,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1787,6 +2113,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1805,6 +2135,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1820,12 +2163,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1858,7 +2210,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1879,6 +2231,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1956,7 +2312,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2044,6 +2400,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2054,11 +2415,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2091,6 +2460,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2126,7 +2499,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2139,6 +2512,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2202,16 +2579,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2227,11 +2619,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index f520a9be..8436749a 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-01 09:00+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: French \n" @@ -27,6 +27,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -35,6 +45,15 @@ msgstr "" "\n" "Clé Publique SSH à utiliser comme Clé de Déploiement :" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Clé Publique SSH à utiliser comme Clé de Déploiement :" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -49,6 +68,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" n'a pas de fichier de métadonnées correspondant !" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' est déjà installé sur '{dev}'." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -64,11 +88,21 @@ msgstr "\"{path}\" contient le récent {name} ({version})" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe mais s3cmd n'est pas installé !" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" n'est pas un format autorisé, convertir en : {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" n'est pas un format autorisé, convertir en : {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -119,6 +153,10 @@ msgstr "l'option %s ne prend pas de valeur" msgid "'keypass' not found in config.py!" msgstr "'keypass' non trouvé dans config.py !" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore' non trouvé dans config.py !" @@ -200,11 +238,11 @@ msgstr "/issues est manquant" msgid "A URL is required as an argument!" msgstr "Une URL est requise en argument !" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Ajouter des signatures PGP avec GnuPG pour les paquets dans le dépôt" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Ajouter une nouvelle application depuis son code source" @@ -237,6 +275,19 @@ msgstr "Faire aussi un miroir de la section d'archive complète" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Alerter aussi à propos des problèmes de formatage, comme rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Aucun SDK Android trouvée !" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -297,7 +348,12 @@ msgstr "Branche « {branch} » utilisée comme commit dans le build « {versionN msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Branche « {branch} » utilisée comme commit dans srclib « {srclib} »" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Construire un paquet depuis les sources" @@ -353,6 +409,11 @@ msgstr "Impossible de lire \"{path}\" !" msgid "Cannot resolve app id {appid}" msgstr "Impossible de résoudre l'identifiant de l'application {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Impossible de lire \"{path}\" !" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "Impossible d'utiliser --list et --to en même temps" @@ -371,7 +432,7 @@ msgstr "Catégorie « %s » invalide" msgid "Categories are not set" msgstr "Catégories non définies" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Vérifier les mises à jour pour les applications" @@ -400,7 +461,7 @@ msgstr "Mise à jour propre - n'utilise pas les caches, traite à nouveau tous l msgid "Comma separated list of categories." msgstr "Liste de catégories séparées par des virgules." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "La commande '%s' n'est pas reconnue.\n" @@ -409,11 +470,25 @@ msgstr "La commande '%s' n'est pas reconnue.\n" msgid "Commit changes" msgstr "Sauvegarder les changements (commit)" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "Impossible de trouver « {command} » sur votre système" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Impossible de trouver la dernière version du code" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Impossible de trouver le nom de la dernière version" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -423,6 +498,16 @@ msgstr "Chemin {path} non trouvé pour suppression" msgid "Could not open apk file for analysis" msgstr "Impossible d'ouvrir le fichier apk pour analyse" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Impossible de trouver l'ID du paquet" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -498,6 +583,16 @@ msgstr "DEBUG_KEYSTORE n'est pas définie ou sa valeur est incomplète" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Supprimer les APK et/ou OBB sans métadonnées dans le dépôt" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -522,6 +617,10 @@ msgstr "La description contient une liste (%s) mais ce n'est ni une liste à puc msgid "Description of length {length} is over the {limit} char limit" msgstr "La longueur de la description {length} dépasser la limite du nombre de caractères autorisés {limit}" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Ne pas déployer les nouveaux fichiers dans le dépôt" @@ -556,7 +655,7 @@ msgstr "Ne pas rafraîchir le dépôt, utile pour tester un build sans connexion msgid "Don't use rsync checksums" msgstr "Ne pas utiliser les sommes de contrôle rsync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Télécharger une image complète des petits dépôts" @@ -604,6 +703,11 @@ msgstr "ERREUR : type de CI non supporté, les corrections sont bienvenues !" msgid "Empty build flag at {linedesc}" msgstr "Drapeau de construction vide à {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -619,14 +723,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Erreur lors de la publication du journal : %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Erreur lors de l'obtention de l'adresse du dépôt" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Extraction des signatures à partir des APKs" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Erreur de lecture {path} : {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -688,6 +797,11 @@ msgstr "Récupération de l'ID du serveur de construction depuis la VM : {buil msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "Récupération de la signature pour '{apkfilename}' -> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -699,6 +813,11 @@ msgstr "Terminé" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "La méthode de donnation Flattr reviens au flag FlatttrID" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "La méthode de donnation Flattr reviens au flag FlatttrID" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Balises HTML interdites" @@ -712,11 +831,20 @@ msgstr "Forcer la construction des application désactiver, et opérateur indép msgid "Force halting build after {0} sec timeout!" msgstr "Arrêt forcer de la construction après {0} secondes de délai d'attente !" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "« {path} » graphique trouvée sans métadonnées pour l'application « {name} » !" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "Appids invalide trouvée dans l'argument" @@ -726,6 +854,11 @@ msgstr "Appids invalide trouvée dans l'argument" msgid "Found invalid versionCodes for some apps" msgstr "Code de version invalide trouvée pour certaines application" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Plusieurs certificats signées trouvée dans {path}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -749,6 +882,11 @@ msgstr "Aucun certificat signée trouvée dans le dépot." msgid "Found non-file at %s" msgstr "Aucun fichier trouvée a %s" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "Traitement de {apkfilename}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -771,6 +909,11 @@ msgstr "Recherche du Git échouée" msgid "Git remote set-head failed" msgstr "Set-head distant du Git à échouer" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Set-head distant du Git à échouer" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Reset de Git échouée" @@ -787,6 +930,25 @@ msgstr "Échec de la mise à jour du sous-module Git" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS doit être utilisé avec les URL de Subversion !" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Ignorer le package sans métadonnées : " @@ -805,6 +967,18 @@ msgstr "Ignorer le fichier {ext} à '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Inclure des fichiers APK signés avec algorithmes désactivés comme MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Initialisation des sous-modules" @@ -813,21 +987,31 @@ msgstr "Initialisation des sous-modules" msgid "Install all signed applications available" msgstr "Installer toutes les applications signées disponibles" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Installer les paquets compilés sur le(s) périphérique(s)" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Installation de %s …" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Installation de %s …" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Installation de '{apkfilename}' sur {dev}…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Installation de '{apkfilename}' sur {dev}…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interagir avec le serveur HTTP du dépôt" @@ -892,6 +1076,21 @@ msgstr "Nom de package non valide {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Redirection non valide vers non-HTTPS : {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Lire toutes les métadonnées et quitter" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -907,11 +1106,19 @@ msgstr "La signature JAR n'a pas pu vérifier:{path}" msgid "JAR signature verified: {path}" msgstr "Signature JAR vérifiée : {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Java JDK introuvable ! Installez dans un emplacement standard ou définissez java_paths !" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Java jarsigner introuvable ! Installez dans un emplacement standard ou définissez java_paths !" @@ -929,6 +1136,11 @@ msgstr "Stockage des clés signée :\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "Le dernier archivage utiliser '{commit}' ressemble a une balise, mais le Mode De Vérification Des Mise A Jour est '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "La méthode de donnation Liberapay appartien dans le flag LiberapayID" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "La méthode de donnation Liberapay appartien dans le flag LiberapayID" @@ -953,6 +1165,10 @@ msgstr "Mirroirs de dépot malformée." msgid "Malformed serverwebroot line:" msgstr "serverwebroot malformer en ligne :" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Répertoire de destination manquant" @@ -992,6 +1208,11 @@ msgid "No git submodules available" msgstr "Aucun sous-module git disponible" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Aucun projet android ou kivy n'a pu être trouver. Spécifiier --subdir ?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Aucune information trouvée." @@ -1020,7 +1241,7 @@ msgstr "Aucun apk signée dispognible pour %s" msgid "No signed output directory - nothing to do" msgstr "Aucun dossier de sortie signée - rien n'est a faire" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "Aucun certificat signée trouvée dans {path}" @@ -1040,6 +1261,10 @@ msgstr "Aucun code de version {versionCode} pour l'application {appid}" msgid "No unsigned directory - nothing to do" msgstr "Aucun dossier signée - rien n'est a faire" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Rien à faire" @@ -1072,7 +1297,7 @@ msgstr "Le nom de paquet d'OBB ne correspond pas à un fichier APK pris en charg msgid "Old APK signature failed to verify: {path}" msgstr "L'ancienne signature APK n'a pas pu être vérifiée : {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Ancien nom obsolète pour fdroid deploy" @@ -1089,6 +1314,11 @@ msgstr "Afficher uniquement les différences avec le Play Store" msgid "Only process apps with auto-updates" msgstr "Traiter uniquement les applications ayant des mises à jour automatiques" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "La méthode de donnation Flattr reviens au flag FlatttrID" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1098,6 +1328,16 @@ msgstr "Options" msgid "Output JSON report to file named after APK." msgstr "Générez un rapport JSON dans un fichier nommé d'après l'APK." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Licence globale du projet." @@ -1111,6 +1351,11 @@ msgstr "Remplacer le chemin pour les fichiers APK de dépôt (par défaut : ./ msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Substitution du nom de version vide dans {apkfilename} des métadonnées : {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1204,11 +1449,11 @@ msgstr "Envoyer les logs de transparence de la compilation vers {url}" msgid "Pushing to {url}" msgstr "Envoyer vers {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Démarrer un nouveau dépôt rapidement" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Lire toutes les métadonnées et quitter" @@ -1267,7 +1512,7 @@ msgstr "Redimensionner toutes les icônes excédant la taille maximale en pixels msgid "Restrict output to warnings and errors" msgstr "Limiter la sortie aux avertissements et aux erreurs" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Réécrire toutes les métadonnées" @@ -1306,7 +1551,11 @@ msgstr "Exécution de wget dans {path}" msgid "Scan only the latest version of each package" msgstr "Analyser seulement la dernière version de chaque paquet" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Scanner le code source d'un paquet" @@ -1330,12 +1579,16 @@ msgstr[1] "Le scanneur a trouvé {} problèmes" msgid "Set clock to that time using:" msgstr "Réglez l'horloge à cette heure à l'aide de :" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Définition de la limite de fichiers ouverts à {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Programmer une compilation de l'application pour le dépôt des versions de test" @@ -1356,11 +1609,11 @@ msgstr "Installez un émulateur, installez l'APK dessus et effectuez un scan Dro msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Signer et déplacer les paquets dans le dépôt" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Signer les indexes créés avec update --nosign" @@ -1418,6 +1671,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Ignorer les données de cache périmées pour {apkfilename}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1476,6 +1734,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1489,6 +1751,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1502,12 +1768,21 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Balise de licence non valide \"%s\" ! Utilisez uniquement des balises de https ://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Exception inconnue détectée !" @@ -1527,6 +1802,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "Format de métadonnée inconnu : {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Format de métadonnée inconnu : {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1605,19 +1885,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Mettre à jour les données des dépôts pour les nouveaux paquets" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Mettre à jour le rapport de transparence des fichiers binaires pour une URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Mettre à jour les statistiques du dépôt" @@ -1640,6 +1930,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Lecture de {apkfilename} à partir du cache" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1675,6 +1975,14 @@ msgstr "Utiliser la date de l'APK plutôt que la date courante pour les APKs nou msgid "Using \"{path}\" for configuring s3cmd." msgstr "Utiliser \"{path}\" pour configurer s3cmd." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "L'utilisation de l'utilitaire jarsigner de Java n'est pas recommandé pour vérifier les APKs ! Utiliser apksigner" @@ -1694,7 +2002,7 @@ msgstr "Utilise le trousseau existant \"{path}\"" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Les commandes valides sont les suivantes :" @@ -1702,7 +2010,7 @@ msgstr "Les commandes valides sont les suivantes :" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Vérifier l'intégrité des paquets téléchargés" @@ -1710,7 +2018,12 @@ msgstr "Vérifier l'intégrité des paquets téléchargés" msgid "Verifying index signature:" msgstr "Vérification de la signature d'index :" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avertir de possibles erreurs dans les métadonnées" @@ -1718,6 +2031,10 @@ msgstr "Avertir de possibles erreurs dans les métadonnées" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Nom distingué' utilisé lors de la génération des clés" @@ -1729,6 +2046,10 @@ msgstr "X.509 'Nom distingué' utilisé lors de la génération des clés" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "Vous pouvez utiliser ANDROID_HOME pour définir le chemin de votre SDK, ex. :" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1751,6 +2072,10 @@ msgstr "option ambiguë : %(option)s peut correspondre à %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "option ambiguë : %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId sous la forme de APPID" @@ -1772,16 +2097,30 @@ msgstr "applicationId avec le versionCode optionnel sous la forme APPID[:VERCODE msgid "argument \"-\" with mode %r" msgstr "argument \"-\" avec le mode %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "tentative de connexion ssh simple pour tester la clé de déploiement :" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "tentative de connexion ssh simple pour tester la clé de déploiement :" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "Impossible d'ouvrir %s : %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "Impossible de trouver un appid pour {path} !" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1806,6 +2145,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "Commande à exécuter : 'init' ou 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1824,6 +2167,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1839,12 +2195,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1877,7 +2242,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1898,6 +2263,10 @@ msgstr "forcer les erreurs (par défaut) sur les métadonnées à être des aver msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1975,7 +2344,7 @@ msgstr "" msgid "no such option: %s" msgstr "option inexistante : %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "aucun information de version n'a été trouvée !" @@ -2063,6 +2432,11 @@ msgstr "" msgid "positional arguments" msgstr "arguments de position" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2073,11 +2447,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2110,6 +2492,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2145,7 +2531,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "permissions dangereuses sur '{config_file}' (doit être 0600) !" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "usage : " @@ -2158,6 +2544,10 @@ msgstr "utilisation : fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "utilisation de Apache libcloud pour syncronizer avec {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2221,16 +2611,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2246,11 +2651,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2263,18 +2678,6 @@ msgid_plural "{} builds succeeded" msgstr[0] "" msgstr[1] "" -#~ msgid "Interactively ask about things that need updating." -#~ msgstr "Demander de manière interactive les choses nécessitant une mise à jour." - -#~ msgid "Specify editor to use in interactive mode. Default " -#~ msgstr "Définir l'éditeur à utiliser en mode interactif. Par défaut " - -#~ msgid "Specify editor to use in interactive mode. Default %s" -#~ msgstr "Définir l'éditeur à utiliser en mode interactif. Par défaut %s" - -#~ msgid "Specify editor to use in interactive mode. Default is {path}" -#~ msgstr "Définir l'éditeur à utiliser en mode interactif. {path} est utilisé par défaut" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Ajouter des signatures GPG pour les paquets dans le dépôt" @@ -2287,3 +2690,15 @@ msgstr[1] "" #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "Mise à jour propre - n'utilise pas les caches, ré-exécute tous les APKs" + +#~ msgid "Interactively ask about things that need updating." +#~ msgstr "Demander de manière interactive les choses nécessitant une mise à jour." + +#~ msgid "Specify editor to use in interactive mode. Default " +#~ msgstr "Définir l'éditeur à utiliser en mode interactif. Par défaut " + +#~ msgid "Specify editor to use in interactive mode. Default %s" +#~ msgstr "Définir l'éditeur à utiliser en mode interactif. Par défaut %s" + +#~ msgid "Specify editor to use in interactive mode. Default is {path}" +#~ msgstr "Définir l'éditeur à utiliser en mode interactif. {path} est utilisé par défaut" diff --git a/locale/hu/LC_MESSAGES/fdroidserver.po b/locale/hu/LC_MESSAGES/fdroidserver.po index 34a43b6b..2b736420 100644 --- a/locale/hu/LC_MESSAGES/fdroidserver.po +++ b/locale/hu/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-04-07 13:43+0000\n" "Last-Translator: Balázs Meskó \n" "Language-Team: Hungarian \n" @@ -16,6 +16,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.0-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -24,6 +34,15 @@ msgstr "" "\n" "A telepítési kulcsként használandó nyilvános SSH-kulcs:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"A telepítési kulcsként használandó nyilvános SSH-kulcs:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -38,6 +57,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "A(z) „%s/” nem rendelkezik megfelelő metaadatfájllal." +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "A(z) „{apkfilename}” már telepítve van ezen: {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -53,11 +77,21 @@ msgstr "A(z) „{path}” friss {name} csomagot tartalmaz ({version})" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "A(z) „{path}” létezik, de az s3cmd nincs telepítve." +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "A(z) „{path}” nem egy elfogadott formátum, alakítsa át erre: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "A(z) „{path}” nem egy elfogadott formátum, alakítsa át erre: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -108,6 +142,10 @@ msgstr "A(z) %s kapcsoló nem fogad értéket" msgid "'keypass' not found in config.py!" msgstr "A „keypass” nem található a config.py fájlban." +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "A „keystore” nem található a config.py fájlban." @@ -189,11 +227,11 @@ msgstr "a /issues hiányzik" msgid "A URL is required as an argument!" msgstr "Az URL argumentumként megadása szükséges." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "PGP aláírások hozzáadása GnuPG segítségével a tároló csomagjaihoz" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Új alkalmazás hozzáadása a forráskódjából" @@ -226,6 +264,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -286,7 +336,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Csomag összeállítása forrásból" @@ -342,6 +397,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -360,7 +420,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Alkalmazásfrissítések keresése" @@ -389,7 +449,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "A(z) „%s” nem ismerhető fel.\n" @@ -398,11 +458,23 @@ msgstr "A(z) „%s” nem ismerhető fel.\n" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -412,6 +484,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -487,6 +568,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Minden metaadat nélküli APK és OBB fájl törlése a tárolóból" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -511,6 +602,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -545,7 +640,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -591,6 +686,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -604,14 +704,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -673,6 +778,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -684,6 +794,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -697,11 +811,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -711,6 +834,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -734,6 +862,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -756,6 +889,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -772,6 +910,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -790,6 +947,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -798,21 +967,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Összeállított csomagok telepítése az eszközökre" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interakció a tároló HTTP kiszolgálójával" @@ -877,6 +1056,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Összes metaadatfájl felolvasása és kilépés" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -892,11 +1086,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -914,6 +1116,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -938,6 +1144,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -977,6 +1187,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1005,7 +1219,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1025,6 +1239,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1057,7 +1275,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1074,6 +1292,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1083,6 +1305,16 @@ msgstr "Beállítások" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1096,6 +1328,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1189,11 +1426,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Új tároló gyors elindítása" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Összes metaadatfájl felolvasása és kilépés" @@ -1252,7 +1489,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Összes metaadatfájl újraírása" @@ -1291,7 +1528,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "A csomag forráskódjának átvizsgálása" @@ -1315,12 +1556,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1340,11 +1585,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Aláírás és csomagok tárolóba helyezése" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Az update --nosign paranccsal készült indexek aláírása" @@ -1402,6 +1647,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1460,6 +1710,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1473,6 +1727,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1486,12 +1744,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Ismeretlen kivétel észlelve!" @@ -1511,6 +1777,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1589,19 +1860,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Tárolóinformációk frissítése az új csomagoknál" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "A bináris átláthatósági napló frissítése az URL-nél" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "A tároló statisztikáinak frissítése" @@ -1624,6 +1905,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1659,6 +1950,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1678,7 +1977,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Az érvényes parancsok:" @@ -1686,7 +1985,7 @@ msgstr "Az érvényes parancsok:" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Ellenőrizze a letöltött csomagok érintetlenségét" @@ -1694,7 +1993,12 @@ msgstr "Ellenőrizze a letöltött csomagok érintetlenségét" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Figyelmeztetés a lehetséges metaadat-hibákról" @@ -1702,6 +2006,10 @@ msgstr "Figyelmeztetés a lehetséges metaadat-hibákról" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1713,6 +2021,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1735,6 +2047,10 @@ msgstr "nem egyértelmű kapcsoló: %(option)s, ezekre illeszkedhet: %(matches)s msgid "ambiguous option: %s (%s?)" msgstr "nem egyértelmű kapcsoló: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1756,16 +2072,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "„%s” nem nyitható meg: %s" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1790,6 +2119,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1808,6 +2141,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1823,12 +2169,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1861,7 +2216,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1882,6 +2237,10 @@ msgstr "" msgid "git svn clone failed" msgstr "git svn klónozás meghiúsult" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1959,7 +2318,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2047,6 +2406,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2057,11 +2421,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2094,6 +2466,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2129,7 +2505,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "használat: " @@ -2142,6 +2518,10 @@ msgstr "használat: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2205,16 +2585,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2230,11 +2625,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index 552c8633..ad493220 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-09-19 17:03+0000\n" "Last-Translator: IvanDan \n" "Language-Team: Italian \n" @@ -19,6 +19,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -27,6 +37,15 @@ msgstr "" "\n" "Chiave pubblica SSH da usare come chiave di deploy:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Chiave pubblica SSH da usare come chiave di deploy:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -41,6 +60,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" non ha un file di metadata corrispondente!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "\"{apkfilename}\" è già installato su {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -56,11 +80,21 @@ msgstr "\"{path}\" contiene {name} recente ({version})" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" esiste ma s3cmd non è installato!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" non è un formato accettato, convertire a: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" non è un formato accettato, convertire a: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -111,6 +145,10 @@ msgstr "l'opzione %s non accetta un valore" msgid "'keypass' not found in config.py!" msgstr "\"keypass\" non trovato in config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "\"keystore\" non trovato in config.py!" @@ -192,11 +230,11 @@ msgstr "/issues è mancante" msgid "A URL is required as an argument!" msgstr "È richiesto un URL come argomento!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Aggiungi firme PGP con GnuPG per i pacchetti in un repository" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Aggiungi una nuova applicazione dal suo codice sorgente" @@ -229,6 +267,19 @@ msgstr "Esegui il mirroring anche per l'intera sezione archivi" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Avvisa anche dei problemi di formattazione, come rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Android SDK non trovato!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -289,7 +340,12 @@ msgstr "Branch \"{branch}\"usata come commit nella build \"{versionName}\"" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Branch \"{branch}\" usata come commit in srclib \"{srclib}\"" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Costruisci un pacchetto dai sorgenti" @@ -345,6 +401,11 @@ msgstr "Impossibile leggere \"{path}\"!" msgid "Cannot resolve app id {appid}" msgstr "Impossibile trovare l'app id {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Impossibile leggere \"{path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "Impossibile usare --list e --to contemporaneamente" @@ -363,7 +424,7 @@ msgstr "La categoria \"%s\" non è valida" msgid "Categories are not set" msgstr "Le categorie non sono impostate" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Cerca gli aggiornamenti delle applicazioni" @@ -392,7 +453,7 @@ msgstr "Aggiornamento pulito - non usa cache, riprocessa tutti gli APK" msgid "Comma separated list of categories." msgstr "Lista di categorie separate da una virgola." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Comando \"%s\" non riconosciuto.\n" @@ -401,11 +462,25 @@ msgstr "Comando \"%s\" non riconosciuto.\n" msgid "Commit changes" msgstr "Cambiamenti del commit" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "Impossibile trovare \"{command}\" sul tuo sistema" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Impossibile trovare il codice dell'ultima versione" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Impossibile trovare il nome dell'ultima versione" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -415,6 +490,16 @@ msgstr "Impossibile trovare {path} da rimuovere" msgid "Could not open apk file for analysis" msgstr "Impossibile aprire il file apk per l'analisi" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Impossibile trovare l'ID del pacchetto" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -490,6 +575,16 @@ msgstr "DEBUG_KEYSTORE non impostato o il valore è incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Cancella gli APK e/o OBB senza metadata dal repository" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -514,6 +609,10 @@ msgstr "La descrizione ha un elenco (%s) ma non è puntato (*) né numerato (#)" msgid "Description of length {length} is over the {limit} char limit" msgstr "La descrizione di lunghezza {length} supera il limite di {limit} caratteri" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Non distribuire i nuovi file nel repository" @@ -548,7 +647,7 @@ msgstr "Non aggiornare il repository, utile per testare una build offline" msgid "Don't use rsync checksums" msgstr "Non usare checksum rsync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -596,6 +695,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "Flag build vuoto a {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -611,14 +715,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Errore tentando di pubblicare il log: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Errore nell'ottenere l'indirizzo del repo" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Estrai le firme dagli APK" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Impossibile leggere {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -680,6 +789,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -691,6 +805,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -704,11 +822,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -718,6 +845,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -741,6 +873,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -763,6 +900,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -779,6 +921,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -797,6 +958,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -805,21 +978,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Installa i pacchetti costruiti su dispositivi" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Impossibile installare '{apkfilename}' su {dev}: {error}" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interagisci col server HTTP del repository" @@ -884,6 +1067,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Leggi tutti i file di metadata ed esci" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -899,11 +1097,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -921,6 +1127,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -945,6 +1155,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -984,6 +1198,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Nessun informazione trovata." @@ -1012,7 +1230,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1032,6 +1250,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1064,7 +1286,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1081,6 +1303,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1090,6 +1316,16 @@ msgstr "Opzioni" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1103,6 +1339,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1196,11 +1437,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Crea velocemente un nuovo repository" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Leggi tutti i file di metadata ed esci" @@ -1259,7 +1500,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Riscrivi tutti i file di metadata" @@ -1298,7 +1539,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Scansiona il codice sorgente di un pacchetto" @@ -1322,12 +1567,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1347,11 +1596,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Firma e metti i pacchetti nel repository" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Firma gli indici creati con update --nosign" @@ -1409,6 +1658,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Impossibile recuperare le firme per '{apkfilename}': {error}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1467,6 +1721,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1480,6 +1738,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1493,12 +1755,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Eccezione sconosciuta trovata!" @@ -1518,6 +1788,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1596,19 +1871,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Aggiorna le informazioni del repository coi nuovi pacchetti" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Aggiorna il log di trasparenza binario con un nuovo URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Aggiorna le statistiche del repo" @@ -1631,6 +1916,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1666,6 +1961,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1685,7 +1988,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "Utilizzando s3cmd per sincronizzare con: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "I comandi validi sono:" @@ -1693,7 +1996,7 @@ msgstr "I comandi validi sono:" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Verifica l'integrità dei pacchetti scaricati" @@ -1701,7 +2004,12 @@ msgstr "Verifica l'integrità dei pacchetti scaricati" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avvisa riguardo possibili errori metadata" @@ -1709,6 +2017,10 @@ msgstr "Avvisa riguardo possibili errori metadata" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1720,6 +2032,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1742,6 +2058,10 @@ msgstr "opzione ambigua: %(option)s potrebbe corrispondere a %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "opzione ambigua: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1763,16 +2083,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "impossibile aprire \"%s\": %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "Impossibile trovare un appid per {path}!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1797,6 +2130,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1815,6 +2152,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1830,12 +2180,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1868,7 +2227,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1889,6 +2248,10 @@ msgstr "forza gli errori di metadati (predefinito) come avvisi, o da ignorare." msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1966,7 +2329,7 @@ msgstr "" msgid "no such option: %s" msgstr "opzione inesistente: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "nessuna informazione sulla versione è stata trovata!" @@ -2054,6 +2417,11 @@ msgstr "" msgid "positional arguments" msgstr "argomenti posizionali" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2064,11 +2432,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2101,6 +2477,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2136,7 +2516,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "permessi su \"{config_file}\" insicuri (dovrebbero essere 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "utilizzo: " @@ -2149,6 +2529,10 @@ msgstr "utilizzo: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "utilizzando Apache libcloud per sincronizzare con {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2212,16 +2596,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2237,11 +2636,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/ja/LC_MESSAGES/fdroidserver.po b/locale/ja/LC_MESSAGES/fdroidserver.po index e8521511..06a01427 100644 --- a/locale/ja/LC_MESSAGES/fdroidserver.po +++ b/locale/ja/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-224-g4b0ade7\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-09-02 16:10+0000\n" "Last-Translator: Hinaloe \n" "Language-Team: Japanese \n" @@ -16,12 +16,28 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -34,6 +50,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}'はすでに{dev}にインストールされています。" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -49,11 +70,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -103,6 +134,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -184,11 +219,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -221,6 +256,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -281,7 +328,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "" @@ -336,6 +388,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -354,7 +411,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -383,7 +440,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -392,11 +449,23 @@ msgstr "" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -406,6 +475,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -481,6 +559,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -505,6 +593,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -539,7 +631,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -585,6 +677,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -598,14 +695,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -667,6 +769,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -678,6 +785,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -691,11 +802,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -705,6 +825,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -728,6 +853,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -750,6 +880,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -766,6 +901,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -784,6 +938,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -792,21 +958,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -871,6 +1047,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -886,11 +1077,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -908,6 +1107,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -932,6 +1135,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -971,6 +1178,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -999,7 +1210,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1019,6 +1230,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1051,7 +1266,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1068,6 +1283,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1077,6 +1296,16 @@ msgstr "" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1090,6 +1319,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1183,11 +1417,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1246,7 +1480,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1285,7 +1519,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1308,12 +1546,16 @@ msgstr[0] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1333,11 +1575,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1395,6 +1637,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1453,6 +1700,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1466,6 +1717,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1479,12 +1734,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1504,6 +1767,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1582,19 +1850,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1617,6 +1895,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1652,6 +1940,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1671,7 +1967,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1679,7 +1975,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1687,7 +1983,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1695,6 +1996,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1706,6 +2011,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1728,6 +2037,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1749,16 +2062,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1783,6 +2109,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1800,6 +2130,19 @@ msgstr[0] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1815,12 +2158,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1852,7 +2204,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1873,6 +2225,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1950,7 +2306,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2038,6 +2394,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2048,11 +2409,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2085,6 +2454,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2120,7 +2493,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2133,6 +2506,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2195,16 +2572,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2220,11 +2612,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/kab/LC_MESSAGES/fdroidserver.po b/locale/kab/LC_MESSAGES/fdroidserver.po index ea8ccc38..173b59b4 100644 --- a/locale/kab/LC_MESSAGES/fdroidserver.po +++ b/locale/kab/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-01 09:00+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Kabyle \n" @@ -16,12 +16,28 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -34,6 +50,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' yebded yakan ɣef {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -49,11 +70,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -104,6 +135,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "'keypass' ulac-it di config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore' ulac-it di config.py!" @@ -185,11 +220,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -222,6 +257,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -282,7 +329,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "" @@ -338,6 +390,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -356,7 +413,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -385,7 +442,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -394,11 +451,23 @@ msgstr "" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -408,6 +477,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -483,6 +561,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -507,6 +595,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -541,7 +633,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -587,6 +679,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -600,14 +697,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -669,6 +771,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -680,6 +787,10 @@ msgstr "Immed" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -693,11 +804,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -707,6 +827,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -730,6 +855,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -752,6 +882,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -768,6 +903,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -786,6 +940,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -794,21 +960,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Asbeddi n %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Asbeddi n %s…" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -873,6 +1049,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -888,11 +1079,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -910,6 +1109,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -934,6 +1137,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -973,6 +1180,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1001,7 +1212,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1021,6 +1232,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1053,7 +1268,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1070,6 +1285,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1079,6 +1298,16 @@ msgstr "Iɣewwaṛen" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1092,6 +1321,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1185,11 +1419,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1248,7 +1482,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1287,7 +1521,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1311,12 +1549,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1336,11 +1578,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1398,6 +1640,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1456,6 +1703,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1469,6 +1720,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1482,12 +1737,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1507,6 +1770,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1585,19 +1853,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Leqqem tidaddanin n ukufi" @@ -1620,6 +1898,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1655,6 +1943,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1674,7 +1970,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1682,7 +1978,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1690,7 +1986,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1698,6 +1999,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1709,6 +2014,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1731,6 +2040,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1752,16 +2065,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1786,6 +2112,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1804,6 +2134,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1819,12 +2162,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1857,7 +2209,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1878,6 +2230,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1955,7 +2311,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2043,6 +2399,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2053,11 +2414,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2090,6 +2459,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2125,7 +2498,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "aqseqdac: " @@ -2138,6 +2511,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2201,16 +2578,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2226,11 +2618,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/ko/LC_MESSAGES/fdroidserver.po b/locale/ko/LC_MESSAGES/fdroidserver.po index 021c31ae..4e70572f 100644 --- a/locale/ko/LC_MESSAGES/fdroidserver.po +++ b/locale/ko/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-135-g16dd6d28\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2019-01-19 22:57+0000\n" "Last-Translator: Seokyong Jung \n" "Language-Team: Korean \n" @@ -17,6 +17,16 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.4-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -25,6 +35,15 @@ msgstr "" "\n" "배포 키로 사용될 SSH 공개 키:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"배포 키로 사용될 SSH 공개 키:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -39,6 +58,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\"에 일치하는 메타데이터 파일이 없습니다!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}'는 이미 {dev}에 설치되어 있습니다." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -54,11 +78,21 @@ msgstr "\"{path}\"는 최근 {name} ({version})를 포함합니다" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\"는 존재하지만 s3cmd는 설치되어 있지 않습니다!" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -108,6 +142,10 @@ msgstr "%s 옵션은 값을 받지 않습니다" msgid "'keypass' not found in config.py!" msgstr "'keypass'를 config.py에서 찾을 수 없습니다!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore'를 config.py에서 찾을 수 없습니다!" @@ -189,11 +227,11 @@ msgstr "/이슈가 없습니다" msgid "A URL is required as an argument!" msgstr "URL은 인수로서 필요합니다!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "저장소의 패키지를 위해 GnuPG를 사용하여 PGP 서명을 추가합니다" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "새 애플리케이션의 소스 코드로부터 그것을 추가합니다" @@ -226,6 +264,19 @@ msgstr "또한 전체 보존 절을 미러합니다" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "또한 rewritemeta -l와 같이, 포맷팅 이슈에 대해 경고합니다" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Android SDK를 찾을 수 없습니다!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -286,7 +337,12 @@ msgstr "브랜치 '{branch}'는 빌드 '{versionName}'에서 커밋으로 사용 msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "브랜치 '{branch}'는 srclib '{srclib}'에서 커밋으로 사용됩니다" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "소스로부터 패키지를 빌드합니다" @@ -341,6 +397,11 @@ msgstr "\"{path}\"를 읽을 수 없습니다!" msgid "Cannot resolve app id {appid}" msgstr "앱 id {appid}를 해결할 수 없습니다" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "\"{path}\"를 읽을 수 없습니다!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "--list 와 --to는 동시에 사용할 수 없습니다" @@ -359,7 +420,7 @@ msgstr "카테고리 '%s'는 올바르지 않습니다" msgid "Categories are not set" msgstr "카테고리가 설정되어 있지 않습니다" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "애플리케이션으로의 업데이트를 확인합니다" @@ -388,7 +449,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "명령 '%s'은 인식되지 않습니다.\n" @@ -397,11 +458,23 @@ msgstr "명령 '%s'은 인식되지 않습니다.\n" msgid "Commit changes" msgstr "번경사항 커밋" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -411,6 +484,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -486,6 +568,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "저장소에서 메타데이터 없이 APK 및/또는 OBB를 삭제합니다" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -510,6 +602,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -544,7 +640,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -590,6 +686,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -603,14 +704,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -672,6 +778,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -683,6 +794,10 @@ msgstr "마침" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -696,11 +811,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "앱 \"{name}\"를 위한 메타데이터가 없이 \"{path}\" 그래픽을 찾았습니다!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -710,6 +834,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -733,6 +862,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "{path} 안으로 {apkfilename}을 복사 중" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -755,6 +889,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -771,6 +910,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -789,6 +947,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "하위 모듈을 초기 설정 중" @@ -797,21 +967,31 @@ msgstr "하위 모듈을 초기 설정 중" msgid "Install all signed applications available" msgstr "사용 가능한 모든 서명된 애플리케이션 설치" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "기기에 내장된 패키지 설치" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "%s 설치 중…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "%s 설치 중…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "{dev}에서 '{apkfilename}' 설치 중…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "{dev}에서 '{apkfilename}' 설치 중…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "저장소 HTTP 서버와의 상호 작용" @@ -876,6 +1056,21 @@ msgstr "잘못된 패키지 이름 {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "HTTPS가 아닌 곳으로의 잘못된 리다이렉트: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "모든 메타데이터 파일을 읽고 종료합니다" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -891,11 +1086,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -913,6 +1116,10 @@ msgstr "서명 키를 위한 키저장소:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -937,6 +1144,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -976,6 +1187,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1004,7 +1219,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1024,6 +1239,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1056,7 +1275,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1073,6 +1292,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1082,6 +1305,16 @@ msgstr "옵션" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1095,6 +1328,11 @@ msgstr "저장소 APK를 위한 경로 재정의 (기본값: ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1188,11 +1426,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "새 저장소를 빠르게 시작합니다" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "모든 메타데이터 파일을 읽고 종료합니다" @@ -1251,7 +1489,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "모든 메타데이터 파일을 다시 씁니다" @@ -1290,7 +1528,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "패키지의 소스 코드를 스캔합니다" @@ -1313,12 +1555,16 @@ msgstr[0] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1338,11 +1584,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "저장소에서 패키지를 서명하고 배치합니다" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "update --nosign을 사용하여 만들어진 색인을 서명합니다" @@ -1400,6 +1646,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1458,6 +1709,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1471,6 +1726,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1484,12 +1743,21 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "잘못된 라이선스 태그 \"%s\"! https://spdx.org/license-list 에서의 태그만을 사용하세요" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "알 수 없는 예외가 찾아졌습니다!" @@ -1509,6 +1777,11 @@ msgstr "알 수 없는 메타데이터 형식: %s" msgid "Unknown metadata format: {path}" msgstr "알 수 없는 메타데이터 형식: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "알 수 없는 메타데이터 형식: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1527,7 +1800,6 @@ msgstr "" #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "copying {apkfilename} into {path}" msgid "Unrecognised app field '{fieldname}' in '{path}'" msgstr "{path} 안으로 {apkfilename}을 복사 중" @@ -1588,19 +1860,29 @@ msgstr "%s에서 사용되지 않은 extlib" msgid "Unused file at %s" msgstr "%s에서 사용되지 않은 파일" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "%s에서 사용되지 않은 파일" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "%s에서 사용되지 않은 파일" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "새 패키지를 위한 저장소 정보를 업데이트합니다" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "URL을 위한 바이너리 투명성 기록을 업데이트합니다" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "저장소의 통계를 업데이트" @@ -1623,6 +1905,16 @@ msgstr "UpdateCheckData는 HTTPS URL을 사용해야 합니다: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData는 올바른 URL이 아닙니다: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "{path} 안으로 {apkfilename}을 복사 중" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1658,6 +1950,14 @@ msgstr "새로 추가된 apk를 위해 현재 시간 대신에 apk에서의 날 msgid "Using \"{path}\" for configuring s3cmd." msgstr "s3cmd를 구성하기 위해 \"{path}\" 사용." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Java의 jarsigner를 사용하여, APK를 검증하는 것은 권장되지 않습니다! apksigner를 사용하세요" @@ -1677,7 +1977,7 @@ msgstr "기존 키스토어 \"{path}\"를 사용 중" msgid "Using s3cmd to sync with: {url}" msgstr "다음과 동기화하는 데 s3cmd 사용: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "올바른 명령은:" @@ -1685,7 +1985,7 @@ msgstr "올바른 명령은:" msgid "Verify against locally cached copy rather than redownloading." msgstr "로컬에 캐시된 복사본을 다시 다운로드하는 대신에 검증합니다." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "다운로드된 패키지의 무결성 확인" @@ -1693,7 +1993,12 @@ msgstr "다운로드된 패키지의 무결성 확인" msgid "Verifying index signature:" msgstr "색인 서명을 검증 중:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "가능한 메타데이터 오류에 대해 경고합니다" @@ -1701,6 +2006,10 @@ msgstr "가능한 메타데이터 오류에 대해 경고합니다" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1712,6 +2021,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "당신은 당신의 SDK에 경로를 설정하기 위해 ANDROID_HOME을 사용할 수 있습니다, 즉:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1734,6 +2047,10 @@ msgstr "모호한 옵션: %(option)s은 %(matches)s와 일치했을 수 있습 msgid "ambiguous option: %s (%s?)" msgstr "모호한 옵션: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "양식 APPID의 applicationId" @@ -1755,16 +2072,29 @@ msgstr "양식 APPID[:VERCODE]에서 선택적인 versionCode로 된 application msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "'%s'를 열 수 없습니다: %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "{path}를 위한 appid를 찾을 수 없습니다!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1789,6 +2119,10 @@ msgstr "{url}를 복제 중" msgid "command to execute, either 'init' or 'update'" msgstr "실행할 명령, 'init' 또는 'update' 중 하나" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1806,6 +2140,19 @@ msgstr[0] "충돌하는 옵션 문자열: %s" msgid "copying {apkfilename} into {path}" msgstr "{path} 안으로 {apkfilename}을 복사 중" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1821,12 +2168,21 @@ msgstr "삭제 중: repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest=는 %r과 같은 옵션을 위해 필요합니다" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1858,7 +2214,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] <명령> [<인수>]" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [<명령>] [-h|--help|--version|<인수>]" @@ -1879,6 +2235,10 @@ msgstr "경고하거나 무시되는 강제 메타데이터 오류 (기본값)." msgid "git svn clone failed" msgstr "git svn 복제에 실패됨" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1956,7 +2316,7 @@ msgstr "제공된 APK가 없습니다" msgid "no such option: %s" msgstr "이러한 옵션이 없습니다: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "버전 정보를 찾지 못했습니다!" @@ -2044,6 +2404,11 @@ msgstr "기존 {path}를 덮어쓰는 중" msgid "positional arguments" msgstr "고정적 인수" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2054,11 +2419,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd 동기화는 {url}로 {path}를 색인하고 삭제합나다" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2091,6 +2464,10 @@ msgstr "소스 타르볼을 건너뛰는 중: {path}" msgid "srclibs missing name and/or @" msgstr "srclibs 없는 이름 및/또는 @" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2126,7 +2503,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "'{config_file}'에 안전하지 않은 권한 (0600이어야 합니다)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "사용법: " @@ -2139,6 +2516,10 @@ msgstr "사용법: fdroid [-h|--help|--version] <명령> [<인수>]" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2201,16 +2582,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\"는 존재하지 않습니다! config.py에서 그것을 고치세요." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2226,11 +2622,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "{path}는 영 크기입니다!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url}는 \"fdroid\"로 끝나지 않습니다, URL 경로를 확인하세요!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url}는 \"fdroid\"로 끝나지 않습니다, URL 경로를 확인하세요!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/ml/LC_MESSAGES/fdroidserver.po b/locale/ml/LC_MESSAGES/fdroidserver.po index c6725281..c2f1b635 100644 --- a/locale/ml/LC_MESSAGES/fdroidserver.po +++ b/locale/ml/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -16,12 +16,28 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -34,6 +50,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -49,11 +70,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -104,6 +135,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -185,11 +220,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -222,6 +257,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -282,7 +329,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "" @@ -338,6 +390,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -356,7 +413,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -385,7 +442,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -394,11 +451,23 @@ msgstr "" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -408,6 +477,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -483,6 +561,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -507,6 +595,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -541,7 +633,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -587,6 +679,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -600,14 +697,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -669,6 +771,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -680,6 +787,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -693,11 +804,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -707,6 +827,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -730,6 +855,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -752,6 +882,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -768,6 +903,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -786,6 +940,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -794,21 +960,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -873,6 +1049,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -888,11 +1079,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -910,6 +1109,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -934,6 +1137,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -973,6 +1180,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1001,7 +1212,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1021,6 +1232,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1053,7 +1268,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1070,6 +1285,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1079,6 +1298,16 @@ msgstr "" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1092,6 +1321,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1185,11 +1419,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1248,7 +1482,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1287,7 +1521,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1311,12 +1549,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1336,11 +1578,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1398,6 +1640,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1456,6 +1703,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1469,6 +1720,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1482,12 +1737,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1507,6 +1770,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1585,19 +1853,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1620,6 +1898,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1655,6 +1943,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1674,7 +1970,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1682,7 +1978,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1690,7 +1986,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1698,6 +1999,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1709,6 +2014,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1731,6 +2040,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1752,16 +2065,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1786,6 +2112,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1804,6 +2134,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1819,12 +2162,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1857,7 +2209,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1878,6 +2230,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1955,7 +2311,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2043,6 +2399,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2053,11 +2414,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2090,6 +2459,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2125,7 +2498,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2138,6 +2511,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2201,16 +2578,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2226,11 +2618,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index 55df985b..dbdd63d9 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-74-ga380b9f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-01 09:00+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Norwegian Bokmål \n" @@ -17,6 +17,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py #, fuzzy msgid "" @@ -26,6 +36,15 @@ msgstr "" "\n" "Offentlig SSH-nøkkel å bruke som utrullingsnøkkel:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Offentlig SSH-nøkkel å bruke som utrullingsnøkkel:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -40,6 +59,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" har ingen samsvarende metadatafil!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' er allerede installert på {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -55,11 +79,21 @@ msgstr "\"{path}\" inneholder nylig {name} ({version})" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" finnes, men s3cmd er ikke installert!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" er ikke et godtatt format, konverter til: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" er ikke et godtatt format, konverter til: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -110,6 +144,10 @@ msgstr "%s-valget tar ikke en verdi" msgid "'keypass' not found in config.py!" msgstr "'keypass' ble ikke funnet i config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore' ble ikke funnet i config.py!" @@ -193,11 +231,11 @@ msgstr "/issues mangler" msgid "A URL is required as an argument!" msgstr "valg -%s krever et argument" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Legg til PGP-signaturer for pakker i pakkebrønnen ved bruk av GnuPG" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Legg til et nytt program fra dets kildekode" @@ -230,6 +268,19 @@ msgstr "Speil også hele arkivdelen" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Advar også om formateringsproblemer, som rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Fant ingen Android-SDK." + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -290,7 +341,12 @@ msgstr "Forgrening '{branch}' brukt som innsendelse i bygg '{versionName}'" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Forgrening '{branch}' brukt som innsendelse i srclib '{srclib}'" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Bygg en pakke fra kildekode" @@ -348,6 +404,11 @@ msgstr "Kan ikke lese \"{path}\"." msgid "Cannot resolve app id {appid}" msgstr "Kan ikke fortolke program-ID {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Kan ikke lese \"{path}\"." + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "Kan ikke bruke --list og --to samtidig" @@ -366,7 +427,7 @@ msgstr "Kategorien '%s' er ikke gyldig" msgid "Categories are not set" msgstr "Kategoreier ikke satt" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Se etter programoppdateringer" @@ -395,7 +456,7 @@ msgstr "Ren oppdatering, ikke bruk hurtiglager, behandle alle APK-er på ny" msgid "Comma separated list of categories." msgstr "Kommainndelt liste over kategorier." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Kommandoen \"%s\" gjenkjennes ikke.\n" @@ -404,11 +465,25 @@ msgstr "Kommandoen \"%s\" gjenkjennes ikke.\n" msgid "Commit changes" msgstr "Send inn endringer" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "Fant ikke \"{command}\" på ditt system" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Fant ikke seneste versjonskode" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Fant ikke seneste versjonsnavn" + #: ../fdroidserver/update.py #, fuzzy, python-brace-format msgid "Could not find {path} to remove it" @@ -419,6 +494,16 @@ msgstr "Fant ikke \"{path}\" for fjerning derav" msgid "Could not open apk file for analysis" msgstr "Kunne ikke åpne APK-fil for analyse" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Fant ikke pakke-ID" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -496,6 +581,16 @@ msgstr "DEBUG_KEYSTORE er ikke satt, eller så er verdien ufullstendig" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Slett APK-er og/eller OBB-er uten metadata fra pakkebrønnen" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -521,6 +616,10 @@ msgstr "Beskrivelsen har en liste (%s), men er ikke punktvis (*) eller nummerert msgid "Description of length {length} is over the {limit} char limit" msgstr "Beskrivelse av lengde {length} overstiger {limit} tegngrensen" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Ikke send de nye filene til pakkebrønnen" @@ -558,7 +657,7 @@ msgstr "Ikke gjenoppfrisk pakkebrønnen, nyttig under testing av et bygg uten å msgid "Don't use rsync checksums" msgstr "Ikke bruk rsync-sjekksummer" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Last ned fullstendige speilinger av små pakkebrønner" @@ -609,6 +708,11 @@ msgstr "Feil: Ustøttet CI-type, feilrettinger er velkomne." msgid "Empty build flag at {linedesc}" msgstr "Tomt byggflagg på {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -624,15 +728,20 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Kunne ikke offentliggjøre logg: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py #, fuzzy msgid "Error while getting repo address" msgstr "Kunne ikke hente pakkebrønnsadresse" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Hent ut signaturer fra APK-er" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Klarte ikke å lese {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -697,6 +806,11 @@ msgstr "Hentet BuildServerID fra VM: {buildserverid}" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "Hentet signaturer for '{apkfilename}' → '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -708,6 +822,11 @@ msgstr "Fullført" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Flatter-donasjonsmetoder hører hjemme i FlattrID-flagget" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Flatter-donasjonsmetoder hører hjemme i FlattrID-flagget" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Forbudte HTML-tagger" @@ -721,11 +840,20 @@ msgstr "Tvinger bygging av avskrudde programmer, og fortsetter uavhengig av skan msgid "Force halting build after {0} sec timeout!" msgstr "Tving gjennom byggstans etter {0} sek. tidsavbrudd." +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, fuzzy, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "Fant \"{path}\"-grafikk uten metadata for programmet \"{name}\"." +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py #, fuzzy msgid "Found invalid appids in arguments" @@ -737,6 +865,11 @@ msgstr "Fant ugyldige App-ID-er i argumenter" msgid "Found invalid versionCodes for some apps" msgstr "Noen programmer ble funnet å ha ugldige versionCodes" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Fant flere signeringssertifikater i {path}." + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -761,6 +894,11 @@ msgstr "Fant ikke noe signeringssertifikat for pakkebrønn." msgid "Found non-file at %s" msgstr "Fant ikke-fil i %s" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "kopierer {apkfilename} inn i {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -784,6 +922,11 @@ msgstr "Git-innhenting mislyktes" msgid "Git remote set-head failed" msgstr "Git set-head annensteds hen mislyktes" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git set-head annensteds hen mislyktes" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Git-tilbakestilling mislyktes" @@ -800,6 +943,25 @@ msgstr "Git-oppdatering av undermodul mislyktes" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS må brukes sammen med Subversjon-nettadresser." +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Ignorerte pakke uten metadata: " @@ -819,6 +981,18 @@ msgstr "Ignorerer {ext}-fil i \"{path}\"" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Inkluder APK-er som er signert med svartelistede algoritmer, som MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Igangsetter undermoduler" @@ -828,21 +1002,31 @@ msgstr "Igangsetter undermoduler" msgid "Install all signed applications available" msgstr "Installer alle tilgjengelige signerte programmer" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Installer bygde pakker på enheter" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Installerer %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Installerer %s…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Installerer '{apkfilename}' på {dev}…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Installerer '{apkfilename}' på {dev}…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interagere med repo HTTP-serveren" @@ -908,6 +1092,21 @@ msgstr "Ugyldig pakkenavn {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Ugyldig videresending til ikke-HTTPS: {before} → {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Les alle metadatafilene og avslutt" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -923,12 +1122,20 @@ msgstr "Klarte ikke å bekrefte JAR-signatur: {path}" msgid "JAR signature verified: {path}" msgstr "JAR-signatur bekreftet: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py #, fuzzy msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Fant ingen Java JDK. Installer på vanlig plass, eller sett java_paths." +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py #, fuzzy msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -948,6 +1155,11 @@ msgstr "Nøkkellager for signeringsnøkkel:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "Sist brukte innsendelse \"{commit}\" ser ut som en tagg, men oppdateringssjekkingsmodus er på \"{ucm}\"." +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Flatter-donasjonsmetoder hører hjemme i FlattrID-flagget" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Flatter-donasjonsmetoder hører hjemme i FlattrID-flagget" @@ -974,6 +1186,10 @@ msgstr "Feilaktig innskrevne pakkebrønnsspeil." msgid "Malformed serverwebroot line:" msgstr "Feilaktig innskrevet serverwebroot-linje:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Manglende utdatamappe" @@ -1014,6 +1230,11 @@ msgid "No git submodules available" msgstr "Ingen Git-undermoduler tilgjengelige" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Fant inget Android- eller Kivy-prosjekt. Angi --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Ingen informasjon funnet." @@ -1042,7 +1263,7 @@ msgstr "Ingen signert APK tilgjengelig for %s" msgid "No signed output directory - nothing to do" msgstr "Ingen signert utdatamappe - ingenting å gjøre" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "Ingen signeringssertifikater funnet i {path}" @@ -1062,6 +1283,10 @@ msgstr "Ingen slik versionCode {versionCode} for programmet {appid}" msgid "No unsigned directory - nothing to do" msgstr "Ingen usignert mappe - ingenting å gjøre" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Ingenting å gjøre" @@ -1094,7 +1319,7 @@ msgstr "OBB-pakkenavn samsvarer ikke med noen støttet APK:" msgid "Old APK signature failed to verify: {path}" msgstr "Klarte ikke å bekrefte foreldet APK-signatur: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, fuzzy msgid "Old, deprecated name for fdroid deploy" msgstr "Gammelt, foreldet navn for fdroid-innsendelse" @@ -1113,6 +1338,11 @@ msgstr "Kun skriv ut forskjeller vis-a-vis Play-butikken" msgid "Only process apps with auto-updates" msgstr "Behandle kun programmer som har auto-oppdateringer" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Flatter-donasjonsmetoder hører hjemme i FlattrID-flagget" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1122,6 +1352,16 @@ msgstr "Valg" msgid "Output JSON report to file named after APK." msgstr "Skriv ut JSON-rapport til fil navngitt etter APK-en." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Overnevnt lisens for prosjektet." @@ -1135,6 +1375,11 @@ msgstr "Overskriv sti for pakkebrønns-APK-er (forvalg: ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Overskriver blank versionName i {apkfilename} fra metadata: {version}." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, fuzzy, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1232,11 +1477,11 @@ msgstr "Dytter binærgjennomsiktighetslogg til {url}." msgid "Pushing to {url}" msgstr "Dytter til {url}." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Raskt starte et nytt lager" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Les alle metadatafilene og avslutt" @@ -1298,7 +1543,7 @@ msgstr "Endre størrelse på alle ikoner som overstiger maksimal pikselantall og msgid "Restrict output to warnings and errors" msgstr "Begrens utdata til advarsler og feil" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Skriv om alle metadatafilene" @@ -1338,7 +1583,11 @@ msgstr "Kjører wget i {path}." msgid "Scan only the latest version of each package" msgstr "Skann kun siste versjon av hver pakke" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Skann kildekoden til en pakke" @@ -1362,12 +1611,16 @@ msgstr[1] "Skanner fant {} problemer" msgid "Set clock to that time using:" msgstr "Sett klokke til sådan tid ved bruk av:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, fuzzy, python-brace-format msgid "Set open file limit to {integer}" msgstr "Sett åpen filgrense til {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Sett opp programbygging for nattlig byggingspakkebrønn." @@ -1390,11 +1643,11 @@ msgstr "Sett opp en emulator, installer APK-en på den og utfør en Drozer-skann msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Sett opp en emulator, installer APK-en på den og utfør en Drozer-skanning" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Logg inn og legg til pakker i pakkebrønnen" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Signer indekser ved bruk av update --nosign" @@ -1454,6 +1707,11 @@ msgstr "Gulp opp enda mer info enn normalt" msgid "Striping mystery signature from {apkfilename}" msgstr "Stripper mystisk signatur fra {apkfilename}" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Stripper mystisk signatur fra {apkfilename}" + #: ../fdroidserver/lint.py #, fuzzy, python-format msgid "Summary '%s' is just the app's name" @@ -1514,6 +1772,10 @@ msgstr "Rotmappen for local_copy_dir \"{path}\" finnes ikke." msgid "There is a keyalias collision - publishing halted" msgstr "Nøkkelaliaskollisjon - offentliggjøring stanset" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1528,6 +1790,10 @@ msgstr "For å bruke AWS-spann, må \"awssecretkey\" og \"awsaccesskeyid\" også msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCM er satt, men det ser ut til at checkupdates ikke har blitt kjørt enda." +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py #, fuzzy msgid "URL shorteners should not be used" @@ -1542,12 +1808,21 @@ msgstr "Nettadressetittel er kun nettadressen, bruk hakeparenteser: [Nettadresse msgid "URL {url} in Description: {error}" msgstr "Nettadresse {url} i beskrivelse: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Ugyldig lisenstagg \"%s\". Kun bruk de som er å finne på https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "Uventet tekst på samme linje som {field} i {linedesc}." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Ukjent unntak møtt!" @@ -1567,6 +1842,11 @@ msgstr "Ukjent metadataformat: %s" msgid "Unknown metadata format: {path}" msgstr "Ukjent metadataformat: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Ukjent metadataformat: {path}" + #: ../fdroidserver/common.py #, fuzzy msgid "Unknown version of aapt, might cause problems: " @@ -1646,20 +1926,30 @@ msgstr "Ubrukt extlib i %s" msgid "Unused file at %s" msgstr "Ubrukt fil i %s" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "Ubrukt fil i %s" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "Ubrukt fil i %s" + #: ../fdroidserver/lint.py #, fuzzy msgid "Update Check Name is set to the known app id - it can be removed" msgstr "\"Update Check Name\" er satt til den kjente App-ID-en - den kan fjernes." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Oppdater repo informasjon for nye pakker" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Oppdater binær gjennomsiktighetslogg for en URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Oppdater pakkebrønnens status" @@ -1682,6 +1972,16 @@ msgstr "UpdateCheckData må bruke HTTPS-nettadresse: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData er ikke en gyldig nettadresse: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Behandler {apkfilename}" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1718,6 +2018,14 @@ msgstr "Bruk dato fra APK istedenfor nåværende tid for nylig tillagte APK-er" msgid "Using \"{path}\" for configuring s3cmd." msgstr "Bruker \"{path}\" for oppsett av s3cmd." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py #, fuzzy msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" @@ -1738,7 +2046,7 @@ msgstr "Bruker eksisterende nøkkellager \"{path}\"." msgid "Using s3cmd to sync with: {url}" msgstr "Bruk s3cmd til å synkronisere med: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Gyldige kommandoer er:" @@ -1746,7 +2054,7 @@ msgstr "Gyldige kommandoer er:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Bekreft mot lokalt hurtiglagret kopi snarere enn å laste ned på ny." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Bekreft integriteten til nedlastede pakker" @@ -1754,7 +2062,12 @@ msgstr "Bekreft integriteten til nedlastede pakker" msgid "Verifying index signature:" msgstr "Bekrefter indekssignatur:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Advar om mulige metadata-feil" @@ -1763,6 +2076,10 @@ msgstr "Advar om mulige metadata-feil" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Når oppsatt for signerte indekser, vil kun usignerte indekser bli opprettet i dette stadiet" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 \"Entydig navn\" (DN) brukt ved generering av nøkler." @@ -1775,6 +2092,10 @@ msgstr "X.509 \"Entydig navn\" (DN) brukt ved generering av nøkler." msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "Du kan bruke ANDROID_HOME til å sette stien til din SDK, f.eks:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, fuzzy, python-brace-format msgid "adding IdentityFile to {path}" @@ -1797,6 +2118,10 @@ msgstr "tvetydig valg: %(option)s kan passe overens med %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "tvetydig valg: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #, fuzzy msgid "applicationId in the form APPID" @@ -1819,17 +2144,31 @@ msgstr "App-ID med valgfri versionCode, i formen APPID[:VERCODE]" msgid "argument \"-\" with mode %r" msgstr "argument \"-\" med modus %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "forsøker naken SSH-tilkobling for å teste utrullingsnøkkel:" + #: ../fdroidserver/nightly.py #, fuzzy msgid "attempting bare ssh connection to test deploy key:" msgstr "forsøker naken SSH-tilkobling for å teste utrullingsnøkkel:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "kan ikke åpne '%s': %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "Finner ikke AppID for {path}." + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1855,6 +2194,10 @@ msgstr "kloner {url}" msgid "command to execute, either 'init' or 'update'" msgstr "kommando å kjøre, enten 'init' eller 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, fuzzy @@ -1874,6 +2217,19 @@ msgstr[1] "konflikterende valgstrenger: %s" msgid "copying {apkfilename} into {path}" msgstr "kopierer {apkfilename} inn i {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1889,12 +2245,21 @@ msgstr "Behandler {apkfilename}" msgid "deployed build logs to '{path}'" msgstr "utrullet bygglogger til \"{path}\"" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest= er påkrevd for valg som %r" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1927,7 +2292,7 @@ msgstr "klarte ikke å rulle ut bygglogger til \"{path}\"" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, fuzzy msgid "fdroid [] [-h|--help|--version|]" msgstr "bruk: fdroid [-h|--help|--version] []" @@ -1952,6 +2317,10 @@ msgstr "tving feil til å bli advarsler, eller ignorer" msgid "git svn clone failed" msgstr "\"git svn clone\" mislyktes" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, fuzzy, python-format @@ -2029,7 +2398,7 @@ msgstr "ingen APK angitt" msgid "no such option: %s" msgstr "Inget slikt valg: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "ingen versjonsinfo funnet!" @@ -2118,6 +2487,11 @@ msgstr "overskriver eksisterende {path}" msgid "positional arguments" msgstr "Posisjonelle argumenter" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, fuzzy, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2128,11 +2502,19 @@ msgstr "nekt nedlasting via usikker HTTP-tilkobling (bruk HTTPS eller angi --no- msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "nekt nedlasting via usikker HTTP-tilkobling (bruk HTTPS eller angi --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, fuzzy, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd synkroniserer indekser {path} til {url} og sletter" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2168,6 +2550,10 @@ msgstr "hopper over kildetjæreball: {path}" msgid "srclibs missing name and/or @" msgstr "srclibs mangler navn og/eller @" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, fuzzy, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2203,7 +2589,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "utrygge tilganger for '{config_file}' (skal være 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "bruk: " @@ -2216,6 +2602,10 @@ msgstr "bruk: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "bruker Apache-libcloud for å synkronisere med {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2279,16 +2669,31 @@ msgstr "{appid}: {field} må være en '{type}', men er ikke et '{fieldtype}!'" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}: {field} må være en '{type}', men er ikke et '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} ikke terminert i {name}." +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" finnes ikke. Rett det i config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, fuzzy, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2304,11 +2709,21 @@ msgstr "{path} har feilaktig filsignatur \"{pattern}\", mulig Janus-utnyttelse." msgid "{path} is zero size!" msgstr "{path} er null størrelse." +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, fuzzy, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} slutter ikke med \"fdroid\", sjekk nettadressestien." +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} slutter ikke med \"fdroid\", sjekk nettadressestien." + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index a097c25d..d897ec44 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-07-02 20:41+0000\n" "Last-Translator: WaldiS \n" "Language-Team: Polish \n" @@ -16,6 +16,16 @@ msgstr "" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.2-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -24,6 +34,15 @@ msgstr "" "\n" "Klucz publiczny SSH do użycia jako klucz wdrażania:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Klucz publiczny SSH do użycia jako klucz wdrażania:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -38,6 +57,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" nie ma pasującego pliku metadanych!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' jest już zainstalowany na {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -53,11 +77,21 @@ msgstr "\"{path}\" zawiera najnowsze {name} ({version})" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" istnieje, ale s3cmd nie jest zainstalowany!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" nie jest akceptowanym formatem, zamień na: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" nie jest akceptowanym formatem, zamień na: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -109,6 +143,10 @@ msgstr "%s opcja nie przyjmuje wartości" msgid "'keypass' not found in config.py!" msgstr "'keypass' nie znaleziono w config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'Plik kluczy' nie został znaleziony w pliku config.py!" @@ -190,11 +228,11 @@ msgstr "/nie ma problemów" msgid "A URL is required as an argument!" msgstr "Adres URL jest wymagany jako argument!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Dodaj podpisy PGP za pomocą GnuPG dla pakietów w repozytorium" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Dodaj nową aplikację ze swojego kodu źródłowego" @@ -227,6 +265,19 @@ msgstr "Również odzwierciedla całą sekcję archiwów" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Ostrzeż także o problemach z formatowaniem, takich jak rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Nie znaleziono pakietu SDK Androida!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -287,7 +338,12 @@ msgstr "Oddział '{branch}' używany jako commit w kompilacji '{versionName}'" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Gałąź '{branch}' używana jako commit w srclib '{srclib}'" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Zbuduj pakiet ze źródła" @@ -344,6 +400,11 @@ msgstr "Nie można odczytać \"{path}\"!" msgid "Cannot resolve app id {appid}" msgstr "Nie można rozpoznać identyfikatora aplikacji {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Nie można odczytać \"{path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "Nie można używać jednocześnie opcji --list i --to" @@ -362,7 +423,7 @@ msgstr "Kategorie '%s' są nieprawidłowe" msgid "Categories are not set" msgstr "Kategorie nie są ustawione" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Sprawdź aktualizacje aplikacji" @@ -391,7 +452,7 @@ msgstr "Czysta aktualizacja - nie używa pamięci podręcznych, przetwarzaj pono msgid "Comma separated list of categories." msgstr "Rozdzielana przecinkami lista kategorii." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Polecenie '%s' nie rozpoznane.\n" @@ -400,11 +461,25 @@ msgstr "Polecenie '%s' nie rozpoznane.\n" msgid "Commit changes" msgstr "Zatwierdź zmiany" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "Nie można znaleźć '{command}' w twoim systemie" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Nie można znaleźć najnowszej wersji kodu" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Nie można znaleźć najnowszej wersji nazwy" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -414,6 +489,16 @@ msgstr "Nie można znaleźć pliku {path}, aby go usunąć" msgid "Could not open apk file for analysis" msgstr "Nie można otworzyć pliku APK do analizy" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Nie można znaleźć identyfikatora pakietu" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -489,6 +574,16 @@ msgstr "DEBUG_KEYSTORE nie jest ustawione lub wartość jest niepełna" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Usuń pliki APK i/lub OBB bez metadanych z repozytorium" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -513,6 +608,10 @@ msgstr "Opis ma listę (%s), ale nie jest wypunktowana (*) ani ponumerowana (#)" msgid "Description of length {length} is over the {limit} char limit" msgstr "Opis długości {length} przekracza limit {limit} char" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Nie wdrażaj nowych plików w repozytorium" @@ -547,7 +646,7 @@ msgstr "Nie odświeżaj repozytorium, przydatne podczas testowania kompilacji be msgid "Don't use rsync checksums" msgstr "Nie używaj sum kontrolnych rsync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Pobierz pełne mirrors małych repozytoriów" @@ -595,6 +694,11 @@ msgstr "BŁĄD: nieobsługiwany typ CI, mile widziane poprawki!" msgid "Empty build flag at {linedesc}" msgstr "Opróżnij flagę kompilacji na {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -610,14 +714,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Błąd podczas próby opublikowania dziennika: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Błąd podczas uzyskiwania adresu repo" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Wyciągnij podpisy z plików APK" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Błąd odczytu {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -679,6 +788,11 @@ msgstr "Pobrano buildserverid z VM: {buildserverid}" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "Pobrane podpisy dla '{apkfilename}' -> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -690,6 +804,11 @@ msgstr "Skończone" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Metody flattr donation należą do flagi FlattrID" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Metody flattr donation należą do flagi FlattrID" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Zakazane tagi HTML" @@ -703,11 +822,20 @@ msgstr "Wymuszaj budowanie wyłączonych aplikacji i działa niezależnie od pro msgid "Force halting build after {0} sec timeout!" msgstr "Wymuś zatrzymanie kompilacji po {0} upływie limitu czasu!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "Znaleziono \"{path}\" grafiki bez metadanych dla aplikacji \"{name}\"!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "Znaleziono nieprawidłowe pliki w argumentach" @@ -717,6 +845,11 @@ msgstr "Znaleziono nieprawidłowe pliki w argumentach" msgid "Found invalid versionCodes for some apps" msgstr "Znaleziono nieprawidłowe kody wersji dla niektórych aplikacji" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Znaleziono wiele certyfikatów do podpisywania w {path}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -740,6 +873,11 @@ msgstr "Nie znaleziono certyfikatów do podpisywania dla repozytorium." msgid "Found non-file at %s" msgstr "Znaleziono plik nieprzechowy na %s" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "kopiowanie {apkfilename} na {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -762,6 +900,11 @@ msgstr "Pobranie Git nie powiodło się" msgid "Git remote set-head failed" msgstr "Git remote set-head nie powiódł się" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git remote set-head nie powiódł się" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Resetowanie Git nie powiodło się" @@ -778,6 +921,25 @@ msgstr "Aktualizacja submodułu Git nie powiodła się" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS musi być używany z adresami URL Subversion!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Ignorowanie pakietu bez metadanych: " @@ -796,6 +958,18 @@ msgstr "Ignorowanie {ext} pliku w '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Dołącz pliki APK, które są podpisane przy użyciu wyłączonych algorytmów, takich jak MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Inicjowanie submodułów" @@ -804,21 +978,31 @@ msgstr "Inicjowanie submodułów" msgid "Install all signed applications available" msgstr "Zainstaluj wszystkie dostępne podpisane aplikacje" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Zainstaluj wbudowane pakiety na urządzeniach" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Instalowanie %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Instalowanie %s…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Instalowanie '{apkfilename}' na {dev}…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Instalowanie '{apkfilename}' na {dev}…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Wejdź w interakcje z repozytorium serwera HTTP" @@ -883,6 +1067,21 @@ msgstr "Niepoprawna nazwa pakietu {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Nieprawidłowe przekierowanie do nie-HTTPS: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Przeczytaj wszystkie pliki metadanych i zakończ" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -898,11 +1097,19 @@ msgstr "Podpis JAR nie mógł zweryfikować: {path}" msgid "JAR signature verified: {path}" msgstr "Podpis JAR potwierdzony: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Nie znaleziono Java JDK! Zainstaluj w standardowej lokalizacji lub ustaw ścieżki java!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Jarsigner Java nie został znaleziony! Zainstaluj w standardowej lokalizacji lub ustaw ścieżki java (java_paths)!" @@ -920,6 +1127,11 @@ msgstr "Magazyn kluczy do podpisywania klucza:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "Ostatnio używany commit '{commit}' wygląda jak tag, ale tryb sprawdzania aktualizacji to '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Metody darowizny Liberapay należą do flagi LiberapayID" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Metody darowizny Liberapay należą do flagi LiberapayID" @@ -944,6 +1156,10 @@ msgstr "Nieprawidłowo repozytorium mirrors." msgid "Malformed serverwebroot line:" msgstr "Nieprawidłowy wiersz serverwebroot:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Brakujący katalog wyjściowy" @@ -983,6 +1199,11 @@ msgid "No git submodules available" msgstr "Brak dostępnych submodułów git" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Nie można znaleźć projektu android ani kivy. Podaj --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Nie znaleziono informacji." @@ -1011,7 +1232,7 @@ msgstr "Żaden podpisany apk nie jest dostępny dla %s" msgid "No signed output directory - nothing to do" msgstr "Brak podpisanego katalogu wyjściowego - nic nie można zrobić" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "Nie znaleziono certyfikatów do podpisu w {path}" @@ -1031,6 +1252,10 @@ msgstr "Brak takiego kodu wersji {versionCode} dla aplikacji {appid}" msgid "No unsigned directory - nothing to do" msgstr "Brak katalogu bez podpisu - nic nie można zrobić" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Nie ma nic do roboty" @@ -1063,7 +1288,7 @@ msgstr "Nazwa pakietu OBB nie jest zgodna z obsługiwanym pakietem APK:" msgid "Old APK signature failed to verify: {path}" msgstr "Stary podpis APK nie udało się zweryfikować: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Stara, przestarzała nazwa dla systemu fdroid" @@ -1080,6 +1305,11 @@ msgstr "Wydrukuj tylko różnice ze Sklepem Play" msgid "Only process apps with auto-updates" msgstr "Przetwarzaj tylko aplikacje z automatycznymi aktualizacjami" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Metody flattr donation należą do flagi FlattrID" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1089,6 +1319,16 @@ msgstr "Opcje" msgid "Output JSON report to file named after APK." msgstr "Wyjście raportu JSON do pliku o nazwie po APK." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Całkowita licencja na projekt." @@ -1102,6 +1342,11 @@ msgstr "Zastąp ścieżkę dla plików APK repo (domyślnie: ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Przesłaniam pustą versionName w {apkfilename} z metadanych: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1195,11 +1440,11 @@ msgstr "Przesyłanie dziennika zmian binarnych do {url}" msgid "Pushing to {url}" msgstr "Naciśnij na {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Szybko uruchom nowe repozytorium" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Przeczytaj wszystkie pliki metadanych i zakończ" @@ -1258,7 +1503,7 @@ msgstr "Zmień rozmiar wszystkich ikon przekraczających maksymalny rozmiar piks msgid "Restrict output to warnings and errors" msgstr "Ogranicz wyjście do ostrzeżeń i błędów" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Przepisz wszystkie pliki metadanych" @@ -1297,7 +1542,11 @@ msgstr "Uruchomienie wget w {path}" msgid "Scan only the latest version of each package" msgstr "Skanuj tylko najnowszą wersję każdego pakietu" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Zeskanuj kod źródłowy pakietu" @@ -1322,12 +1571,16 @@ msgstr[2] "Skaner znalazł {} problemy" msgid "Set clock to that time using:" msgstr "Ustaw zegar na ten czas, używając:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Ustaw limit otwartych plików na {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Skonfiguruj aplikację na nocne repozytorium" @@ -1347,11 +1600,11 @@ msgstr "Skonfiguruj emulator, zainstaluj na nim plik APK i wykonaj skanowanie Dr msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Skonfiguruj emulator, zainstaluj na nim apk i wykonaj skanowanie drozer" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Podpisz i umieść paczki w repozytorium" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Zarejestruj indeksy utworzone przy użyciu update --nosign" @@ -1409,6 +1662,11 @@ msgstr "Wypluwaj jeszcze więcej informacji niż zwykle" msgid "Striping mystery signature from {apkfilename}" msgstr "Odrysowywanie tajemniczego podpisu od {apkfilename}" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Odrysowywanie tajemniczego podpisu od {apkfilename}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1467,6 +1725,10 @@ msgstr "Katalog główny katalogu local_copy_dir \"{path}\" nie istnieje!" msgid "There is a keyalias collision - publishing halted" msgstr "Istnieje kolizja keyalias - wstrzymano publikowanie" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1480,6 +1742,10 @@ msgstr "Aby użyć awsbucket, awssecretkey i awsaccesskeyid muszą być równie msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCM jest ustawione, ale wygląda na to, że checkupdates nie zostało jeszcze uruchomione" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "Skróty adresów URL nie powinny być używane" @@ -1493,12 +1759,21 @@ msgstr "Tytuł adresu URL to tylko adres URL, użyj nawiasów kwadratowych: [URL msgid "URL {url} in Description: {error}" msgstr "Adres URL {url} w opisie {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Nieprawidłowy tag licencji \"%s\"! Używaj tylko tagów z https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "Nieoczekiwany tekst w tej samej linii co {field} w {linedesc}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Znaleziono nieznany wyjątek!" @@ -1518,6 +1793,11 @@ msgstr "Nieznany format metadanych: %s" msgid "Unknown metadata format: {path}" msgstr "Nieznany format metadanych: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Nieznany format metadanych: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "Nieznana wersja programu aapt może powodować problemy: " @@ -1596,19 +1876,29 @@ msgstr "Niewykorzystane extlib o %s" msgid "Unused file at %s" msgstr "Plik UNUSED, o %s" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "Plik UNUSED, o %s" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "Plik UNUSED, o %s" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "Aktualizacja Check Name jest ustawiona na znany identyfikator aplikacji - można go usunąć" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Zaktualizuj informacje o repozytorium dla nowych pakietów" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Zaktualizuj dziennik przezroczystości binarnej dla adresu URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Zaktualizuj statystyki repozytorium" @@ -1631,6 +1921,16 @@ msgstr "UpdateCheckData musi używać adresu URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData nie jest prawidłowym adresem URL: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Czytanie {apkfilename} z pamięci podręcznej" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1666,6 +1966,14 @@ msgstr "Użyj daty z apk zamiast bieżącego czasu dla nowo dodanych plików apk msgid "Using \"{path}\" for configuring s3cmd." msgstr "Użyj \"{path}\" do konfiguracji s3cmd." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Korzystanie z jarsignera Java nie jest zalecane do weryfikacji plików APK! Użyj apksigner" @@ -1685,7 +1993,7 @@ msgstr "Korzystanie z istniejącego magazynu kluczy \"{path}\"" msgid "Using s3cmd to sync with: {url}" msgstr "Użyj s3cmd do synchronizacji z: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Prawidłowe polecenia to:" @@ -1693,7 +2001,7 @@ msgstr "Prawidłowe polecenia to:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Zweryfikuj lokalnie kopiowaną pamięć podręczną zamiast pobierać ponownie." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Sprawdź integralność pobranych pakietów" @@ -1701,7 +2009,12 @@ msgstr "Sprawdź integralność pobranych pakietów" msgid "Verifying index signature:" msgstr "Weryfikowanie podpisu indeksu:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Ostrzegaj o możliwych błędach metadanych" @@ -1709,6 +2022,10 @@ msgstr "Ostrzegaj o możliwych błędach metadanych" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Po skonfigurowaniu dla indeksów podpisanych utwórz na tym etapie tylko niepodpisane indeksy" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Distiguished Name' używana podczas generowania kluczy" @@ -1720,6 +2037,10 @@ msgstr "X.509 'Distinguished Name' używana podczas generowania kluczy" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "Możesz użyć ANDROID_HOME, aby ustawić ścieżkę do SDK, tj .:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1742,6 +2063,10 @@ msgstr "niejednoznaczna opcja: %(option)s może dopasować %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "niejednoznaczna opcja: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId w postaci APPID" @@ -1763,16 +2088,30 @@ msgstr "applicationId z opcjonalnym versionCode w postaci APPID [:VERCODE]" msgid "argument \"-\" with mode %r" msgstr "argument \"-\" w trybie %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "próbując odsłoniętego połączenia ssh, aby przetestować klucz wdrożenia:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "próbując odsłoniętego połączenia ssh, aby przetestować klucz wdrożenia:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "nie można otworzyć '%s':%s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "Nie można znaleźć załącznika dla {path}!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1797,6 +2136,10 @@ msgstr "klonowanie {url}" msgid "command to execute, either 'init' or 'update'" msgstr "polecenie do wykonania, 'init' lub 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1816,6 +2159,19 @@ msgstr[2] "sprzeczne ciągi opcji: %s" msgid "copying {apkfilename} into {path}" msgstr "kopiowanie {apkfilename} na {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1831,12 +2187,21 @@ msgstr "usuwanie: repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "wdrożone dzienniki kompilacji do '{path}'" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest = jest wymagany dla opcji takich jak %r" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1870,7 +2235,7 @@ msgstr "nie udało się wdrożyć dzienników kompilacji do '{path}'" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1891,6 +2256,10 @@ msgstr "wymuszaj błędy metadanych (domyślnie), aby były ostrzeżeniami lub a msgid "git svn clone failed" msgstr "klon git svn nie powiódł się" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1968,7 +2337,7 @@ msgstr "nie dostarczono pakietu APK" msgid "no such option: %s" msgstr "brak takiej opcji: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "nie znaleziono informacji o wersji!" @@ -2056,6 +2425,11 @@ msgstr "nadpisanie istniejącego {path}" msgid "positional arguments" msgstr "argumenty pozycyjne" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2066,11 +2440,19 @@ msgstr "odmów pobierania przez niezabezpieczone połączenie HTTP (użyj HTTPS msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "odmów pobierania przez niezabezpieczone połączenie http (użyj https lub określ --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd zsynchronizuj indeksy {path} do {url} i usuń" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2103,6 +2485,10 @@ msgstr "pomijanie archiwum źródłowego: {path}" msgid "srclibs missing name and/or @" msgstr "brak nazwy srclibs i/lub @" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2138,7 +2524,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "niebezpieczne uprawnienia na '{config_file}' (powinno być 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "stosowanie: " @@ -2151,6 +2537,10 @@ msgstr "użycie: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "używając Apache libcloud do zsynchronizowania z {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2215,16 +2605,31 @@ msgstr "{appid}: {field} musi być '{type}', ale to jest '{fieldtype}!'" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}: {field} musi być '{type}', ale to jest '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} nie została zakończona w {name}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" nie istnieje! Popraw go w config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2240,11 +2645,21 @@ msgstr "{path} ma zły podpis pliku \"{pattern}\", możliwe wykorzystanie Janusa msgid "{path} is zero size!" msgstr "{path} ma zerowy rozmiar!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} nie kończy się na 'fdroid', sprawdź ścieżkę URL!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} nie kończy się na 'fdroid', sprawdź ścieżkę URL!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index df151aed..ed984f9b 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-01 09:00+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Portuguese (Brazil) \n" @@ -18,6 +18,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -26,6 +36,15 @@ msgstr "" "\n" "Chave pública SSH para ser usada como chave de implantar:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Chave pública SSH para ser usada como chave de implantar:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -40,6 +59,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" não tem arquivo de metadados correspondente!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' já está instalado no {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -55,11 +79,21 @@ msgstr "\"{path}\" contém {name} ({version}) recente" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe, mas s3cmd não está instalado!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -110,6 +144,10 @@ msgstr "opção %s não leva um valor" msgid "'keypass' not found in config.py!" msgstr "'keypass' não foi encontrada em config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore' não encontrada em config.py!" @@ -191,11 +229,11 @@ msgstr "está faltando o /issues" msgid "A URL is required as an argument!" msgstr "Uma URL é necessária como um argumento!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Adicione assinaturas PGP usando GnuPG para os pacotes no repositório" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Adicione um novo aplicativo a partir do seu código fonte" @@ -228,6 +266,19 @@ msgstr "Também espelhar o arquivo completo da seção" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Também avisar sobre problemas de formatação, como rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Nenhum 'Android SDK' foi encontrado!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -288,7 +339,12 @@ msgstr "Filial '{branch} 1' usada como commit no build '{versionName} 2'" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Ramificação '{branch}' usada como commit em srclib '{srclib}'" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Compilar um pacote a partir do código fonte" @@ -344,6 +400,11 @@ msgstr "Impossível ler \"{path}\"!" msgid "Cannot resolve app id {appid}" msgstr "Impossível resolver o ID de Aplicativo '{appid}'" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Impossível ler \"{path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "Não é possível usar --list e --to ao mesmo tempo" @@ -362,7 +423,7 @@ msgstr "Categorias '%s' não são válidas" msgid "Categories are not set" msgstr "As categorias não estão definidas" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Verifique se existem atualizações para os aplicativos" @@ -391,7 +452,7 @@ msgstr "Atualização limpa - não utiliza o cache, reprocessa todos os APKs" msgid "Comma separated list of categories." msgstr "Lista de categorias separadas por vírgula." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Comando '%s' não é reconhecido\n" @@ -400,11 +461,25 @@ msgstr "Comando '%s' não é reconhecido\n" msgid "Commit changes" msgstr "Enviar mudanças" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "Impossível encontrar '{command}' em seu sistema" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Impossível encontrar o código da versão mais recente" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Impossível encontrar o nome da versão mais recente" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -414,6 +489,16 @@ msgstr "Impossível encontrar {path} para removê-lo" msgid "Could not open apk file for analysis" msgstr "Impossível abrir o arquivo de APK para analisá-lo" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Impossível encontrar o ID do pacote" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -489,6 +574,16 @@ msgstr "DEBUG_KEYSTORE não está definido ou o valor está incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Apagar os APKs e/ou OBBs sem metadados do repositório" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -513,6 +608,10 @@ msgstr "Descrição tem uma lista (%s), mas não é com marcadores (*) nem numer msgid "Description of length {length} is over the {limit} char limit" msgstr "A descrição de tamanho {length} está acima do limite de {limit} caracteres" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Não implemente os novos arquivos no repositório" @@ -547,7 +646,7 @@ msgstr "Não atualizar o repositório; útil quando testando uma compilação se msgid "Don't use rsync checksums" msgstr "Não usar as somas de verificação (checksums) do rsync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Faça o download de espelhos completos de pequenos repositórios" @@ -595,6 +694,11 @@ msgstr "ERRO: tipo de IC não suportado, correções bem-vindas!" msgid "Empty build flag at {linedesc}" msgstr "Bandeira de construção vazia no {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -610,14 +714,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Erro ao tentar publicar o registro: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Erro ao obter o endereço do repositório" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Extrair assinaturas de APKs" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Falha ao ler {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -679,6 +788,11 @@ msgstr "ID do servidor de compilação buscado na Máquina Virtual: {buildserver msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "As assinaturas buscadas para '{apkfilename}' -> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -690,6 +804,11 @@ msgstr "Acabado" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Métodos de doação Flattr pertencem ao sinalizador FlattrID" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Métodos de doação Flattr pertencem ao sinalizador FlattrID" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Tags HTML proibidas" @@ -703,11 +822,20 @@ msgstr "Forçar a compilação de aplicativos desativados e continuar independen msgid "Force halting build after {0} sec timeout!" msgstr "Forçar a parada da compilação após tempo limite de {0} segundos!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "Foi encontrado o gráfico \"{path}\" sem metadados para o aplicativo \"{name}\"!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "Encontrou aplicativos inválidos em argumentos" @@ -717,6 +845,11 @@ msgstr "Encontrou aplicativos inválidos em argumentos" msgid "Found invalid versionCodes for some apps" msgstr "Encontrado versões de códigos inválidas para alguns aplicativos" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Encontrado vários certificados de assinatura em {path}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -740,6 +873,11 @@ msgstr "Não encontrado os certificados de assinatura para o repositório." msgid "Found non-file at %s" msgstr "Arquivo não encontrado em %s" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "copiando {apkfilename} para {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -762,6 +900,11 @@ msgstr "Falha no 'fetch' do Git" msgid "Git remote set-head failed" msgstr "Falha ao indicar o 'head' do Git remoto" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Falha ao indicar o 'head' do Git remoto" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Falha no 'reset' do Git" @@ -778,6 +921,25 @@ msgstr "Falha na atualização do submódulo Git" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS deve ser usado com URLs do Subversion(SVN)!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Ignorando o pacote sem metadados: " @@ -796,6 +958,18 @@ msgstr "Ignorando arquivo tipo {ext} em '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Inclua APKs assinados com algoritmos desativados, como o MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Inicializando submódulos" @@ -804,21 +978,31 @@ msgstr "Inicializando submódulos" msgid "Install all signed applications available" msgstr "Instalar todos os aplicativos assinados disponíveis" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Instalar pacotes prontos nos dispositivos" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Instalando %s …" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Instalando %s …" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Instalando '{apkfilename}' em {dev} …" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Instalando '{apkfilename}' em {dev} …" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interagir com o servidor HTTP do repositório" @@ -883,6 +1067,21 @@ msgstr "Nome do pacote inválido {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Redirecionamento inválido para não HTTPS: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Ler todos os arquivos de metadados e sair" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -898,11 +1097,19 @@ msgstr "A assinatura JAR falhou ao verificar: {path}" msgid "JAR signature verified: {path}" msgstr "Assinatura do JAR verificada: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Java JDK não encontrado! Instale no local padrão ou defina java_paths!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Java jarsigner não encontrado! Instale no local padrão ou defina java_paths!" @@ -920,6 +1127,11 @@ msgstr "Armazenamento de chaves de assinatura:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "O último commit usado '{commit}' parece com uma tag, mas o Update Check Mode é '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Métodos de doação Liberapay pertencem à bandeira LiberapayID" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Métodos de doação Liberapay pertencem à bandeira LiberapayID" @@ -944,6 +1156,10 @@ msgstr "Espelhos de repositórios malformados." msgid "Malformed serverwebroot line:" msgstr "Linha mal-formada do 'serverwebroot':" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Diretório de saída ausente" @@ -983,6 +1199,11 @@ msgid "No git submodules available" msgstr "Nenhum Submódulo Git disponível" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Nenhum projeto android ou kivy foi encontrado. Especifique --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Nenhuma informação encontrada." @@ -1011,7 +1232,7 @@ msgstr "Não há APK assinado disponível para %s" msgid "No signed output directory - nothing to do" msgstr "Nenhum diretório de saída assinado - nada a fazer" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "Nenhum certificado de assinatura encontrado em {path}" @@ -1031,6 +1252,10 @@ msgstr "Nenhum tal versionCode {versionCode} para o aplicativo {appid}" msgid "No unsigned directory - nothing to do" msgstr "Nenhum diretório não assinado - nada a fazer" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Nada para fazer" @@ -1063,7 +1288,7 @@ msgstr "O nome do pacote do OBB não corresponde a um APK suportado:" msgid "Old APK signature failed to verify: {path}" msgstr "Falha na assinatura do antigo APK ao verificar: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Nome antigo e obsoleto para o implante fdroid" @@ -1080,6 +1305,11 @@ msgstr "Apenas mostrar diferenças com a Play Store" msgid "Only process apps with auto-updates" msgstr "Processar apenas aplicativos com atualizações automáticas" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Métodos de doação Flattr pertencem ao sinalizador FlattrID" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1089,6 +1319,16 @@ msgstr "Opções" msgid "Output JSON report to file named after APK." msgstr "Exporte a saída do relatório JSON para um nome de arquivo após APK." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Licença geral do projeto." @@ -1102,6 +1342,11 @@ msgstr "Substituir o caminho para os APKs do repositório (padrão: ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Substituindo versionName em branco em {apkfilename} dos metadados: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1195,11 +1440,11 @@ msgstr "Atualizar o log de transparência de um binário para {url}" msgid "Pushing to {url}" msgstr "Empurrando para {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Rapidamente comece um novo repositório" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Ler todos os arquivos de metadados e sair" @@ -1258,7 +1503,7 @@ msgstr "Redimensionar todos os ícones que excedam o tamanho máximo de pixels e msgid "Restrict output to warnings and errors" msgstr "Restringir a saída a erros e avisos" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Reescrever todos os arquivos de metadados" @@ -1297,7 +1542,11 @@ msgstr "Executando o 'wget' em {path}" msgid "Scan only the latest version of each package" msgstr "Escanear apenas a versão mais recente de cada pacote" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Escanear o código fonte de um pacote" @@ -1321,12 +1570,16 @@ msgstr[1] "O Scanner encontrou {} problemas" msgid "Set clock to that time using:" msgstr "Ajuste o relógio para esse horário usando:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Defina o limite de arquivos abertos para {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Configurar uma compilação de aplicativo para um repositório de compilação todas-as-noites" @@ -1346,11 +1599,11 @@ msgstr "Configurar um emulador, instalar o apk nele e escanear com o Drozer" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Configurar um emulador, instalar o apk nele e escanear com o drozer" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Assine e coloque pacotes no repositório" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Assinar os índices criados usando update --nosign" @@ -1408,6 +1661,11 @@ msgstr "Mostrar ainda mais informações que o normal" msgid "Striping mystery signature from {apkfilename}" msgstr "Assinatura misteriosa de striping de {apkfilename}" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Assinatura misteriosa de striping de {apkfilename}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1466,6 +1724,10 @@ msgstr "O diretório raiz para local_copy_dir \"{path}\" não existe!" msgid "There is a keyalias collision - publishing halted" msgstr "Há uma colisão do keyalias - publicação parada" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1479,6 +1741,10 @@ msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCM é definido, mas parece que checkupdates ainda não foi executado" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "Encurtadores de URL não devem ser usados" @@ -1492,12 +1758,21 @@ msgstr "O título do URL é apenas o URL, use parênteses: [URL]" msgid "URL {url} in Description: {error}" msgstr "Há o URL {url} na descrição: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Etiqueta de licença inválida \"%s\"! Use apenas tags de https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "Texto inesperado na mesma linha como {field} em {linedesc}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Exceção desconhecida encontrada!" @@ -1517,6 +1792,11 @@ msgstr "Formato de metadados desconhecido: %s" msgid "Unknown metadata format: {path}" msgstr "Formato de metadados desconhecido: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Formato de metadados desconhecido: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "Versão desconhecida do aapt, pode causar problemas: " @@ -1595,19 +1875,29 @@ msgstr "Extlib não utilizado em %s" msgid "Unused file at %s" msgstr "Arquivo não utilizado em %s" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "Arquivo não utilizado em %s" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "Arquivo não utilizado em %s" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Atualize as informações do repositório para novos pacotes" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Atualizar o log de transparência de um binário para um URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Atualizar as estatísticas do repositório" @@ -1630,6 +1920,16 @@ msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Lendo {apkfilename} do cache" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1665,6 +1965,14 @@ msgstr "Usar a data do apk ao invés do horário atual para APKs recentemente ad msgid "Using \"{path}\" for configuring s3cmd." msgstr "Usando \"{path}\" para configurar s3cmd." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Usando o jarsigner de Java, não recomendado para verificar APKs! Use apksigner" @@ -1684,7 +1992,7 @@ msgstr "Utilizando armazenamento de chave existente \"{path}\"" msgid "Using s3cmd to sync with: {url}" msgstr "Usando s3cmd para sincronizar com: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Os comandos válidos são:" @@ -1692,7 +2000,7 @@ msgstr "Os comandos válidos são:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Verifique a cópia em cache local em vez de redescarregando." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Verifique a integridade dos pacotes baixados" @@ -1700,7 +2008,12 @@ msgstr "Verifique a integridade dos pacotes baixados" msgid "Verifying index signature:" msgstr "Verificar o índice de assinatura:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avisar sobre possíveis erros de metadados" @@ -1708,6 +2021,10 @@ msgstr "Avisar sobre possíveis erros de metadados" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Quando configurado para índices assinados, crie apenas índices não assinados nesta etapa" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Distiguished Name' usado ao gerar as chaves" @@ -1719,6 +2036,10 @@ msgstr "X.509 'Distiguished Name' usado na geração de chaves" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "Você pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou seja:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1741,6 +2062,10 @@ msgstr "opção ambígua: %(option)s poderia corresponder %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "opção ambígua: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId, na forma APPID" @@ -1762,16 +2087,30 @@ msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" msgid "argument \"-\" with mode %r" msgstr "argumento \"-\" com o modo %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "não dá pra abrir '%s': %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "Não é possível encontrar um appid para {path} 1!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1796,6 +2135,10 @@ msgstr "clonagem {url}" msgid "command to execute, either 'init' or 'update'" msgstr "comando para executar, seja 'init' ou 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1814,6 +2157,19 @@ msgstr[1] "opções conflitantes nas strings: %s" msgid "copying {apkfilename} into {path}" msgstr "copiando {apkfilename} para {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1829,12 +2185,21 @@ msgstr "apagando: repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "logs de compilação implantados para '{path}'" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest = é necessário para opções como %r" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1867,7 +2232,7 @@ msgstr "falha na implantação de logs de compilação para '{path}'" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1888,6 +2253,10 @@ msgstr "Forçar os erros de metadados (padrão) para serem avisos, ou para serem msgid "git svn clone failed" msgstr "git svn clone falhou" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1965,7 +2334,7 @@ msgstr "nenhum APK fornecido" msgid "no such option: %s" msgstr "não tem tal opção: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "não há informações de versão encontrada!" @@ -2053,6 +2422,11 @@ msgstr "sobrescrevendo {path} existente" msgid "positional arguments" msgstr "argumentos posicionais" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2063,11 +2437,19 @@ msgstr "Recuse o download inseguro via conexão HTTP (use HTTPS ou especifique - msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "Recuse o download insegura via conexão http (use https ou especifique --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sincroniza índices {path} para {url} e exclui" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2100,6 +2482,10 @@ msgstr "ignorando o tarball de origem: {path}" msgid "srclibs missing name and/or @" msgstr "Nome 'srclibs' ausente e/ou '@'" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2135,7 +2521,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "permissões inseguras em '{config_file}' (deveria ser 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "uso: " @@ -2148,6 +2534,10 @@ msgstr "uso: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "usando o Apache libcloud para sincronizar com {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2211,16 +2601,31 @@ msgstr "O {appid}: {field} deve ser um '{type}', porém é um '{fieldtype}!'" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "O {appid}: {field} deve ser um '{type}', porém é um '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} não foi terminado em {name}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" não existe! Corrija-o no config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2236,11 +2641,21 @@ msgstr "{path} tem uma má assinatura de arquivo \"{pattern}\", um exploração msgid "{path} is zero size!" msgstr "{path} tem um tamanho de zero!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2253,6 +2668,16 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} compilação foi bem sucedida" msgstr[1] "{} compilações foram bem sucedidas" +#, fuzzy +#~ msgid "Add PGP signatures for packages in repo using GnuPG" +#~ msgstr "Adicione assinaturas gpg para os pacotes no repositório" + +#~ msgid "Add gpg signatures for packages in repo" +#~ msgstr "Adicione assinaturas gpg para os pacotes no repositório" + +#~ msgid "Clean update - don't uses caches, reprocess all apks" +#~ msgstr "Atualização limpa - não usa cache, reprocessa todos os APKs" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "Perguntar interativamente sobre elementos que precisam de atualização." @@ -2265,16 +2690,6 @@ msgstr[1] "{} compilações foram bem sucedidas" #~ msgid "Specify editor to use in interactive mode. Default is {path}" #~ msgstr "Especifique o editor a ser usado no modo interativo. O padrão é {path}" -#, fuzzy -#~ msgid "Add PGP signatures for packages in repo using GnuPG" -#~ msgstr "Adicione assinaturas gpg para os pacotes no repositório" - -#~ msgid "Add gpg signatures for packages in repo" -#~ msgstr "Adicione assinaturas gpg para os pacotes no repositório" - -#~ msgid "Clean update - don't uses caches, reprocess all apks" -#~ msgstr "Atualização limpa - não usa cache, reprocessa todos os APKs" - #~ msgid "app-id in the form APPID" #~ msgstr "app-id na forma APPID" diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index 84187861..3fc24a50 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-01 09:00+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Portuguese (Portugal) \n" @@ -19,6 +19,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -27,6 +37,15 @@ msgstr "" "\n" "Chave pública SSH para ser usada como chave de implantar:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Chave pública SSH para ser usada como chave de implantar:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -41,6 +60,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" não tem ficheiro de metadados correspondente!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' já está instalado no {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -56,11 +80,21 @@ msgstr "\"{path}\" contém {name} ({version}) recente" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe, mas s3cmd não está instalado!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -111,6 +145,10 @@ msgstr "opção %s não leva um valor" msgid "'keypass' not found in config.py!" msgstr "'keypass' não foi encontrada em config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore' não encontrada em config.py!" @@ -192,11 +230,11 @@ msgstr "está faltando o /issues" msgid "A URL is required as an argument!" msgstr "Uma URL é necessária como um argumento!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Adicione assinaturas PGP usando GnuPG para os pacotes no repositório" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Adicionar nova aplicação através do código fonte" @@ -229,6 +267,19 @@ msgstr "Também espelhar o ficheiro completo da secção" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Também avisar sobre problemas de formatação, como rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Android SDK não encontrado!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -289,7 +340,12 @@ msgstr "Filial '{branch} 1' usada como commit no build '{versionName} 2'" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Ramificação '{branch}' usado como commit em srclib '{srclib}'" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Construir pacote através da fonte" @@ -345,6 +401,11 @@ msgstr "Não é possível ler \"{path}\"!" msgid "Cannot resolve app id {appid}" msgstr "Não é possível resolver o ID da app {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Não é possível ler \"{path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "Não é possível usar --list e --to ao mesmo tempo" @@ -363,7 +424,7 @@ msgstr "As categorias '%s' não são válidas" msgid "Categories are not set" msgstr "As categorias não são definidas" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Verificação de actualizações das aplicações" @@ -392,7 +453,7 @@ msgstr "Atualização limpa - não usa cache, reprocessa todos os APKs" msgid "Comma separated list of categories." msgstr "Lista de categorias separadas por vírgula." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Comando '%s' não reconhecido.\n" @@ -401,11 +462,25 @@ msgstr "Comando '%s' não reconhecido.\n" msgid "Commit changes" msgstr "Enviar mudanças" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "Não foi possível encontrar '{command}' no seu sistema" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Não foi possível encontrar o código de versão mais recente" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Não foi possível encontrar o nome da versão mais recente" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -415,6 +490,16 @@ msgstr "Não foi possível localizar {path} para removê-lo" msgid "Could not open apk file for analysis" msgstr "Não foi possível abrir ficheiro apk para análise" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Não foi possível encontrar o ID do pacote" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -490,6 +575,16 @@ msgstr "DEBUG_KEYSTORE não está definido ou o valor está incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Eliminação de APK'S e/ou OBBs que não contêm metadados do repositório" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -514,6 +609,10 @@ msgstr "A descrição tem a lista (%s), mas não tem marcadores (*), nem é nume msgid "Description of length {length} is over the {limit} char limit" msgstr "A descrição de comprimento {length} é sobre o limite de char {limit}" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Não implante os novos ficheiros no repositório" @@ -548,7 +647,7 @@ msgstr "Não atualizar o repositório; útil quando testando uma compilação se msgid "Don't use rsync checksums" msgstr "Não usar as somas de verificação (checksums) do rsync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Descarregar espelhos completos de repos pequenos" @@ -596,6 +695,11 @@ msgstr "ERRO: tipo de CI sem suporte, patches são bem-vindos!" msgid "Empty build flag at {linedesc}" msgstr "Sinalizador de compilação vazio em {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -611,14 +715,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Erro ao tentar publicar o log: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Erro ao obter o endereço do repo" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Extrato de assinaturas de APKs" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Falha de leitura {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -680,6 +789,11 @@ msgstr "Buildserverid obtido da VM: {buildserverid}" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "Assinaturas obtidas para '{apkfilename}'-> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -691,6 +805,11 @@ msgstr "Terminado" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Os métodos de doação do Flattr pertencem no sinalizador FlattrID" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Os métodos de doação do Flattr pertencem no sinalizador FlattrID" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Tags HTML proibidos" @@ -704,11 +823,20 @@ msgstr "Forçar a compilação de apps desativados e continuar independentemente msgid "Force halting build after {0} sec timeout!" msgstr "Forçar suspender a construção depois de esperar {0} segundos!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "\"{path}\" gráfico encontrado sem metadados para o app \"{name}\"!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "appids inválidos encontrados em argumentos" @@ -718,6 +846,11 @@ msgstr "appids inválidos encontrados em argumentos" msgid "Found invalid versionCodes for some apps" msgstr "versionCodes inválidos encontrados para algumas apps" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Vários certificados de assinatura encontrados em {path}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -741,6 +874,11 @@ msgstr "Nenhum certificado de assinatura para repositório encontrado." msgid "Found non-file at %s" msgstr "Não-ficheiro encontrado em %s" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "copiando {apkfilename} para {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -763,6 +901,11 @@ msgstr "Git fetch falhou" msgid "Git remote set-head failed" msgstr "Git remote set-head falhou" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git remote set-head falhou" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Git reset falhou" @@ -779,6 +922,25 @@ msgstr "Git submodule update falhou" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS deve ser usado nos URLs do Subversion!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Ignorando o pacote sem metadados: " @@ -797,6 +959,18 @@ msgstr "Ignorando o ficheiro {ext} em '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Incluir APKs assinados com algoritmos desabilitados como MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Inicializando submódulos" @@ -805,21 +979,31 @@ msgstr "Inicializando submódulos" msgid "Install all signed applications available" msgstr "Instalar todas as aplicações assinadas disponíveis" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Instalação dos pacotes compilados no aparelho" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Instalando %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Instalando %s…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Instalando '{apkfilename}' em {dev}…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Instalando '{apkfilename}' em {dev}…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interacção com o repositório do servidor HTTP" @@ -884,6 +1068,21 @@ msgstr "Nome do pacote inválido {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Redirecionamento inválido para não-HTTPS: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Ler todos os ficheiros de metadados e sair" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -899,11 +1098,19 @@ msgstr "A assinatura JAR falhou a verificação: {path}" msgid "JAR signature verified: {path}" msgstr "Assinatura JAR verificada: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "O Java JDK não foi encontrado! Instalar no local predefinido ou definir java_paths!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Java jarsigner não encontrado! Instale no local predefinido ou define java_paths!" @@ -921,6 +1128,11 @@ msgstr "Armazenamento de chaves de assinatura:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o modo de verificação de atualização é '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Os métodos de doação de Liberapay pertencem na bandeira de LiberapayID" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Os métodos de doação de Liberapay pertencem na bandeira de LiberapayID" @@ -945,6 +1157,10 @@ msgstr "Espelhos de repositório malformados." msgid "Malformed serverwebroot line:" msgstr "Linha de serverwebroot malformada:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Falta diretório de saída" @@ -984,6 +1200,11 @@ msgid "No git submodules available" msgstr "Não há submódulos git disponíveis" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Nenhum projeto Android ou Kivy poderia ser encontrado. Especificar --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Nenhuma informação encontrada." @@ -1012,7 +1233,7 @@ msgstr "Nenhum apk assinado disponível para %s" msgid "No signed output directory - nothing to do" msgstr "Nenhum diretório de saída assinado - nada a fazer" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "Nenhum certificado de assinatura encontrado em {path}" @@ -1032,6 +1253,10 @@ msgstr "Nenhum versionCode {versionCode} para o app {appid}" msgid "No unsigned directory - nothing to do" msgstr "Nenhum diretório não assinado - nada a fazer" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Nada para fazer" @@ -1064,7 +1289,7 @@ msgstr "O packagename do OBB não corresponde a um APK suportado:" msgid "Old APK signature failed to verify: {path}" msgstr "A assinatura antiga do APK não pôde ser verificada: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Nome velho e obsoleto para implantar fdroid" @@ -1081,6 +1306,11 @@ msgstr "Apenas mostrar diferenças com a Play Store" msgid "Only process apps with auto-updates" msgstr "Processar apenas apps com atualizações automáticas" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Os métodos de doação do Flattr pertencem no sinalizador FlattrID" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1090,6 +1320,16 @@ msgstr "Opções" msgid "Output JSON report to file named after APK." msgstr "Saída de relatório JSON para ficheiro nomeado após APK." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Licença geral do projeto." @@ -1103,6 +1343,11 @@ msgstr "Substituir o caminho para os APKs do repositório (predefinição: ./rep msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Substituindo versionName em branco em {apkfilename} dos metadados: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1196,11 +1441,11 @@ msgstr "A submeter o registo de transparência de binário para {url}" msgid "Pushing to {url}" msgstr "A submeter para {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Criar rapidamente um novo repositório" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Ler todos os ficheiros de metadados e sair" @@ -1259,7 +1504,7 @@ msgstr "Redimensionar todos os ícones que excedam o tamanho máximo de pixels e msgid "Restrict output to warnings and errors" msgstr "Restringir a saída a erros e avisos" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Regravar todos os ficheiros de metadados" @@ -1298,7 +1543,11 @@ msgstr "Executando o wget em {path}" msgid "Scan only the latest version of each package" msgstr "Escanear apenas a versão mais recente de cada pacote" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Analisar o código fonte de um pacote" @@ -1322,12 +1571,16 @@ msgstr[1] "Scanner encontrou {} problemas" msgid "Set clock to that time using:" msgstr "Configurar o relógio para esse tempo usando:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Definir o limite de ficheiros abertos para {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Configurar uma compilação de app para um repositório de compilação noturno" @@ -1347,11 +1600,11 @@ msgstr "Configure um emulador, instale o APK nele e execute um scan do Drozer" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Configure um emulador, instale o apk nele e execute um scan do drozer" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Assinar e pôr os pacotes no repositório" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Assinar os índices criados com o uso de update --nosign" @@ -1409,6 +1662,11 @@ msgstr "Mostrar ainda mais informações que o normal" msgid "Striping mystery signature from {apkfilename}" msgstr "Esvaziar assinatura misteriosa de {apkfilename}" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Esvaziar assinatura misteriosa de {apkfilename}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1467,6 +1725,10 @@ msgstr "O diretório raiz para local_copy_dir \"{path}\" não existe!" msgid "There is a keyalias collision - publishing halted" msgstr "Há uma colisão do keyalias - publicação parada" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1480,6 +1742,10 @@ msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCM é definido, mas parece que checkupdates ainda não foi executado" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "Encurtadores de URL não devem ser usados" @@ -1493,12 +1759,21 @@ msgstr "O título do URL é apenas o URL, use parênteses: [URL]" msgid "URL {url} in Description: {error}" msgstr "Há o URL {url} na descrição: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Etiqueta de licença \"%s\" inválida! Use apenas etiquetas de https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "Texto inesperado na mesma linha como {field} em {linedesc}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Exceção desconhecida!" @@ -1518,6 +1793,11 @@ msgstr "Formato de metadados desconhecido: %s" msgid "Unknown metadata format: {path}" msgstr "Formato de metadados desconhecido: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Formato de metadados desconhecido: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "Versão desconhecida do aapt, pode causar problemas: " @@ -1596,19 +1876,29 @@ msgstr "Extlib não utilizado em %s" msgid "Unused file at %s" msgstr "Ficheiro não utilizado em %s" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "Ficheiro não utilizado em %s" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "Ficheiro não utilizado em %s" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Atualizar a informação do repositório para novos pacotes" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Atualizar o registo de transparência de binário para um URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Atualizar as estatísticas do repositório" @@ -1631,6 +1921,16 @@ msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Lendo {apkfilename} do cache" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1666,6 +1966,14 @@ msgstr "Use a data do apk em vez do tempo atual para apks recém-adicionados" msgid "Using \"{path}\" for configuring s3cmd." msgstr "Usando \"{path}\" para configurar s3cmd." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Usando o jarsigner de Java, não recomendado para verificar APKs! Use apksigner" @@ -1685,7 +1993,7 @@ msgstr "Utilizando armazenamento de chave existente \"{path}\"" msgid "Using s3cmd to sync with: {url}" msgstr "Usando s3cmd para sincronizar com: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Comandos válidos:" @@ -1693,7 +2001,7 @@ msgstr "Comandos válidos:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Verifique a cópia em cache local em vez de redescarregando." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Verifique a integridade dos pacotes descarregados" @@ -1701,7 +2009,12 @@ msgstr "Verifique a integridade dos pacotes descarregados" msgid "Verifying index signature:" msgstr "Verificar o índice de assinatura:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avisar sobre possíveis erros de metadados" @@ -1709,6 +2022,10 @@ msgstr "Avisar sobre possíveis erros de metadados" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Quando configurado para índices assinados, crie apenas índices não assinados nesta etapa" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Distiguished Name' usado ao gerar as chaves" @@ -1720,6 +2037,10 @@ msgstr "X.509 'Distiguished Name' usado na geração de chaves" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "Pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou seja:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1742,6 +2063,10 @@ msgstr "opção ambígua: %(option)s poderia corresponder %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "opção ambígua: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId, na forma APPID" @@ -1763,16 +2088,30 @@ msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" msgid "argument \"-\" with mode %r" msgstr "argumento \"-\" com o modo %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "não dá pra abrir '%s': %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "Não é possível encontrar um appid para {path} 1!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1797,6 +2136,10 @@ msgstr "clonagem {url}" msgid "command to execute, either 'init' or 'update'" msgstr "comando para executar, seja 'init' ou 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1815,6 +2158,19 @@ msgstr[1] "cadeias de opções conflitantes: %s" msgid "copying {apkfilename} into {path}" msgstr "copiando {apkfilename} para {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1830,12 +2186,21 @@ msgstr "apagando: repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "logs de compilação implantados para '{path}'" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest = é necessário para opções como %r" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1868,7 +2233,7 @@ msgstr "falha na implantação de logs de compilação para '{path}'" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1889,6 +2254,10 @@ msgstr "Forçar os erros de metadados (padrão) para serem avisos, ou para serem msgid "git svn clone failed" msgstr "git svn clone falhou" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1966,7 +2335,7 @@ msgstr "nenhum APK fornecido" msgid "no such option: %s" msgstr "não tem tal opção: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "não há informações de versão encontrada!" @@ -2054,6 +2423,11 @@ msgstr "sobrescrevendo {path} existente" msgid "positional arguments" msgstr "argumentos posicionais" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2064,11 +2438,19 @@ msgstr "Recusado o download via conexão HTTP insegura (use HTTPS ou especifique msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "Recusado o download via conexão http insegura (use https ou especifique --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sincroniza índices {path} para {url} e exclui" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2101,6 +2483,10 @@ msgstr "ignorando o tarball de origem: {path}" msgid "srclibs missing name and/or @" msgstr "Nome 'srclibs' ausente e/ou '@'" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2136,7 +2522,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "permissões inseguras em '{config_file}' (deveria ser 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "utilização: " @@ -2149,6 +2535,10 @@ msgstr "utilização: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "usando o Apache libcloud para sincronizar com {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2212,16 +2602,31 @@ msgstr "{appid}: {field} deve ser um '{type}', mas é um '{fieldtype}!'" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}: {field} deve ser um '{type}', mas é um '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} não foi terminado em {name}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" não existe! Corrija-o no config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2237,11 +2642,21 @@ msgstr "{path} tem uma má assinatura de ficheiro \"{pattern}\", um exploração msgid "{path} is zero size!" msgstr "{path} tem um tamanho de zero!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 71a8dc60..3a6e3072 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-07-08 21:41+0000\n" "Last-Translator: gardenapple \n" "Language-Team: Russian \n" @@ -20,6 +20,16 @@ msgstr "" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.2-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -28,6 +38,15 @@ msgstr "" "\n" "Использовать публичный SSH ключ как ключ для развертывания (Deploy Key):" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Использовать публичный SSH ключ как ключ для развертывания (Deploy Key):" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -42,6 +61,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "У \"%s/\" нет соответствующего файла метаданных!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' уже установлен на {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -57,11 +81,21 @@ msgstr "в пути \"{path}\" последние имя {name} и версия msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "путь \"{path}\" существует, но s3cmd клиент не установлен!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "формат пути \"{path}\" не принимается, преобразуйте в другой доступный: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "формат пути \"{path}\" не принимается, преобразуйте в другой доступный: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -113,6 +147,10 @@ msgstr "%s параметр не принимает значений" msgid "'keypass' not found in config.py!" msgstr "В config.py нет переменной 'keypass'!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "В config.py нет переменной 'keystore'!" @@ -194,11 +232,11 @@ msgstr "Не хватает /issues" msgid "A URL is required as an argument!" msgstr "В качестве аргумента нужен URL-адрес!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Добавить PGP подписи для пакетов в репозитории с помощью GnuPG" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Добавить новое приложение из исходного кода" @@ -231,6 +269,19 @@ msgstr "Дополнительно создать полную копию раз msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Дополнительно предупреждать о нарушениях форматирования (вроде rewritemeta -l)" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Android SDK не обнаружена!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -291,7 +342,12 @@ msgstr "Ветка '{branch}' вошла в билд '{versionName}' как ко msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Ветка '{branch}' вошла в библиотеку '{srclib}' как коммит" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Собрать пакет из исходников" @@ -348,6 +404,11 @@ msgstr "Неправильно указан путь \"{path}\"!" msgid "Cannot resolve app id {appid}" msgstr "Не удалось разобрать app id {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Неправильно указан путь \"{path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "Опции --list и --to нельзя использовать одновременно" @@ -366,7 +427,7 @@ msgstr "Неправильные категории: '%s'" msgid "Categories are not set" msgstr "Категории не выбраны" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Проверить обновления для приложений" @@ -395,7 +456,7 @@ msgstr "Очистка с обновлением: не использовать msgid "Comma separated list of categories." msgstr "Категории перечислены через запятую." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Команда '%s' не распознана.\n" @@ -404,11 +465,25 @@ msgstr "Команда '%s' не распознана.\n" msgid "Commit changes" msgstr "Сохранить изменения (commit)" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "В вашей системе недоступна команда '{command}'" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Не удалось найти внутреннюю версию приложения (versionCode)" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Не удалось найти публичную версию приложения (versionName)" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -418,6 +493,16 @@ msgstr "Указанный для удаления {path} не найден" msgid "Could not open apk file for analysis" msgstr "Не удалось открыть и проанализировать файл APK" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Не удалось найти package ID" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -493,6 +578,16 @@ msgstr "Переменная DEBUG_KEYSTORE пустая или заполнен msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Удалить из репозитория APK и/или OBB файлы без метаданных" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -517,6 +612,10 @@ msgstr "В описании есть неразмеченный список (%s msgid "Description of length {length} is over the {limit} char limit" msgstr "Описание {length} превышает лимит по количеству знаков {limit}" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Не помещать новые файлы сразу в репозиторий" @@ -551,7 +650,7 @@ msgstr "Не обновлять репозиторий. Упрощает тес msgid "Don't use rsync checksums" msgstr "Не использовать контрольные суммы rsync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Полностью загружать зеркала для небольших репозиториев" @@ -599,6 +698,11 @@ msgstr "ОШИБКА: этот тип CI не поддерживается, на msgid "Empty build flag at {linedesc}" msgstr "У флага сборки в {linedesc} нет значения" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -614,14 +718,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Ошибка во время публикации лога: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Ошибка при получении адреса репозитория" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Извлечь подписи из APK файлов" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Не удалось распознать {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -683,6 +792,11 @@ msgstr "Сервер для сборки скопирован с ВМ {buildserv msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "Получены подписи для '{apkfilename}' -> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -694,6 +808,11 @@ msgstr "Готово" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Способы пожертвования с помощью Flattr определяются флагом FlattrID" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Способы пожертвования с помощью Flattr определяются флагом FlattrID" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Запрещенные теги HTML" @@ -707,11 +826,20 @@ msgstr "Принудительно собирать заблокированны msgid "Force halting build after {0} sec timeout!" msgstr "Принудительно останавливать сборку, если тайм-аут больше {0} секунд!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "В \"{path}\" обнаружены изображения без метаданных для приложения \"{name}\"!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "В аргументах обнаружены неправильные appid" @@ -721,6 +849,11 @@ msgstr "В аргументах обнаружены неправильные ap msgid "Found invalid versionCodes for some apps" msgstr "Для некоторых приложений обнаружены неправильные номера внутренней версии (versionCode)" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "В {path} обнаружено несколько сертификатов для подписывания" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -744,6 +877,11 @@ msgstr "Сертификат для подписывания для этого msgid "Found non-file at %s" msgstr "Это не похоже на файл: %s" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "копирование {apkfilename} в {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -766,6 +904,11 @@ msgstr "Не удалось получить данные из репозито msgid "Git remote set-head failed" msgstr "Не удалось настроить HEAD для удаленного репозитория (git remote set-head)" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Не удалось настроить HEAD для удаленного репозитория (git remote set-head)" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Не удалось отменить изменения (git reset)" @@ -782,6 +925,25 @@ msgstr "Не удалось обновить модули Git (git submodules up msgid "HTTPS must be used with Subversion URLs!" msgstr "URL-адреса для Subversion должны начинаться с HTTPS!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Пропустить пакеты без метаданных: " @@ -800,6 +962,18 @@ msgstr "Пропустить файл {ext} в '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Разрешить APK, подписанные без использования алгоритмов идентичности (MD5 и т.п.)" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Подключение модулей" @@ -808,21 +982,31 @@ msgstr "Подключение модулей" msgid "Install all signed applications available" msgstr "Установить все доступные подписанные приложения" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Установить собранные пакеты на устройства" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Установка %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Установка %s…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Установка '{apkfilename}' на устройство {dev}…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Установка '{apkfilename}' на устройство {dev}…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Взаимодействовать с HTTP сервером репозитория" @@ -887,6 +1071,21 @@ msgstr "Неверное имя (package name) {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Неверное перенаправление (не HTTPS): {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Прочесть все метаданные и выйти" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -902,11 +1101,19 @@ msgstr "Не удаётся проверить подпись JAR: {path}" msgid "JAR signature verified: {path}" msgstr "Подпись JAR прошла проверку: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Не обнаружена Java JDK! Установите её по стандартному пути или настройте переменную java_paths!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Java jarsigner не обнаружен! Установите по стандартному пути или настройте переменную java_paths!" @@ -924,6 +1131,11 @@ msgstr "Хранилище ключа для подписывания:→\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "Последний наложенный коммит '{commit}' похож на метку (tag), но режим проверки обновлений (Update Check Mode) — '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Способ пожертвования Liberapay определяется с помощью флага LiberapayID" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Способ пожертвования Liberapay определяется с помощью флага LiberapayID" @@ -948,6 +1160,10 @@ msgstr "Неверные адреса зеркал для репозитория msgid "Malformed serverwebroot line:" msgstr "Неверный путь serverwebroot:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Директории для хранения выводных данных не существует" @@ -987,6 +1203,11 @@ msgid "No git submodules available" msgstr "Модулей Git не обнаружено" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Неверный путь к проекту Android или Kivy. Указать его в опции --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Информация о репозитории неверна." @@ -1015,7 +1236,7 @@ msgstr "Для %s нет подписанного apk" msgid "No signed output directory - nothing to do" msgstr "Директории с данными для подписывания не найдено. До новых встреч" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "В {path} не обнаружены сертификаты для подписывания" @@ -1035,6 +1256,10 @@ msgstr "Внутренней версии (versionCode) с номером {versi msgid "No unsigned directory - nothing to do" msgstr "Директории с неподписанными данными не существует. До новых встреч" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "До новых встреч" @@ -1067,7 +1292,7 @@ msgstr "Указанный в OBB файле packagename не соответст msgid "Old APK signature failed to verify: {path}" msgstr "Не удалось проверить прежнюю подпись APK: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Старое название для fdroid deploy" @@ -1084,6 +1309,11 @@ msgstr "Отобразить только приложения, версия к msgid "Only process apps with auto-updates" msgstr "Запустить проверку только для приложений с автоматическим обновлением" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Способы пожертвования с помощью Flattr определяются флагом FlattrID" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1093,6 +1323,16 @@ msgstr "Параметры" msgid "Output JSON report to file named after APK." msgstr "Вывод отчёта в формате JSON под именем файла APK." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Основная лицензия проекта." @@ -1106,6 +1346,11 @@ msgstr "Переопределить путь к APK файлам репозит msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Заменить пустое значение versionName в {apkfilename} значением из метаданных: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1199,11 +1444,11 @@ msgstr "Публикация лога прозрачности кода в {url} msgid "Pushing to {url}" msgstr "Публикация в {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Создать новый репозиторий (укороченная процедура)" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Прочесть все метаданные и выйти" @@ -1262,7 +1507,7 @@ msgstr "Изменить размер всех иконок, превышающ msgid "Restrict output to warnings and errors" msgstr "Показывать в выводе только предупреждения и ошибки" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Перезаписать все метаданные" @@ -1301,7 +1546,11 @@ msgstr "Выполняется wget в {path}" msgid "Scan only the latest version of each package" msgstr "Сканировать только самую свежую версию каждого пакета" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Сканировать исходный код пакета" @@ -1326,12 +1575,16 @@ msgstr[2] "Сканирование обнаружило {} ошибок" msgid "Set clock to that time using:" msgstr "Настроить системное время с помощью:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Настроить ограничение для количества одновременно открытых файлов: {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Настроить ежедневную сборку приложения (nightly build)" @@ -1351,11 +1604,11 @@ msgstr "Настроить эмулятор, установить в него AP msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Настроить эмулятор, установить в него APK и запустить сканирование Drozer" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Подписать пакеты и поместить в репозиторий" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Подписать индексы, созданные с флагом \"update --nosign\"" @@ -1413,6 +1666,11 @@ msgstr "Писать очень подробные логи" msgid "Striping mystery signature from {apkfilename}" msgstr "Удаление неизвестной подписи {apkfilename}" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Удаление неизвестной подписи {apkfilename}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1471,6 +1729,10 @@ msgstr "Корневой директории для local_copy_dir \"{path}\" msgid "There is a keyalias collision - publishing halted" msgstr "Есть расхождения в алиасах ключей для подписывания. Публикация остановлена" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1484,6 +1746,10 @@ msgstr "Необходимо определить переменные awsbucket msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "Режим проверки обновлений (Update Check Mode) выбран, но проверка еще ни разу не выполнялась" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "URL-адреса сокращать нельзя" @@ -1497,12 +1763,21 @@ msgstr "Текст URL-адреса должен быть заключен в с msgid "URL {url} in Description: {error}" msgstr "URL-адрес {url} в описании приложения: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Неверная метка лицензии: \"%s\". Используйте только метки, перечисленные в https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "Лишний текст в той же строчке, что и {field} в {linedesc}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Произошла неизвестная ошибка!" @@ -1522,6 +1797,11 @@ msgstr "Неизвестный формат метаданных: %s" msgid "Unknown metadata format: {path}" msgstr "Неизвестный формат метаданных: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Неизвестный формат метаданных: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "Неизвестная версия AAPT. Это может сломать сборку: " @@ -1600,19 +1880,29 @@ msgstr "Внешняя библиотека не используется %s" msgid "Unused file at %s" msgstr "Файл не ипользуется %s" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "Файл не ипользуется %s" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "Файл не ипользуется %s" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "Имя приложения для проверки обновлений (Update Check Name) соответствует app id. Это поле можно удалить" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Обновить информацию о репозитории для новых пакетов" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Обновить лог степени прозрачности (binary transparency log) для URL-адреса" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Обновить статистику репозитория" @@ -1635,6 +1925,16 @@ msgstr "URL-адрес в UpdateCheckData должен начинаться с H msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData содержит некорректный URL-адрес: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Чтение {apkfilename} из кеша" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1670,6 +1970,14 @@ msgstr "Использовать время date из APK вместо теку msgid "Using \"{path}\" for configuring s3cmd." msgstr "Для конфигурации s3cmd используется \"{path}\"." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Проверка APK с помощью Java jarsigner. Так делать не следует! Пользуйтесь для этого apksigner" @@ -1689,7 +1997,7 @@ msgstr "Используются ключи из \"{path}\"" msgid "Using s3cmd to sync with: {url}" msgstr "s3cmd синхронизация с: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Допустимые команды:" @@ -1697,7 +2005,7 @@ msgstr "Допустимые команды:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Сверяться с закешированной копией вместо того, чтобы загружать еще раз." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Проверить загруженные пакеты на повреждения" @@ -1705,7 +2013,12 @@ msgstr "Проверить загруженные пакеты на повреж msgid "Verifying index signature:" msgstr "Проверка подписи индекса:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Предупреждать о возможных ошибках в метаданных" @@ -1713,6 +2026,10 @@ msgstr "Предупреждать о возможных ошибках в ме msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Если в конфигурации сборки задано подписывать индексы, опция позволяет вместо этого создавать неподписанные индексы" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "При генерации ключей использовалось различимое имя (Distinguished Name) стандарта X.509" @@ -1724,6 +2041,10 @@ msgstr "При генерации ключей использовалось ра msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "Путь к SDK можно указать в переменной ANDROID_HOME:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1746,6 +2067,10 @@ msgstr "неоднозначный выбор: %(option)s совпадает с msgid "ambiguous option: %s (%s?)" msgstr "неоднозначный выбор: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId в виде APPID" @@ -1767,16 +2092,30 @@ msgstr "applicationId и внутренняя версия приложения msgid "argument \"-\" with mode %r" msgstr "аргумент \"-\" c режимом %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "попытка установить SSH соединение для проверки ключа развертывания:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "попытка установить SSH соединение для проверки ключа развертывания:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "не получается открыть '%s': %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "По указанному пути {path} не удалось найти appid!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1801,6 +2140,10 @@ msgstr "клонирование {url}" msgid "command to execute, either 'init' or 'update'" msgstr "выполняемая команда, 'init' или 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1820,6 +2163,19 @@ msgstr[2] "конфликтующих строк: %s" msgid "copying {apkfilename} into {path}" msgstr "копирование {apkfilename} в {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1835,12 +2191,21 @@ msgstr "удаление: repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "логи сборки загружены в '{path}'" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "для опции %r необходимо указать dest=" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1874,7 +2239,7 @@ msgstr "не получается загрузить логи сборки в '{ msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] <команда> [<аргументы>]" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [<команда>] [-h|--help|--version|<аргументы>]" @@ -1895,6 +2260,10 @@ msgstr "принудительно обрабатывать ошибки как msgid "git svn clone failed" msgstr "команда git svn clone не выполнена" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1972,7 +2341,7 @@ msgstr "APK файл не указан" msgid "no such option: %s" msgstr "такой опции нет: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "определить версию не удалось!" @@ -2060,6 +2429,11 @@ msgstr "перезапись существующего пути {path}" msgid "positional arguments" msgstr "позиционные аргументы" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2070,11 +2444,19 @@ msgstr "использовать для загрузки небезопасно msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "использовать для загрузки небезопасное HTTP-соединение не стоит (пользуйтесь HTTPS или укажите --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd синхронизировать индексы из {path} в {url} и удалить их" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2107,6 +2489,10 @@ msgstr "пропустить для архива с исходниками: {pat msgid "srclibs missing name and/or @" msgstr "библиотеки srclib: имя отсутствует или не содержит символа @" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2142,7 +2528,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "небезопасные права доступа к файлу '{config_file}' (должны быть 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "использование: " @@ -2155,6 +2541,10 @@ msgstr "использование: fdroid [-h|--help|--version] <команда msgid "using Apache libcloud to sync with {url}" msgstr "Аpache libcloud: синхронизация с {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2219,16 +2609,31 @@ msgstr "{appid}: {field} должно быть '{type}', а не '{fieldtype}'!" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}: {field} должно быть '{type}', а не '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "Неверно заполненное поле {field} в {name}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name}: неверный путь \"{path}\"! Поправьте его в config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2244,11 +2649,21 @@ msgstr "{path}: неверная подпись \"{pattern}\". Выглядит msgid "{path} is zero size!" msgstr "размер {path} равен нулю!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "Адрес {url} должен заканчиваться на \"fdroid\". Проверьте URL-адрес!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "Адрес {url} должен заканчиваться на \"fdroid\". Проверьте URL-адрес!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/sk/LC_MESSAGES/fdroidserver.po b/locale/sk/LC_MESSAGES/fdroidserver.po index ff887d67..7a6bcc26 100644 --- a/locale/sk/LC_MESSAGES/fdroidserver.po +++ b/locale/sk/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -15,12 +15,28 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -33,6 +49,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -48,11 +69,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -104,6 +135,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -185,11 +220,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -222,6 +257,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -282,7 +329,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "" @@ -339,6 +391,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -357,7 +414,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -386,7 +443,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -395,11 +452,23 @@ msgstr "" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -409,6 +478,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -484,6 +562,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -508,6 +596,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -542,7 +634,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -588,6 +680,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -601,14 +698,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -670,6 +772,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -681,6 +788,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -694,11 +805,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -708,6 +828,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -731,6 +856,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -753,6 +883,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -769,6 +904,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -787,6 +941,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -795,21 +961,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -874,6 +1050,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -889,11 +1080,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -911,6 +1110,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -935,6 +1138,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -974,6 +1181,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1002,7 +1213,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1022,6 +1233,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1054,7 +1269,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1071,6 +1286,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1080,6 +1299,16 @@ msgstr "" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1093,6 +1322,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1186,11 +1420,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1249,7 +1483,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1288,7 +1522,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1313,12 +1551,16 @@ msgstr[2] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1338,11 +1580,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1400,6 +1642,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1458,6 +1705,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1471,6 +1722,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1484,12 +1739,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1509,6 +1772,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1587,19 +1855,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1622,6 +1900,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1657,6 +1945,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1676,7 +1972,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1684,7 +1980,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1692,7 +1988,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1700,6 +2001,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1711,6 +2016,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1733,6 +2042,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1754,16 +2067,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1788,6 +2114,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1807,6 +2137,19 @@ msgstr[2] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1822,12 +2165,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1861,7 +2213,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1882,6 +2234,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1959,7 +2315,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2047,6 +2403,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2057,11 +2418,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2094,6 +2463,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2129,7 +2502,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2142,6 +2515,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2206,16 +2583,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2231,11 +2623,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/sq/LC_MESSAGES/fdroidserver.po b/locale/sq/LC_MESSAGES/fdroidserver.po index 2d3ce666..ef73e829 100644 --- a/locale/sq/LC_MESSAGES/fdroidserver.po +++ b/locale/sq/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-04-26 19:11+0000\n" "Last-Translator: Besnik Bleta \n" "Language-Team: Albanian \n" @@ -16,6 +16,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.0.2-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -24,6 +34,15 @@ msgstr "" "\n" "Kyç SSH Publik për t’u përdorur si Kyç Sendërtimesh:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Kyç SSH Publik për t’u përdorur si Kyç Sendërtimesh:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -38,6 +57,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" s’ka kartel tejtëdhënash me përputhje!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' është tashmë e instaluar në {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -53,11 +77,21 @@ msgstr "\"{path}\" përmban {name} të freskët ({version})" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" ekziston, por s3cmd s’është e instaluar!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" s’është në një format të pranuar, shndërrojeni në: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" s’është në një format të pranuar, shndërrojeni në: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -108,6 +142,10 @@ msgstr "Mundësia %s s’merr ndonjë vlerë" msgid "'keypass' not found in config.py!" msgstr "S’u gjet 'keypass' në config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "S’u gjet 'keystore' në config.py!" @@ -189,11 +227,11 @@ msgstr "/issues mungon" msgid "A URL is required as an argument!" msgstr "Lypset një URL si argument!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Shtoni për paketa në depo nënshkrime PGP duke përdorur GnuPG-në" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Shtoni një aplikacion të ri që prej kodit të tij burim" @@ -226,6 +264,19 @@ msgstr "Pasqyro gjithashtu pjesën e arkivit të plotë" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Sinjalizo gjithashtu mbi probleme formatimi, bie fjala, rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "S’u gjet SDK Android!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -286,7 +337,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Montoni një paketë nga burimi" @@ -342,6 +398,11 @@ msgstr "S’lexohet dot \"${path}\"!" msgid "Cannot resolve app id {appid}" msgstr "S’ftillohet dot ID aplikacioni {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "S’lexohet dot \"${path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "S’mund të përdoret --list dhe --to në të njëjtën kohë" @@ -360,7 +421,7 @@ msgstr "Kategoritë '%s' s’janë të vlefshme" msgid "Categories are not set" msgstr "S’janë ujdisur kategori" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Kontrollo për përditësime aplikacionesh" @@ -389,7 +450,7 @@ msgstr "Përditësim na e para - nuk përdor fshehtina, ripërpuno krejt APK-të msgid "Comma separated list of categories." msgstr "Listë kategorish ndarë me presje." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Urdhër '%s' jo i pranuar.\n" @@ -398,11 +459,25 @@ msgstr "Urdhër '%s' jo i pranuar.\n" msgid "Commit changes" msgstr "Depozito ndryshimet" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "Në sistemin tuaj s’u gjet '{command}'" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "S’ u gjet dot kod i versionit më të ri" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "S’ u gjet dot emër versioni më të ri" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -412,6 +487,16 @@ msgstr "S’u gjet dot {path} për ta hequr" msgid "Could not open apk file for analysis" msgstr "S’u hap dot kartela apk për analizim" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "S’u gjet dot ID pakete" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -487,6 +572,16 @@ msgstr "DEBUG_KEYSTORE s’është ujdisur ose vlera është e paplotë" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Fshi APK-ra dhe/ose OBB-ra pa tejtëdhëna prej depos" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -511,6 +606,10 @@ msgstr "Përshkrimi ka një listë (%s), por kjo s’është as me toptha (*), a msgid "Description of length {length} is over the {limit} char limit" msgstr "Përshkrimi me gjatësi {length} është mbi kufirin prej {limit} shenjash" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Mos i vendos kartelat e reja te depoja" @@ -545,7 +644,7 @@ msgstr "Mos rifresko depon, e dobishme kur testohet një montim pa lidhje intern msgid "Don't use rsync checksums" msgstr "Mos përdorni checksum-e rsync-u" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Shkarko pasqyra të plota deposh të vogla" @@ -593,6 +692,11 @@ msgstr "GABIM: lloj CI i pambuluar, arnimet janë të mirëpritura!" msgid "Empty build flag at {linedesc}" msgstr "Flamurkë e zbrazët montimi te {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -608,14 +712,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Gabim gjatë përpjekjes për botim regjistri: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Gabim teksa merrej adresë depoje" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Përfto nënshkrime prej APK-sh" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "S’u arrit të lexohej {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -677,6 +786,11 @@ msgstr "U soll buildserverid prej VM-je: {buildserverid}" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "U sollën nënshkrime për '{apkfilename}' -> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -688,6 +802,11 @@ msgstr "Përfundoi" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Metodat e dhurimit përmes Flattr-i i takojnë flamurkës FlattrID" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Metodat e dhurimit përmes Flattr-i i takojnë flamurkës FlattrID" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Etiketa HTML të ndaluara" @@ -701,11 +820,20 @@ msgstr "Detyro montim aplikacionesh të çaktivizuara, dhe vazhdon pavarësisht msgid "Force halting build after {0} sec timeout!" msgstr "Detyro ndaljen e montimit pas {0} sek. mbarimi kohe!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "U gjet grafik \"{path}\" pa tejtëdhëna për aplikacionin \"{name}\"!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "U gjetën appid-e të pavlefshëm te argumente" @@ -715,6 +843,11 @@ msgstr "U gjetën appid-e të pavlefshëm te argumente" msgid "Found invalid versionCodes for some apps" msgstr "U gjetën versionCodes të pavlefshëm për disa aplikacione" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "U gjetën dëshmi të shumta nënshkrimi te {path}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -738,6 +871,11 @@ msgstr "S’u gjetën dëshmi nënshkrimi për depon." msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "po kopjohet {apkfilename} te {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -760,6 +898,11 @@ msgstr "Veprimi “git fetch” dështoi" msgid "Git remote set-head failed" msgstr "Veprimi “git remote set-head” dështoi" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Veprimi “git remote set-head” dështoi" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Veprimi “git reset” dështoi" @@ -776,6 +919,25 @@ msgstr "Veprimi “git submodule update” dështoi" msgid "HTTPS must be used with Subversion URLs!" msgstr "Me URL Subversion duhet përdorur HTTPS!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Po shpërfillet paketë pa tejtëdhëna: " @@ -794,6 +956,18 @@ msgstr "Po shpërfillet kartelë {ext} te '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Përfshi APKra që janë nënshkruar me algoritme të çaktivizuar, bie fjala, me MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Po gatiten nënmodule" @@ -802,21 +976,31 @@ msgstr "Po gatiten nënmodule" msgid "Install all signed applications available" msgstr "Instalo krejt aplikacionet e nënshkruara që mundet" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Instalo në pajisje paketat montuara" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Po instalohet %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Po instalohet %s…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Po instalohet '{apkfilename}' në {dev}…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Po instalohet '{apkfilename}' në {dev}…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Ndërveproni me shërbyesin HTTP të depos" @@ -881,6 +1065,21 @@ msgstr "Emër i pavlefshëm pakete {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Ridrejtim i pavlefshëm te non-HTTPS: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Lexo krejt kartelat e tejtëdhënave dhe dil" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -896,11 +1095,19 @@ msgstr "Dështoi verifikimi i nënshkrimit JAR: {path}" msgid "JAR signature verified: {path}" msgstr "Nënshkrimi JAR u verifikua: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "S’u gjet Java JDK! Instalojeni në vendndodhje standarde ose caktoni java_paths!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "S’u gjet Java jarsigner! Instalojeni në vendndodhje standarde ose caktoni java_paths!" @@ -918,6 +1125,11 @@ msgstr "Depo kyçesh për kyç nënshkrimi:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "Parashtrimi '{commit}' i përdorur së fundi duket si etiketë, por si Mënyrë Kontrolli Përditësimesh është '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Metodat e dhurimit përmes Liberapay i takojnë flamurkës Liberapay" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Metodat e dhurimit përmes Liberapay i takojnë flamurkës Liberapay" @@ -942,6 +1154,10 @@ msgstr "Pasqyra depoje të keqformuara." msgid "Malformed serverwebroot line:" msgstr "Rresht serverwebroot i keqformuar:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Mungon drejtori përfundimesh" @@ -981,6 +1197,11 @@ msgid "No git submodules available" msgstr "S’ka “git submodules”" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "S’u gjet dot projekt android ose kivy. Të specifikohet --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "S’u gjetën të dhëna." @@ -1009,7 +1230,7 @@ msgstr "S’ka të gatshme apk të nënshkruara për %s" msgid "No signed output directory - nothing to do" msgstr "S’ka drejtori output-i të nënshkruar - s’ka ç’bëhet" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "S’u gjetën dëshmi nënshkrimi te {path}" @@ -1029,6 +1250,10 @@ msgstr "S’ka versionCode {versionCode} për aplikacionin {appid}" msgid "No unsigned directory - nothing to do" msgstr "S’ka drejtori të panënshkruar - s’ka ç’bëhet" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "S’ka ç’bëhet" @@ -1061,7 +1286,7 @@ msgstr "packagename i OBB-së nuk përputhet me ndonjë APK të mbuluar:" msgid "Old APK signature failed to verify: {path}" msgstr "S’u arrit të verifikohej nënshkrim i vjetër APK-je: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Emër i vjetër, i nxjerrë nga përdorimi për sendërtim fdroid" @@ -1078,6 +1303,11 @@ msgstr "Shtyp vetëm dallimet me Play Store-in" msgid "Only process apps with auto-updates" msgstr "Kryeje vetëm për aplikacione me vetëpërditësime" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Metodat e dhurimit përmes Flattr-i i takojnë flamurkës FlattrID" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1087,6 +1317,16 @@ msgstr "Mundësi" msgid "Output JSON report to file named after APK." msgstr "Hidhe raportin JSON te kartelë e emërtuar sipas APK-sh." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Licenca e përgjithshme e projektit." @@ -1100,6 +1340,11 @@ msgstr "Shteg anashkalimi për APK-ra depoje (parazgjedhje: ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Po anashkalohet versionName i zbrazët te {apkfilename} prej tejtëdhënash: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1193,11 +1438,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Filloni shpejt e shpejt një depo të re" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Lexo krejt kartelat e tejtëdhënave dhe dil" @@ -1256,7 +1501,7 @@ msgstr "Ripërmaso krejt ikonat që tejkalojnë madhësinë maksimum në piksel msgid "Restrict output to warnings and errors" msgstr "Kufizoje output-in në sinjalizime dhe gabime" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Rishkruaj krejt kartelat e tejtëdhënave" @@ -1295,7 +1540,11 @@ msgstr "Po xhirohet wget te {path}" msgid "Scan only the latest version of each package" msgstr "Skano vetëm versionin më të ri të çdo pakete" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Skanoni kodin burim të një pakete" @@ -1319,12 +1568,16 @@ msgstr[1] "Skaneri gjeti {} probleme" msgid "Set clock to that time using:" msgstr "Vëre sahatin në atë kohë duke përdorur:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Si kufi hapjeje kartele cakto {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Ujdisni një montim aplikacioni për një depo montimesh të përnatshme" @@ -1344,11 +1597,11 @@ msgstr "Ujdisni një emulues, instaloni në të APK-në dhe kryeni një skanim D msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Ujdisni një emulues, instaloni në të APK-në dhe kryeni një skanim Drozer" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Nënshkruani dhe vendosni paketa te depoja" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Tregues nënshkrimi të krijuar duke përdorur “update --nosign”" @@ -1406,6 +1659,11 @@ msgstr "U la të rrjedhë edhe më tepër informacion se sa normalisht" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Po shpërfillen të dhëna të ndenjura fshehtine për {apkfilename}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1464,6 +1722,10 @@ msgstr "Drejtoria rrënjë për local_copy_dir \"{path}\" s’ekziston!" msgid "There is a keyalias collision - publishing halted" msgstr "Ka një përplasje keyalias-i - botimi u ndal" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1477,6 +1739,10 @@ msgstr "Për të përdorur awsbucket, te config.py duhen ujdisur edhe awssecretk msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCM është ujdisur, por duket sikur checkupdates s’është xhiruar ende" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "S’duhen përdorur shkurtues URL-sh" @@ -1490,12 +1756,21 @@ msgstr "Titulli i URL-së është thjesht URL-ja, përdorni kllapa: [URL]" msgid "URL {url} in Description: {error}" msgstr "URL {url} te Përshkrim: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Etiketë e pavlefshme licence \"%s\"! Përdorni vetëm etiketa nga https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "Tekst i papritur në të njëjtin rresht me {field} te {linedesc}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "U gjet përjashtim i panjohur!" @@ -1515,6 +1790,11 @@ msgstr "Format i panjohur tejtëdhënash: %s" msgid "Unknown metadata format: {path}" msgstr "Format i panjohur tejtëdhënash: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Format i panjohur tejtëdhënash: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "Version i panjohur i aapt-së, mund të sjellë probleme: " @@ -1593,19 +1873,29 @@ msgstr "extlib i papërdorur te %s" msgid "Unused file at %s" msgstr "Kartelë e papërdorur te %s" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "Kartelë e papërdorur te %s" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "Kartelë e papërdorur te %s" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Përditësoni të dhëna depoje për paketa të reja" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Përditësoni regjistrin e transparencës së dyorit për një URL" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Përditëso statistikat e depos" @@ -1628,6 +1918,16 @@ msgstr "UpdateCheckData duhet të përdorë URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData s’është URL e vlefshme: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Po lexohet {apkfilename} prej fshehtine" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1663,6 +1963,14 @@ msgstr "Për APK-ra të shtuara rishtazi, përdor datë prej APK-je, në vend se msgid "Using \"{path}\" for configuring s3cmd." msgstr "Po përdoret \"{path}\" për formësim të s3cmd." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Po përdoret jarsigner Java, nuk rekomandohet për verifikim APK-sh! Përdorni apksigner" @@ -1682,7 +1990,7 @@ msgstr "Po përdoret depo ekzistuese kyçesh \"{path}\"" msgid "Using s3cmd to sync with: {url}" msgstr "Po përdoret s3cmd për njëkohësim me: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Urdhrat e vlefshëm janë:" @@ -1690,7 +1998,7 @@ msgstr "Urdhrat e vlefshëm janë:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Verifikoje ndaj një kopjeje të ruajtur lokalisht në fshehtinë, në vend se ta rishkarkosh." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Verifikoni integritetin e paketave të shkarkuara" @@ -1698,7 +2006,12 @@ msgstr "Verifikoni integritetin e paketave të shkarkuara" msgid "Verifying index signature:" msgstr "Po verifikohet nënshkrim treguesi:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Sinjalizo rreth gabimesh të mundshëm tejtëdhënash" @@ -1706,6 +2019,10 @@ msgstr "Sinjalizo rreth gabimesh të mundshëm tejtëdhënash" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Kur është formësuar për tregues të nënshkruar, në këtë fazë krijo vetëm tregues të panënshkruar" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1717,6 +2034,10 @@ msgstr "X.509 'Distinguished Name' i përdorur teksa prodhoheshin kyçe" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "Mund të përdorni ANDROID_HOME që të caktoni shtegun për te SDK-ja juaj, domethënë:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1739,6 +2060,10 @@ msgstr "mundësi e dykuptimtë: %(option)s mund të përputhej me %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "mundësi e dykuptimtë: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId në formën e APPID" @@ -1760,16 +2085,30 @@ msgstr "applicationId me versionCode opsional në formën APPID[:VERCODE]" msgid "argument \"-\" with mode %r" msgstr "argument \"-\" me mënyrën %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "po tentohet lidhje ssh e zhveshur, për të testuar kyç sendërtimesh:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "po tentohet lidhje ssh e zhveshur, për të testuar kyç sendërtimesh:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "s’hapet dot '%s': %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "S’gjendet dot një appid për {path}!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1794,6 +2133,10 @@ msgstr "po klonohet {url}" msgid "command to execute, either 'init' or 'update'" msgstr "urdhër për t’u ekzekutuar, ose 'init', ose 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1812,6 +2155,19 @@ msgstr[1] "vargje mundësish me përplasje: %s" msgid "copying {apkfilename} into {path}" msgstr "po kopjohet {apkfilename} te {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1827,12 +2183,21 @@ msgstr "po fshihet: repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "u vunë regjistra montimi te '{path}'" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest= është e domosdoshme për mundësi si %r" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1865,7 +2230,7 @@ msgstr "s’u arrit të hidhen regjistrat e montimeve te '{path}'" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1886,6 +2251,10 @@ msgstr "bëji gabimet e tejtëdhënave (parazgjedhje) të jenë sinjalizime, ose msgid "git svn clone failed" msgstr "veprimi “git svn clone” dështoi" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1963,7 +2332,7 @@ msgstr "s’u dha APK" msgid "no such option: %s" msgstr "s’ka mundësi të tillë: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "s’u gjetën të dhëna versioni!" @@ -2051,6 +2420,11 @@ msgstr "po mbishkruhet {path} ekzistues" msgid "positional arguments" msgstr "argumente pozicionalë" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2061,11 +2435,19 @@ msgstr "refuzo shkarkim përmes lidhjeje HTTP të pasigurt (përdorni HTTPS ose msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "mos pranon shkarkim përmes lidhjeje http të pasigurt (përdorni https ose specifikoni --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2098,6 +2480,10 @@ msgstr "po anashkalohet paketë tar burimi: {path}" msgid "srclibs missing name and/or @" msgstr "srclibs-it i mungon emër dhe/ose @" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2133,7 +2519,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "leje jo të parrezikshme mbi '{config_file}' (duhet të ishin 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "përdorimi: " @@ -2146,6 +2532,10 @@ msgstr "përdorimi: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "po përdoret Apache libcloud për njëkohësim me {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2209,16 +2599,31 @@ msgstr "{appid}: {field} duhet të jetë një '{type}', po është një '{fieldt msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}: {field} duhet të jetë një '{type}', por është një '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} e papërfunduar te {name}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" s’ekziston! Ndreqeni te config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2234,11 +2639,21 @@ msgstr "{path} ka \"{pattern}\" të gabuar nënshkrimi kartele, ka gjasa të jet msgid "{path} is zero size!" msgstr "{path} është me madhësi zero!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} s’përfundon me \"fdroid\", kontrolloni shtegun e URL-së!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} s’përfundon me \"fdroid\", kontrolloni shtegun e URL-së!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/sv/LC_MESSAGES/fdroidserver.po b/locale/sv/LC_MESSAGES/fdroidserver.po index 25e3c6c0..e24ac13a 100644 --- a/locale/sv/LC_MESSAGES/fdroidserver.po +++ b/locale/sv/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2018-10-14 14:43+0000\n" "Last-Translator: Jonatan Nyberg \n" "Language-Team: Swedish \n" @@ -17,12 +17,28 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.2.1\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -35,6 +51,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' är redan installerad på {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -50,11 +71,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -105,6 +136,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -186,11 +221,11 @@ msgstr "/issues saknas" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Lägg till en ny applikation från dess källkod" @@ -223,6 +258,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -283,7 +330,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Bygg ett paket från källa" @@ -339,6 +391,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -357,7 +414,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Kontrollera efter uppdateringar av appar" @@ -386,7 +443,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Kommandot '%s' känns inte igen.\n" @@ -395,11 +452,23 @@ msgstr "Kommandot '%s' känns inte igen.\n" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -409,6 +478,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -484,6 +562,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Ta bort APKs och/eller OBBs utan metadata från förråd" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -508,6 +596,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -542,7 +634,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -588,6 +680,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -601,14 +698,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -670,6 +772,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -681,6 +788,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -694,11 +805,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -708,6 +828,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -731,6 +856,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -753,6 +883,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -769,6 +904,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -787,6 +941,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -795,21 +961,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Installera byggda paket på enheter" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Interagera med förrådets HTTP-servern" @@ -874,6 +1050,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Läs alla metadatafiler och avsluta" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -889,11 +1080,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -911,6 +1110,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -935,6 +1138,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -974,6 +1181,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1002,7 +1213,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1022,6 +1233,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1054,7 +1269,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1071,6 +1286,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1080,6 +1299,16 @@ msgstr "Alternativ" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1093,6 +1322,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1186,11 +1420,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Starta snabbt ett nytt förråd" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Läs alla metadatafiler och avsluta" @@ -1249,7 +1483,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Skriv om alla metadatafiler" @@ -1288,7 +1522,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Skanna källkoden för ett paket" @@ -1312,12 +1550,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1337,11 +1579,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Signera och placera paket i förrådet" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1399,6 +1641,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1457,6 +1704,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1470,6 +1721,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1483,12 +1738,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Okänt undantag hittades!" @@ -1508,6 +1771,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1586,19 +1854,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Uppdatera förrådinformation för nya paket" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1621,6 +1899,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1656,6 +1944,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1675,7 +1971,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Giltiga kommandon är:" @@ -1683,7 +1979,7 @@ msgstr "Giltiga kommandon är:" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1691,7 +1987,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1699,6 +2000,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1710,6 +2015,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1732,6 +2041,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1753,16 +2066,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1787,6 +2113,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1805,6 +2135,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1820,12 +2163,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1858,7 +2210,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1879,6 +2231,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1956,7 +2312,7 @@ msgstr "" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "" @@ -2044,6 +2400,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2054,11 +2415,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2091,6 +2460,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2126,7 +2499,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "användning: " @@ -2139,6 +2512,10 @@ msgstr "användning: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2202,16 +2579,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2227,11 +2619,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index 84a6af0c..27722576 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-07-20 20:29+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" @@ -16,6 +16,16 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.2-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -24,6 +34,15 @@ msgstr "" "\n" "Dağıtım Anahtarı olarak kullanılacak SSH Açık Anahtar:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Dağıtım Anahtarı olarak kullanılacak SSH Açık Anahtar:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -38,6 +57,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" eşleşen üst veri dosyasına sahip değil!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' zaten {dev} üzerinde kurulu." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -53,11 +77,21 @@ msgstr "\"{path}\" en son {name} ({version}) içeriyor" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" var ancak s3cmd kurulu değil!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" kabul edilebilir bir biçim değil, şuna dönüştürün: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" kabul edilebilir bir biçim değil, şuna dönüştürün: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -108,6 +142,10 @@ msgstr "%s seçeneği bir değer almaz" msgid "'keypass' not found in config.py!" msgstr "'keypass' config.py içinde bulunamadı!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore' config.py içinde bulunamadı!" @@ -189,11 +227,11 @@ msgstr "/issues eksik" msgid "A URL is required as an argument!" msgstr "Bir URL, argüman olarak gereklidir!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Depodaki paketler için GnuPG ile PGP imzaları ekle" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Kaynak kodundan yeni bir uygulama ekle" @@ -226,6 +264,19 @@ msgstr "Tam arşiv bölümünü de yansıt" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Ayrıca biçimlendirme sorunları hakkında uyar, rewritemeta -l gibi" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Android SDK bulunamadı!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -286,7 +337,12 @@ msgstr "Dal '{branch}' inşa '{versionName}' içinde işleme olarak kullanıldı msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Srclib '{srclib}' içine işleme için dal '{branch}' kullanıldı" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Kaynaktan bir paket inşa et" @@ -342,6 +398,11 @@ msgstr "\"{path}\" okunamıyor!" msgid "Cannot resolve app id {appid}" msgstr "App id {appid} çözülemiyor" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "\"{path}\" okunamıyor!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "--list ve --to aynı anda kullanılamaz" @@ -360,7 +421,7 @@ msgstr "'%s' kategorileri geçersiz" msgid "Categories are not set" msgstr "Kategoriler ayarlı değil" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Uygulama güncellemelerini denetle" @@ -389,7 +450,7 @@ msgstr "Temiz güncelleme - önbellekleri kullanmaz, tüm APKları yeniden işle msgid "Comma separated list of categories." msgstr "Kategorilerin virgülle ayrılmış listesi." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Komut '%s' tanınmıyor.\n" @@ -398,11 +459,25 @@ msgstr "Komut '%s' tanınmıyor.\n" msgid "Commit changes" msgstr "Değişiklikleri işle" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "'{command}' sisteminizde bulunamadı" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Son sürüm kodu bulunamadı" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Son sürüm adı bulunamadı" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -412,6 +487,16 @@ msgstr "Kaldırmak için {path} bulunamadı" msgid "Could not open apk file for analysis" msgstr "İnceleme için apk dosyası açılamadı" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Paket ID bulunamadı" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -487,6 +572,16 @@ msgstr "DEBUG_KEYSTORE ayarlı değil veya değer eksik" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Depodan üst verisi olmayan APKları ve/veya OBBleri sil" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -511,6 +606,10 @@ msgstr "Açıklamanın bir listesi (%s) var fakat madde imli (*) veya numaralı( msgid "Description of length {length} is over the {limit} char limit" msgstr "{length} uzunluğundaki açıklama, {limit} karakter sınırının üstünde" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Yeni dosyaları repo'ya dağıtmayın" @@ -545,7 +644,7 @@ msgstr "Depoyu yenileme, bir inşa internet bağlantısı olmadan sınanırken y msgid "Don't use rsync checksums" msgstr "Rsync sağlama toplamlarını kullanma" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Küçük depoların tam yansımasını indir" @@ -593,6 +692,11 @@ msgstr "HATA: desteklenmeyen CI türü, yama gönderebilirsiniz!" msgid "Empty build flag at {linedesc}" msgstr "{linedesc} satırında boş inşa bayrağı" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -608,14 +712,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Günlük yayımlamaya çalışırken hata: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Depo adresi alınırken hata" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "APK'lardan imzaları ayıkla" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "{path} okunamadı: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -677,6 +786,11 @@ msgstr "VM'den buildserverid alındı: {buildserverid}" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "'{apkfilename}' için imzalar alındı -> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -688,6 +802,11 @@ msgstr "Tamamlandı" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Flattr bağış yöntemleri FlattrID bayrağında olmalı" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Flattr bağış yöntemleri FlattrID bayrağında olmalı" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Yasaklı HTML etiketleri" @@ -701,11 +820,20 @@ msgstr "Devre dışı uygulamaların inşasını zorunlu kıl, ve tarama problem msgid "Force halting build after {0} sec timeout!" msgstr "İnşa, {0} saniye zaman aşımından sonra zorla durduruluyor!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "\"{name}\" uygulaması için üst verisi olmayan \"{path}\" grafiği bulundu!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "Argümanda geçersiz appid'ler bulundu" @@ -715,6 +843,11 @@ msgstr "Argümanda geçersiz appid'ler bulundu" msgid "Found invalid versionCodes for some apps" msgstr "Bazı uygulamalar için geçersiz versionCodes bulundu" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "{path} içinde birden çok imzalama sertifikası bulundu" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -738,6 +871,11 @@ msgstr "Depo için imzalama sertifikaları bulunmadı." msgid "Found non-file at %s" msgstr "%s konumunda dosya olmayan bulundu" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "{apkfilename} {path} içine kopyalanıyor" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -760,6 +898,11 @@ msgstr "Git fetch başarısız" msgid "Git remote set-head failed" msgstr "Git remote set-head başarısız" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git remote set-head başarısız" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Git reset başarısız" @@ -776,6 +919,25 @@ msgstr "Git submodule update başarısız" msgid "HTTPS must be used with Subversion URLs!" msgstr "Subversion URL'leriyle HTTPS kullanılmalı!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Üst verisiz paket yok sayılıyor: " @@ -794,6 +956,18 @@ msgstr "'{path}' konumundaki {ext} dosyası yok sayılıyor" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "MD5 gibi devre dışı algoritmalarla imzalanmış APK'ları dahil et" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Altmodüller başlatılıyor" @@ -802,21 +976,31 @@ msgstr "Altmodüller başlatılıyor" msgid "Install all signed applications available" msgstr "Kullanılabilir tüm imzalı uygulamaları kur" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "İnşa edilen paketleri aygıtlara kur" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "%s kuruluyor…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "%s kuruluyor…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "'{apkfilename}' {dev} üstüne kuruluyor…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "'{apkfilename}' {dev} üstüne kuruluyor…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Depo HTTP sunucusu ile etkileşim kur" @@ -881,6 +1065,21 @@ msgstr "Geçersiz paket adı {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "HTTPS olmayanlara geçersiz yönlendirme: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Tüm üst veri dosyalarını oku ve çık" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -896,11 +1095,19 @@ msgstr "JAR imzası doğrulanamadı: {path}" msgid "JAR signature verified: {path}" msgstr "JAR imzası doğrulandı: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Java JDK bulunmadı! Standart konumda kurun veya java_paths'i ayarlayın!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Java jarsigner bulunamadı! Standart konuma kurun veya java_path ayarlayın!" @@ -918,6 +1125,11 @@ msgstr "İmzalama için anahtar deposu:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "Son kullanılan işleme '{commit}' bir etiket gibi görünüyor, ama güncelleme denetleme kipi '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Liberapay bağış yöntemleri LiberapayID bayrağında olmalı" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Liberapay bağış yöntemleri LiberapayID bayrağında olmalı" @@ -942,6 +1154,10 @@ msgstr "Bozuk depo yansımaları." msgid "Malformed serverwebroot line:" msgstr "Bozuk serverwebroot satırı:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Eksik çıktı dizini" @@ -981,6 +1197,11 @@ msgid "No git submodules available" msgstr "Kullanılabilir git submodules yok" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Android veya kivy projesi bulunamadı. --subdir belirtin?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Bilgi bulunamadı." @@ -1009,7 +1230,7 @@ msgstr "%s için kullanılabilir imzalanmış APK yok" msgid "No signed output directory - nothing to do" msgstr "İmzalanmış çıktı dizini yok - yapılacak işlem yok" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "{path} içinde imzalama sertifikaları bulunamadı" @@ -1029,6 +1250,10 @@ msgstr "Uygulama {appid} için böyle bir versionCode {versionCode} yok" msgid "No unsigned directory - nothing to do" msgstr "İmzalanmamış dizin yok - yapılacak işlem yok" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Yapılacak işlem yok" @@ -1061,7 +1286,7 @@ msgstr "OBB'ın packagename değeri desteklenen APK ile eşleşmiyor:" msgid "Old APK signature failed to verify: {path}" msgstr "Eski APK imzası doğrulanamadı: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Fdroid dağıtımı için eski, kullanımdan kaldırılmış isim" @@ -1078,6 +1303,11 @@ msgstr "Yalnızca Play Store ile olan farkları yazdır" msgid "Only process apps with auto-updates" msgstr "Yalnızca kendiliğinden güncellemesi olan uygulamaları işle" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Flattr bağış yöntemleri FlattrID bayrağında olmalı" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1087,6 +1317,16 @@ msgstr "Seçenekler" msgid "Output JSON report to file named after APK." msgstr "APK'den sonra adlandırılmış dosyaya JSON raporu yazdırın." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Projenin genel lisansı." @@ -1100,6 +1340,11 @@ msgstr "Depo APK'ları için konumu geçersiz kıl (öntanımlı olarak: ./repo) msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "{apkfilename} içindeki boş versionName değerine üst verideki yazılıyor: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1193,11 +1438,11 @@ msgstr "İkili şeffaflık günlüğü {url} konumuna gönderiliyor" msgid "Pushing to {url}" msgstr "{url} adresine itiliyor" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Hızlıca yeni bir depo başlat" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Tüm üst veri dosyalarını oku ve çık" @@ -1256,7 +1501,7 @@ msgstr "Piksel boyut sınırını aşan tüm simgeleri yeniden boyutlandır ve msgid "Restrict output to warnings and errors" msgstr "Çıkışı uyarılara ve hatalara kısıtla" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Tüm üst veri dosyalarını yeniden yaz" @@ -1295,7 +1540,11 @@ msgstr "{path} konumunda wget çalıştırılıyor" msgid "Scan only the latest version of each package" msgstr "Her paketin sadece en son sürümünü tara" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Bir paketin kaynak kodunu tara" @@ -1319,12 +1568,16 @@ msgstr[1] "Tarayıcı {} sorun buldu" msgid "Set clock to that time using:" msgstr "Saati o zamana şunu kullanarak ayarla:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Açık dosya sınırını {integer} olarak ayarla" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Gecelik bir inşa deposu için bir uygulama inşası kurun" @@ -1344,11 +1597,11 @@ msgstr "Bir emülatör kur, APKyı ona kur ve bir Drozer taraması yap" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Bir emülatör kur, APKyı ona kur ve bir Drozer taraması yap" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Paketleri imzala ve depoya yerleştir" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "update --nosign ile yaratılan indeksleri imzala" @@ -1406,6 +1659,11 @@ msgstr "Olağandan daha da çok bilgi çıkart" msgid "Striping mystery signature from {apkfilename}" msgstr "Gizemli imza {apkfilename} dosyasından kaldırılıyor" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Gizemli imza {apkfilename} dosyasından kaldırılıyor" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1464,6 +1722,10 @@ msgstr "local_copy_dir \"{path}\" için kök dizini yok!" msgid "There is a keyalias collision - publishing halted" msgstr "Bir keyalias çakışması var - yayımlama durdu" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1477,6 +1739,10 @@ msgstr "Awsbucket kullanmak için, awssecretkey ve awsaccesskeyid de config.py i msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCM ayarlı ancak checkupdates henüz çalıştırılmamış gibi görünüyor" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "URL kısaltıcılar kullanılmamalı" @@ -1490,12 +1756,21 @@ msgstr "URL başlığı yalnızca URL, köşeli ayraç kullanın: [URL]" msgid "URL {url} in Description: {error}" msgstr "Açıklamada URL {url}: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Geçersiz lisans etiketi \"%s\"! Yalnızca https://spdx.org/license-list adresindeki etiketleri kullanın" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "{linedesc} içinde {field} ile aynı satırda beklenmeyen metin" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Bilinmeyen özel durum bulundu!" @@ -1515,6 +1790,11 @@ msgstr "Bilinmeyen üst veri biçimi: %s" msgid "Unknown metadata format: {path}" msgstr "Bilinmeyen üst veri biçimi: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Bilinmeyen üst veri biçimi: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "aapt'nin bilinmeyen sürümü, soruna neden olabilir: " @@ -1593,19 +1873,29 @@ msgstr "%s konumunda kullanılmayan extlib" msgid "Unused file at %s" msgstr "%s konumunda kullanılmayan dosya" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "%s konumunda kullanılmayan dosya" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "%s konumunda kullanılmayan dosya" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "Update Check Name bilinen app id'ye ayarlı - kaldırılabilir" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Yeni paketler için depo bilgisini güncelle" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Bir URL için çalıştırılabilir şeffaflık günlüğünü güncelle" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Depo istatistikleri güncelleştir" @@ -1628,6 +1918,16 @@ msgstr "UpdateCheckData, HTTPS URL'sini kullanmalıdır: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData geçerli bir URL değil: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "{apkfilename} önbellekten okunuyor" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1663,6 +1963,14 @@ msgstr "Yeni eklenen APKlar için o anki zaman yerine APK tarihini kullan" msgid "Using \"{path}\" for configuring s3cmd." msgstr "s3cmd yapılandırması için \"{path}\" kullanılıyor." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Java'nın jarsigner'ı kullanılıyor, APK'ları doğrulamak için önerilmez! apksigner'ı kullanın" @@ -1682,7 +1990,7 @@ msgstr "Var olan anahtar deposu \"{path}\" kullanılıyor" msgid "Using s3cmd to sync with: {url}" msgstr "{url} ile eşitleme için s3cmd kullanılıyor" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Geçerli komutlar:" @@ -1690,7 +1998,7 @@ msgstr "Geçerli komutlar:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Yeniden yükleme yerine yerel olarak önbelleğe alınmış kopyaya karşı doğrulayın." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "İndirilen paketlerin bütünlüğünü doğrula" @@ -1698,7 +2006,12 @@ msgstr "İndirilen paketlerin bütünlüğünü doğrula" msgid "Verifying index signature:" msgstr "İndeks imzası doğrulanıyor:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Olası üst veri hataları hakkında uyar" @@ -1706,6 +2019,10 @@ msgstr "Olası üst veri hataları hakkında uyar" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "İmzalı indeksler için yapılandırıldığında, bu aşamada sadece imzasız indeksleri yarat" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "Anahtarlar üretilirken X.509 'Distinguished Name' kullanılır" @@ -1717,6 +2034,10 @@ msgstr "Anahtarlar üretilirken X.509 'Distinguished Name' kullanılır" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "SDK'nızın konumunu ayarlamak için ANDROID_HOME'u kullanabilirsiniz:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1739,6 +2060,10 @@ msgstr "belirsiz şeçenek: %(option)s ile %(matches)s eşleşebilir" msgid "ambiguous option: %s (%s?)" msgstr "belirsiz şeçenek: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "APPID biçiminde applicationId" @@ -1760,16 +2085,30 @@ msgstr "APPID[:VERCODE] biçiminde applicationId, isteğe bağlı versionCode il msgid "argument \"-\" with mode %r" msgstr "%r kipiyle \"-\" argümanı" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "Dağıtım anahtarını sınamak için çıplak ssh bağlantısı deneniyor:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "Dağıtım anahtarını sınamak için çıplak ssh bağlantısı deneniyor:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "'%s' açılamıyor: %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "{path} için bir appid bulunamıyor!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1794,6 +2133,10 @@ msgstr "{url} klonlanıyor" msgid "command to execute, either 'init' or 'update'" msgstr "çalıştırılacak komut, 'init' ya da 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1812,6 +2155,19 @@ msgstr[1] "çakışan seçenek satırları: %s" msgid "copying {apkfilename} into {path}" msgstr "{apkfilename} {path} içine kopyalanıyor" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1827,12 +2183,21 @@ msgstr "siliniyor: repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "'{path}' için günlükleri oluşturdu" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest= %r gibi seçenekler için gerekli" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1865,7 +2230,7 @@ msgstr "inşa günlükleri '{path}' konumuna konuşlanamadı" msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [] [-h|--help|--version|]" @@ -1886,6 +2251,10 @@ msgstr "üst veri hatalarının (öntanımlı) uyarı olmasını veya yok sayıl msgid "git svn clone failed" msgstr "git svn clone başarısız" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1963,7 +2332,7 @@ msgstr "APK sağlanmadı" msgid "no such option: %s" msgstr "böyle bir şeçenek yok: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "Sürüm bilgisi bulunamadı!" @@ -2051,6 +2420,11 @@ msgstr "var olan {path} üzerine yazılıyor" msgid "positional arguments" msgstr "konumsal argümanlar" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2061,11 +2435,19 @@ msgstr "güvensiz HTTP bağlantısı ile indirmeyi reddet (HTTPS kullanın veya msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "güvensiz http bağlantısı ile indirmeyi reddet (https kullanın veya --no-https-check belirtin): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sync {path} konumunu {url} adresine indeksler ve siler" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2098,6 +2480,10 @@ msgstr "kaynak tarball'ı atlanıyor: {path}" msgid "srclibs missing name and/or @" msgstr "srclibs'de ad ve/veya @ eksik" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2133,7 +2519,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "'{config_file}' üzerinde güvenli olmayan izinler (0600 olmalı)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "kullanım: " @@ -2146,6 +2532,10 @@ msgstr "kullanım: fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "{url} ile eşitleme için Apache libcloud kullanılıyor" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2209,16 +2599,31 @@ msgstr "{appid}: {field} bir '{type}' olmalı, fakat o bir '{fieldtype}!'" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}: {field} bir '{type}' olmalı, fakat o bir '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} alanı {name} içinde sonlandırılmamış" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" yok! config.py içinde düzeltin." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2234,11 +2639,21 @@ msgstr "{path} konumunun bozum imzası \"{pattern}\" var, olası Janus istismar msgid "{path} is zero size!" msgstr "{path} boyutu sıfır!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} \"fdroid\" ile bitmiyor, URL konumunu doğrulayın!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} \"fdroid\" ile bitmiyor, URL konumunu doğrulayın!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2251,18 +2666,6 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} inşa başarılı" msgstr[1] "{} inşa başarılı" -#~ msgid "Interactively ask about things that need updating." -#~ msgstr "Güncelleme gerektiren şeyler hakkında etkileşimli olarak sor." - -#~ msgid "Specify editor to use in interactive mode. Default " -#~ msgstr "Etkileşimli kipte kullanılacak editörü belirtin. Öntanımlı " - -#~ msgid "Specify editor to use in interactive mode. Default %s" -#~ msgstr "Etkileşimli kipte kullanılacak editörü belirtin. Öntanımlı %s" - -#~ msgid "Specify editor to use in interactive mode. Default is {path}" -#~ msgstr "Etkileşimli kipte kullanılacak düzenleyiciyi belirtin. Öntanımlı olan {path}" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Depodaki paketler için GPG imzaları ekle" @@ -2276,6 +2679,18 @@ msgstr[1] "{} inşa başarılı" #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "Temiz güncelleme - önbellekleri kullanmaz, tüm APKları yeniden işler" +#~ msgid "Interactively ask about things that need updating." +#~ msgstr "Güncelleme gerektiren şeyler hakkında etkileşimli olarak sor." + +#~ msgid "Specify editor to use in interactive mode. Default " +#~ msgstr "Etkileşimli kipte kullanılacak editörü belirtin. Öntanımlı " + +#~ msgid "Specify editor to use in interactive mode. Default %s" +#~ msgstr "Etkileşimli kipte kullanılacak editörü belirtin. Öntanımlı %s" + +#~ msgid "Specify editor to use in interactive mode. Default is {path}" +#~ msgstr "Etkileşimli kipte kullanılacak düzenleyiciyi belirtin. Öntanımlı olan {path}" + #~ msgid "app-id in the form APPID" #~ msgstr "APPID biçiminde app-id" diff --git a/locale/ug/LC_MESSAGES/fdroidserver.po b/locale/ug/LC_MESSAGES/fdroidserver.po index d2ce2566..f76ca690 100644 --- a/locale/ug/LC_MESSAGES/fdroidserver.po +++ b/locale/ug/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2018-06-08 03:44+0000\n" "Last-Translator: ۋولقان \n" "Language-Team: Uyghur \n" @@ -17,12 +17,28 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.0\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" "SSH Public Key to be used as Deploy Key:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -35,6 +51,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -50,11 +71,21 @@ msgstr "" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -105,6 +136,10 @@ msgstr "" msgid "'keypass' not found in config.py!" msgstr "" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "" @@ -186,11 +221,11 @@ msgstr "" msgid "A URL is required as an argument!" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "" @@ -223,6 +258,18 @@ msgstr "" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -283,7 +330,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "مەنبەدىن بىر بوغچا قۇرۇش" @@ -339,6 +391,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -357,7 +414,7 @@ msgstr "تۈرلەر قۇرۇلمىغان '%s'" msgid "Categories are not set" msgstr "تۈرلەر قۇرۇلمىغان" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "" @@ -386,7 +443,7 @@ msgstr "" msgid "Comma separated list of categories." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "" @@ -395,11 +452,23 @@ msgstr "" msgid "Commit changes" msgstr "" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -409,6 +478,15 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -484,6 +562,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -508,6 +596,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -542,7 +634,7 @@ msgstr "" msgid "Don't use rsync checksums" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -588,6 +680,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -601,14 +698,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -670,6 +772,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -681,6 +788,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -694,11 +805,20 @@ msgstr "" msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -708,6 +828,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -731,6 +856,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -753,6 +883,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -769,6 +904,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -787,6 +941,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -795,21 +961,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "" @@ -874,6 +1050,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -889,11 +1080,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -911,6 +1110,10 @@ msgstr "" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -935,6 +1138,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -974,6 +1181,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1002,7 +1213,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1022,6 +1233,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1054,7 +1269,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1071,6 +1286,10 @@ msgstr "" msgid "Only process apps with auto-updates" msgstr "" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1080,6 +1299,16 @@ msgstr "" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "" @@ -1093,6 +1322,11 @@ msgstr "" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1186,11 +1420,11 @@ msgstr "" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "" @@ -1249,7 +1483,7 @@ msgstr "" msgid "Restrict output to warnings and errors" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "" @@ -1288,7 +1522,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "" @@ -1312,12 +1550,16 @@ msgstr[1] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1337,11 +1579,11 @@ msgstr "" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "" @@ -1399,6 +1641,11 @@ msgstr "" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1457,6 +1704,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1470,6 +1721,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1483,12 +1738,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "" @@ -1508,6 +1771,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1586,19 +1854,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "" @@ -1621,6 +1899,16 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1656,6 +1944,14 @@ msgstr "" msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1675,7 +1971,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "" @@ -1683,7 +1979,7 @@ msgstr "" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "" @@ -1691,7 +1987,12 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" @@ -1699,6 +2000,10 @@ msgstr "" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "" @@ -1710,6 +2015,10 @@ msgstr "" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1732,6 +2041,10 @@ msgstr "" msgid "ambiguous option: %s (%s?)" msgstr "" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -1753,16 +2066,29 @@ msgstr "" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1787,6 +2113,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1805,6 +2135,19 @@ msgstr[1] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1820,12 +2163,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1858,7 +2210,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "" @@ -1879,6 +2231,10 @@ msgstr "" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1956,7 +2312,7 @@ msgstr "ھېچقانداق APK تەمىنلەنمىگەن" msgid "no such option: %s" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "نەشىر ئۇچۇرى تېپىلمىدى!" @@ -2044,6 +2400,11 @@ msgstr "" msgid "positional arguments" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2054,11 +2415,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2091,6 +2460,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2126,7 +2499,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "" @@ -2139,6 +2512,10 @@ msgstr "" msgid "using Apache libcloud to sync with {url}" msgstr "" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2202,16 +2579,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2227,11 +2619,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index b0a6660b..0cda8b8d 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-09-19 17:03+0000\n" "Last-Translator: ihor_ck \n" "Language-Team: Ukrainian \n" @@ -17,6 +17,16 @@ msgstr "" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -25,6 +35,15 @@ msgstr "" "\n" "Громадський ключ SSH буде використино як постановчий ключ (Deploy Key):" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Громадський ключ SSH буде використино як постановчий ключ (Deploy Key):" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -39,6 +58,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" не має відповідного файлу метаданих!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' вже встановлено на {dev}." + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -54,11 +78,21 @@ msgstr "\"{path}\" містить найновішу {name}{version}" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" існує, але s3cmd не встановлений!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" має непідтримуваний формат, конвертувати до: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" має непідтримуваний формат, конвертувати до: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -110,6 +144,10 @@ msgstr "%s параметр не приймає значення" msgid "'keypass' not found in config.py!" msgstr "'keypass' не знайдено в config.py!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "'keystore' не знайдено в config.py!" @@ -191,11 +229,11 @@ msgstr "/issues відсутній" msgid "A URL is required as an argument!" msgstr "URL потребується як аргумент!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "Додати підписи GnuPG для пакетів у сховищеві" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "Додайте новий застосунку зі свого вихідного коду" @@ -228,6 +266,19 @@ msgstr "Також відзеркалити всю секцію архіву" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "Також попередити про проблеми форматування, наприклад rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "Не знайдено Android SDK!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -288,7 +339,12 @@ msgstr "Гілка \"{branch}\" використовується як подан msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "Гілка '{branch}' використовується як подання в бібліотеку srclib '{srclib}'" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "Побудуйте пакет з джерела" @@ -345,6 +401,11 @@ msgstr "Неправильно вказано шлях \"{path}\"!" msgid "Cannot resolve app id {appid}" msgstr "Неможливо розв'язати id застосунку {appid}" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Неправильно вказано шлях \"{path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "Не можна одночасно використовувати --list та --to" @@ -363,7 +424,7 @@ msgstr "Категорія '%s' неприпустима" msgid "Categories are not set" msgstr "Категорії не встановлено" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "Перевірте наявність оновлень для застосунків" @@ -392,7 +453,7 @@ msgstr "Очистити оновлення - не використовує ке msgid "Comma separated list of categories." msgstr "Список категорій, розділених комами." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "Команда '%s' не визнана.\n" @@ -401,11 +462,25 @@ msgstr "Команда '%s' не визнана.\n" msgid "Commit changes" msgstr "Прийняти зміни" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "Не вдалося знайти '{command}' у вашій системі" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "Не вдається знайти останню версію коду" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "Не вдається знайти найновішу назву версії" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -415,6 +490,16 @@ msgstr "Не вдалося знайти шлях {path}, щоб вилучит msgid "Could not open apk file for analysis" msgstr "Не вдалося відкрити файл apk для аналізу" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "Не вдається знайти ідентифікатор пакета" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -490,6 +575,16 @@ msgstr "DEBUG_KEYSTORE не встановлено або значення є н msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Видалити APKs і/або OBBs без метаданих зі сховища" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -514,6 +609,10 @@ msgstr "Опис містить список (%s) але не маркірова msgid "Description of length {length} is over the {limit} char limit" msgstr "Довжина опису {length} перевищує ліміт {limit}" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "Не розміщувати нові файли до сховища одразу" @@ -548,7 +647,7 @@ msgstr "Не оновлюйте сховище, корисне під час т msgid "Don't use rsync checksums" msgstr "Не використовуйте контрольні суми rsync" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "Завантажувати повноцінні дзеркала невеликих сховищ" @@ -596,6 +695,11 @@ msgstr "ПОМИЛКА: непідтримуваний вид CI, виправл msgid "Empty build flag at {linedesc}" msgstr "Порожній прапорець збірки на {linedesc}" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -611,14 +715,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "Помилка під час отримання адреси сховища: %s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "Помилка отримання адреси сховища" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "Експортування підписів з APK" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Не вдалося розпізнати {path}: {error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -680,6 +789,11 @@ msgstr "Сервер для збірки скопійовано з ВМ {buildse msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "Отримані підписи для '{apkfilename}' -> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -691,6 +805,11 @@ msgstr "Готово" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Методи допомоги Flattr належать до прапора FlattrID" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Методи допомоги Flattr належать до прапора FlattrID" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "Заборонені мітки HTML" @@ -704,11 +823,20 @@ msgstr "Збирати заблоковані застосунки попри п msgid "Force halting build after {0} sec timeout!" msgstr "Примусово зупиняти збірку після {0} сек. затримки!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "У \"{path}\" виявлено зображення без метаданих для застосунку \"{name}\"!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "Знайдено недійсні прикладні програми в аргументах" @@ -718,6 +846,11 @@ msgstr "Знайдено недійсні прикладні програми в msgid "Found invalid versionCodes for some apps" msgstr "Знайдено недійсні версії коду для деяких застосунків" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Знайдено кілька сертифікатів для підписання на {path}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -741,6 +874,11 @@ msgstr "Не знайдено сертифікатів підписування msgid "Found non-file at %s" msgstr "Знайдено не файл у %s" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "копіювання {apkfilename} у {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -763,6 +901,11 @@ msgstr "Git вибірка не вдалася" msgid "Git remote set-head failed" msgstr "Не вдалося встановити пульт дистанційного керування Git" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Не вдалося встановити пульт дистанційного керування Git" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Скидання Git не вдалося" @@ -779,6 +922,25 @@ msgstr "Не вдалося оновити підмодуль Git" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS потрібно використовувати з URL-адресами Subversion!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "Нехтування пакунком без метаданих: " @@ -797,6 +959,18 @@ msgstr "Нехтування файлом {ext} у '{path}'" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "Включити APK, які підписані без алгоритмів, таких як MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "Під'єднання підмодулів" @@ -805,21 +979,31 @@ msgstr "Під'єднання підмодулів" msgid "Install all signed applications available" msgstr "Встановити всі доступні підписані застосунки" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "Встановити побудовані пакети на пристрої" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "Встановлення %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "Встановлення %s…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "Встановлення '{apkfilename}' на {dev}…" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "Встановлення '{apkfilename}' на {dev}…" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "Взаємодія з HTTP-сервером сховища" @@ -884,6 +1068,21 @@ msgstr "Неправильна назва пакунку {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Недійсне переспрямування на не-HTTPS: {before} -> {after} " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Прочитайте всі файли метаданих і вийдіть" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -899,11 +1098,19 @@ msgstr "Підпис JAR не вдалося перевірити: {path}" msgid "JAR signature verified: {path}" msgstr "Підтверджено підпис JAR: {path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "Java JDK не знайдено! Встановіть в усталеному розташуванні або встановіть java_paths!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "Jarsigner Java не знайдено! Встановіть в усталеному розташуванні або встановіть java_paths!" @@ -921,6 +1128,11 @@ msgstr "Шлях до сховища ключів для ключа підпис msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "Останнє подання '{commit}' виглядає як мітка, але в режимі перевірки оновлення '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Методи допомоги Flattr належать до прапора FlattrID" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Методи допомоги Flattr належать до прапора FlattrID" @@ -945,6 +1157,10 @@ msgstr "Несправні дзеркала сховища." msgid "Malformed serverwebroot line:" msgstr "Несправний шлях serverwebroot:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "Відсутній вихідний шлях" @@ -984,6 +1200,11 @@ msgid "No git submodules available" msgstr "Немає доступних підмодулів git" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Не знайдено жодного Android чи kivy проєкту. Вказати його у --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "Подробиць не знайдено." @@ -1012,7 +1233,7 @@ msgstr "Немає підписаних apk для %s" msgid "No signed output directory - nothing to do" msgstr "Немає підписаного вихідного шляху — нічого виконувати" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "У {path} не знайдено сертифікатів для підписання" @@ -1032,6 +1253,10 @@ msgstr "Немає такого versionCode {versionCode} для застосу msgid "No unsigned directory - nothing to do" msgstr "Немає непідписаної теки — нічого виконувати" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "Нічого виконувати" @@ -1064,7 +1289,7 @@ msgstr "Назва пакунку OBB не відповідає підтриму msgid "Old APK signature failed to verify: {path}" msgstr "Не вдалося підтвердити старий підпис APK: {path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "Застаріла назва розгортання (deploy) fdroid" @@ -1081,6 +1306,11 @@ msgstr "Друкувати відмінності тільки з Play Store" msgid "Only process apps with auto-updates" msgstr "Обробляти застосунки лише за допомогою автоматичних оновлень" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Методи допомоги Flattr належать до прапора FlattrID" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1090,6 +1320,16 @@ msgstr "Параметри" msgid "Output JSON report to file named after APK." msgstr "Виведіть JSON-звіт у назві файлу APK." +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "Загальна ліцензія проекту." @@ -1103,6 +1343,11 @@ msgstr "Перевизначити шлях для сховища APK-файлі msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "Перезапис порожнього versionName у {apkfilename} з метаданих: {version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1196,11 +1441,11 @@ msgstr "Оновити двійковий журнал прозорості дл msgid "Pushing to {url}" msgstr "Оприлюднення до {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "Швидкий запуск нового сховища" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "Прочитайте всі файли метаданих і вийдіть" @@ -1259,7 +1504,7 @@ msgstr "Змінити розмір усіх значків, що перевищ msgid "Restrict output to warnings and errors" msgstr "Обмеження виводу на попередження і помилки" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "Перепишіть усі файли метаданих" @@ -1298,7 +1543,11 @@ msgstr "Запуск wget у {path}" msgid "Scan only the latest version of each package" msgstr "Сканувати лише останню версію кожного пакета" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "Сканування вихідного коду пакета" @@ -1323,12 +1572,16 @@ msgstr[2] "Знайдено {} проблем" msgid "Set clock to that time using:" msgstr "Встановіть годинник на цей час, використовуючи:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "Встановити обмеження відкритого файлу на {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "Налаштувати застосунок для збірки сховища в нічний час" @@ -1348,11 +1601,11 @@ msgstr "Налаштуйте емулятор, встановіть на ньо msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "Налаштуйте емулятор, встановіть apk на нього та виконайте drozer сканування" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "Записати та розмістити пакети у сховищеві" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "Запис індексів, створених за допомогою update --nosign" @@ -1410,6 +1663,11 @@ msgstr "Випишіть ще більше даних, ніж звичайно" msgid "Striping mystery signature from {apkfilename}" msgstr "Видалення невідомого підпису для {apkfilename}" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Видалення невідомого підпису для {apkfilename}" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1468,6 +1726,10 @@ msgstr "Кореневої теки local_copy_dir \"{path}\" не існує!" msgid "There is a keyalias collision - publishing halted" msgstr "Відбулося зіткнення keyalias ключів - припинення оприлюднення" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1481,6 +1743,10 @@ msgstr "Для використання awsbucket, awssecretkey та awsaccesske msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "Режим перевірки оновлень встановлено, але схоже, що ще не запущено перевірку" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "Скорочувачі URL-адрес не варто використовувати" @@ -1494,12 +1760,21 @@ msgstr "Заголовок URL - це лише текст URL, користуй msgid "URL {url} in Description: {error}" msgstr "URL {url} в описі: {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Недійсна мітка ліцензії \"%s\"! Використовуйте лише мітки з https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "Несподіваний текст у тому ж рядку, що і {field} у {linedesc}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "Виявлено невідому виняткову ситуацію!" @@ -1519,6 +1794,11 @@ msgstr "Невідомий формат метаданих: %s" msgid "Unknown metadata format: {path}" msgstr "Створення скелетів файлів метаданих: {path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Створення скелетів файлів метаданих: {path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "Невідома версія aapt, може спричинити складнощі: " @@ -1597,19 +1877,29 @@ msgstr "Невикористаний extlib у %s" msgid "Unused file at %s" msgstr "Невикористаний файл у %s" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "Невикористаний файл у %s" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "Невикористаний файл у %s" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "Назву застосунку для перевірки оновлень встановлено на відомий id застосунку - його можна буде вилучити" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Оновіть інформацію сховища для нових пакетів" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "Оновити бінарний журнал прозорості для URL-адреси" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "Оновити статистику сховища" @@ -1632,6 +1922,16 @@ msgstr "UpdateCheckData має використовувати URL-адресу H msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData не є дійсною URL-адресою: {url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "Читання {apkfilename} з кешу" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1667,6 +1967,14 @@ msgstr "Використовуйте дату з apk, замість поточ msgid "Using \"{path}\" for configuring s3cmd." msgstr "Використання \"{path}\" для налаштування s3cmd." +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "Не варто перевіряти APK за допомогою jarsigner Java! Користуйтеся apksigner" @@ -1686,7 +1994,7 @@ msgstr "Застосування наявного сховища ключів \" msgid "Using s3cmd to sync with: {url}" msgstr "Використовувати s3cmd для синхронізації з: {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "Дійсні команди:" @@ -1694,7 +2002,7 @@ msgstr "Дійсні команди:" msgid "Verify against locally cached copy rather than redownloading." msgstr "Перевіряти, за допомогою локальної кешованої копії замість повторного завантаження." -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "Перевірте цілісність завантажених пакетів" @@ -1702,7 +2010,12 @@ msgstr "Перевірте цілісність завантажених пак msgid "Verifying index signature:" msgstr "Перевірка підпису індексу:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Попереджати про можливі помилки метаданих" @@ -1710,6 +2023,10 @@ msgstr "Попереджати про можливі помилки метада msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "Коли налаштовано для підписаних індексів, на цьому етапі створюйте лише непідписані індекси" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Distiguished Name' використовується при створенні ключів" @@ -1721,6 +2038,10 @@ msgstr "X.509 'Distiguished Name' використовується під час msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "За допомогою ANDROID_HOME можна встановити шлях до SDK, тобто:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1743,6 +2064,10 @@ msgstr "неоднозначний параметр: %(option)s може від msgid "ambiguous option: %s (%s?)" msgstr "неоднозначний параметр: %s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId у формі APPID" @@ -1764,16 +2089,30 @@ msgstr "applicationId з необов'язковим versionCode у формі A msgid "argument \"-\" with mode %r" msgstr "аргумент \"-\" в режимі %r" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "спроба відкритого з'єднання ssh для перевірки ключа розгортання:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "спроба відкритого з'єднання ssh для перевірки ключа розгортання:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "не може відкрити '%s': %s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "Не вдається знайти appid за шляхом {path}!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1798,6 +2137,10 @@ msgstr "клонування {url}" msgid "command to execute, either 'init' or 'update'" msgstr "команда виконати, 'init' або 'update'" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1817,6 +2160,19 @@ msgstr[2] "суперечних рядків параметра: %s" msgid "copying {apkfilename} into {path}" msgstr "копіювання {apkfilename} у {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1832,12 +2188,21 @@ msgstr "видалення: сховище/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "розгорнуто журнали збірки до '{path}'" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest= потрібен для таких варіантів, як %r" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1871,7 +2236,7 @@ msgstr "не вдалося розгорнути журнали збірки д msgid "fdroid [-h|--help|--version] []" msgstr "fdroid [-h|--help|--version] <команда> [<аргументи>]" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "fdroid [<команда>] [-h|--help|--version|<аргументи>]" @@ -1892,6 +2257,10 @@ msgstr "показувати помилки метаданих (типово), msgid "git svn clone failed" msgstr "Не вдалося клонувати git svn" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1969,7 +2338,7 @@ msgstr "APK не надано" msgid "no such option: %s" msgstr "такого параметру немає: %s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "не вдалося визначити версію!" @@ -2057,6 +2426,11 @@ msgstr "перезаписування наявного шляху {path}" msgid "positional arguments" msgstr "позиційні аргументи" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2067,11 +2441,19 @@ msgstr "відмовитись від завантаження через неб msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "відмовитись від завантаження через незахищене з'єднання http (користати https чи вказати --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd синхронізувати індекси з {path} до {url} та видалити" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2104,6 +2486,10 @@ msgstr "пропустити для архіву з джерелом: {path}" msgid "srclibs missing name and/or @" msgstr "srclibs відсутнє ім’я та/чи @" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2139,7 +2525,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "небезпечні дозволи на '{config_file}' (should be 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "використання: " @@ -2152,6 +2538,10 @@ msgstr "використання: fdroid [-h|--help|--version] <команда> msgid "using Apache libcloud to sync with {url}" msgstr "Apache libcloud: синхронізація з {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2216,16 +2606,31 @@ msgstr "{appid}: {field} повинен бути '{type}', а не '{fieldtype}! msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}: {field} повинно бути '{type}', а не '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} не припинено в {name}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" не існує! Виправте його в config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2241,11 +2646,21 @@ msgstr "{path}: недійсний підпис \"{pattern}\". Виглядає msgid "{path} is zero size!" msgstr "{path} не має розміру!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} не закінчується на \"fdroid\", перевірте шлях URL!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} не закінчується на \"fdroid\", перевірте шлях URL!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2260,6 +2675,19 @@ msgstr[0] "{} зібрано успішно" msgstr[1] "{} зібрано успішно" msgstr[2] "{} зібрано успішно" +#, fuzzy +#~ msgid "Add PGP signatures for packages in repo using GnuPG" +#~ msgstr "Додайте підписи gpg для пакетів у репозиторії" + +#~ msgid "Add gpg signatures for packages in repo" +#~ msgstr "Додайте підписи gpg для пакетів у репозиторії" + +#~ msgid "Android Build Tools path '{path}' does not exist!" +#~ msgstr "Шлях '{path}' до інструментів створення Android не існує!" + +#~ msgid "Clean update - don't uses caches, reprocess all apks" +#~ msgstr "Очистити оновлення - не використовує кеш, повторно обробляє всі apks" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "Інтерактивно запитайте про речі, які потребують оновлення." @@ -2274,19 +2702,6 @@ msgstr[2] "{} зібрано успішно" #~ msgid "Specify editor to use in interactive mode. Default is {path}" #~ msgstr "Вкажіть редактор для використання в інтерактивному режимі. За замовчуванням %s" -#, fuzzy -#~ msgid "Add PGP signatures for packages in repo using GnuPG" -#~ msgstr "Додайте підписи gpg для пакетів у репозиторії" - -#~ msgid "Add gpg signatures for packages in repo" -#~ msgstr "Додайте підписи gpg для пакетів у репозиторії" - -#~ msgid "Android Build Tools path '{path}' does not exist!" -#~ msgstr "Шлях '{path}' до інструментів створення Android не існує!" - -#~ msgid "Clean update - don't uses caches, reprocess all apks" -#~ msgstr "Очистити оновлення - не використовує кеш, повторно обробляє всі apks" - #~ msgid "app-id in the form APPID" #~ msgstr "app-id у формі APPID" diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index 171a7eee..a7dc2150 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-07-16 09:41+0000\n" "Last-Translator: Eric \n" "Language-Team: Chinese (Simplified) \n" @@ -20,6 +20,16 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.2-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -28,6 +38,15 @@ msgstr "" "\n" "SSH 公钥被用来作为布署密钥:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"SSH 公钥被用来作为布署密钥:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -42,6 +61,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" 没有匹配的元数据文件!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}'已安装在{dev}上。" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -57,11 +81,21 @@ msgstr "\"{path}\" 包含近期的 {name} ({version})" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\"存在,但未安装 s3cmd!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" 不是可接受的格式, 需转换成 : {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" 不是可接受的格式, 需转换成 : {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -111,6 +145,10 @@ msgstr "%s 选项不采用值" msgid "'keypass' not found in config.py!" msgstr "config.py中找不到'keypass'!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "config.py中找不到'keypass'!" @@ -192,11 +230,11 @@ msgstr "/问题丢失" msgid "A URL is required as an argument!" msgstr "需要有URL为参数!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "添加 gpg 签名至资源库软件包" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "从源码添加新的应用程序" @@ -229,6 +267,19 @@ msgstr "同时对存档部分完整镜像" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "同时提示格式问题,如 rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "未找到 Android SDK!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -289,7 +340,12 @@ msgstr "" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "从源生成包" @@ -344,6 +400,11 @@ msgstr "" msgid "Cannot resolve app id {appid}" msgstr "" +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "" @@ -362,7 +423,7 @@ msgstr "" msgid "Categories are not set" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "检查应用更新" @@ -391,7 +452,7 @@ msgstr "干净更新- 不用缓存,重新处理全部 APK文件" msgid "Comma separated list of categories." msgstr "逗号分割的目录列表。" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "无法识别命令 '%s'。\n" @@ -400,11 +461,25 @@ msgstr "无法识别命令 '%s'。\n" msgid "Commit changes" msgstr "提交更改" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "仅编译每个包的最新版本" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "仅编译每个包的最新版本" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -414,6 +489,16 @@ msgstr "" msgid "Could not open apk file for analysis" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "未能匹配应用程序" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -489,6 +574,16 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "从资源库中删除没有元数据的 APK 和 OBB" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -513,6 +608,10 @@ msgstr "" msgid "Description of length {length} is over the {limit} char limit" msgstr "" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "" @@ -547,7 +646,7 @@ msgstr "不刷新资源库,便于没有互联网时的内部版本测试" msgid "Don't use rsync checksums" msgstr "请勿使用 rsync 校验和" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "" @@ -593,6 +692,11 @@ msgstr "" msgid "Empty build flag at {linedesc}" msgstr "" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -606,14 +710,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -675,6 +784,11 @@ msgstr "" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -686,6 +800,10 @@ msgstr "" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "" +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "" @@ -699,11 +817,20 @@ msgstr "强制编译已禁用应用,忽略扫描出错。仅用于测试模式 msgid "Force halting build after {0} sec timeout!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "" @@ -713,6 +840,11 @@ msgstr "" msgid "Found invalid versionCodes for some apps" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -736,6 +868,11 @@ msgstr "" msgid "Found non-file at %s" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -758,6 +895,11 @@ msgstr "" msgid "Git remote set-head failed" msgstr "" +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "" @@ -774,6 +916,25 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "" @@ -792,6 +953,18 @@ msgstr "" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "" @@ -800,21 +973,31 @@ msgstr "" msgid "Install all signed applications available" msgstr "安装全部可用的已签名应用" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "在设备上安装生成包" +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "" +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "与资源库 HTTP 服务器互动" @@ -879,6 +1062,21 @@ msgstr "" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "读取全部元数据文件并退出" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -894,11 +1092,19 @@ msgstr "" msgid "JAR signature verified: {path}" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "" @@ -916,6 +1122,10 @@ msgstr "签名密钥的密钥库:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "" +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "" @@ -940,6 +1150,10 @@ msgstr "" msgid "Malformed serverwebroot line:" msgstr "" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "" @@ -979,6 +1193,10 @@ msgid "No git submodules available" msgstr "" #: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "" @@ -1007,7 +1225,7 @@ msgstr "" msgid "No signed output directory - nothing to do" msgstr "" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "" @@ -1027,6 +1245,10 @@ msgstr "" msgid "No unsigned directory - nothing to do" msgstr "" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "" @@ -1059,7 +1281,7 @@ msgstr "" msgid "Old APK signature failed to verify: {path}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "" @@ -1076,6 +1298,10 @@ msgstr "仅输出与 Play Store 的差异" msgid "Only process apps with auto-updates" msgstr "仅处理使用自动更新的应用" +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1085,6 +1311,16 @@ msgstr "选项" msgid "Output JSON report to file named after APK." msgstr "" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "项目总体许可证。" @@ -1098,6 +1334,11 @@ msgstr "覆盖资源库 APK 路径(默认为 ./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1191,11 +1432,11 @@ msgstr "正推送二进制文件透明日志到{url}" msgid "Pushing to {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "快速新建资源库" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "读取全部元数据文件并退出" @@ -1254,7 +1495,7 @@ msgstr "对超过像素大小上限的全部图标进行尺寸调整,然后退 msgid "Restrict output to warnings and errors" msgstr "仅输出警告和出错信息" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "重写全部元数据文件" @@ -1293,7 +1534,11 @@ msgstr "" msgid "Scan only the latest version of each package" msgstr "仅扫描每个包的最新版本" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "扫描包源码" @@ -1316,12 +1561,16 @@ msgstr[0] "" msgid "Set clock to that time using:" msgstr "" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "" @@ -1341,11 +1590,11 @@ msgstr "设置一个模拟器,在其中安装APK并执行Drozer扫描" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "设置一个模拟器,然后在其中安装 apk 并执行 drozer 扫描" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "对包进行签名并将其加入资源库" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "签署使用更新创建的索引 --nosign" @@ -1403,6 +1652,11 @@ msgstr "比一般情况输出更多的信息" msgid "Striping mystery signature from {apkfilename}" msgstr "" +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1461,6 +1715,10 @@ msgstr "" msgid "There is a keyalias collision - publishing halted" msgstr "" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1474,6 +1732,10 @@ msgstr "" msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "" @@ -1487,12 +1749,20 @@ msgstr "" msgid "URL {url} in Description: {error}" msgstr "" +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "发生未知异常!" @@ -1512,6 +1782,11 @@ msgstr "" msgid "Unknown metadata format: {path}" msgstr "未知元数据格式:{path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "未知元数据格式:{path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "" @@ -1590,19 +1865,29 @@ msgstr "" msgid "Unused file at %s" msgstr "" +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "更新新包的资源库信息" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "更新 URL 的二进制透明度日志" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "更新资源库统计信息" @@ -1625,6 +1910,16 @@ msgstr "UpdateCheckData必须使用HTTPS URL:{url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1660,6 +1955,14 @@ msgstr "对于最新添加的 apk,使用来自 apk 的日期,而不是当前 msgid "Using \"{path}\" for configuring s3cmd." msgstr "" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "" @@ -1679,7 +1982,7 @@ msgstr "" msgid "Using s3cmd to sync with: {url}" msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "有效的命令为:" @@ -1687,7 +1990,7 @@ msgstr "有效的命令为:" msgid "Verify against locally cached copy rather than redownloading." msgstr "" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "验证已下载包的完整性" @@ -1695,7 +1998,12 @@ msgstr "验证已下载包的完整性" msgid "Verifying index signature:" msgstr "" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "有关元数据可能错误的警告" @@ -1703,6 +2011,10 @@ msgstr "有关元数据可能错误的警告" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "如果已配置为使用签名索引,该阶段仅创建未签名索引" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 生成密钥时所用的“可分辨名称”" @@ -1714,6 +2026,10 @@ msgstr "生成密钥时使用了X.509 ‘可识别名’" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1736,6 +2052,10 @@ msgstr "模糊选项:%(option)s 可以相配 %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "不明确的选项:%s(%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "app-id,格式:APPID" @@ -1757,16 +2077,29 @@ msgstr "带有可选 versionCode 的 app-id,格式:APPID[:VERCODE]" msgid "argument \"-\" with mode %r" msgstr "" +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "无法打开 '%s': %s" +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1791,6 +2124,10 @@ msgstr "" msgid "command to execute, either 'init' or 'update'" msgstr "执行命令:init 或 update" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1808,6 +2145,19 @@ msgstr[0] "" msgid "copying {apkfilename} into {path}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1823,12 +2173,21 @@ msgstr "" msgid "deployed build logs to '{path}'" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1860,7 +2219,7 @@ msgstr "" msgid "fdroid [-h|--help|--version] []" msgstr "用法:fdroid [-h|--help|--version] []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "用法:fdroid [-h|--help|--version] []" @@ -1881,6 +2240,10 @@ msgstr "强制元数据错误(默认)为警告,或忽略。" msgid "git svn clone failed" msgstr "" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1958,7 +2321,7 @@ msgstr "" msgid "no such option: %s" msgstr "没有此选项:%s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "没有找到版本信息!" @@ -2046,6 +2409,11 @@ msgstr "" msgid "positional arguments" msgstr "位置参数" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2056,11 +2424,19 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2093,6 +2469,10 @@ msgstr "" msgid "srclibs missing name and/or @" msgstr "" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2128,7 +2508,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "{config_file}有不安全的权限(应该是0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "用法: " @@ -2141,6 +2521,10 @@ msgstr "用法:fdroid [-h|--help|--version] []" msgid "using Apache libcloud to sync with {url}" msgstr "正在用Apache libcloud同步{url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2203,16 +2587,31 @@ msgstr "" msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2228,11 +2627,21 @@ msgstr "" msgid "{path} is zero size!" msgstr "" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2243,6 +2652,16 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "" +#, fuzzy +#~ msgid "Add PGP signatures for packages in repo using GnuPG" +#~ msgstr "添加包 gpg 签名至资源库" + +#~ msgid "Add gpg signatures for packages in repo" +#~ msgstr "添加包 gpg 签名至资源库" + +#~ msgid "Clean update - don't uses caches, reprocess all apks" +#~ msgstr "清除更新:不用缓存,重新处理全部 apk" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "需更新事项的互动提示。" @@ -2257,16 +2676,6 @@ msgstr[0] "" #~ msgid "Specify editor to use in interactive mode. Default is {path}" #~ msgstr "指定编辑器使用互动模式。默认 %s" -#, fuzzy -#~ msgid "Add PGP signatures for packages in repo using GnuPG" -#~ msgstr "添加包 gpg 签名至资源库" - -#~ msgid "Add gpg signatures for packages in repo" -#~ msgstr "添加包 gpg 签名至资源库" - -#~ msgid "Clean update - don't uses caches, reprocess all apks" -#~ msgstr "清除更新:不用缓存,重新处理全部 apk" - #~ msgid "app-id in the form APPID" #~ msgstr "app-id,格式:APPID" diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index a8d022d6..d24bca1b 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2019-01-28 13:31+0000\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-01 09:00+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Chinese (Traditional) \n" @@ -17,6 +17,16 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.3-dev\n" +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + #: ../fdroidserver/nightly.py msgid "" "\n" @@ -25,6 +35,15 @@ msgstr "" "\n" "SSH 公鑰被用來作為佈署密鑰:" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"SSH 公鑰被用來作為佈署密鑰:" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "" @@ -39,6 +58,11 @@ msgstr "" msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s 1/\" 沒有符合的中介資料檔案!" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' 已安裝在 {dev} 上。" + #: ../fdroidserver/update.py #, python-brace-format msgid "\"{path}\" contains outdated {name} ({version})" @@ -54,11 +78,21 @@ msgstr "\"{path}\" 包含近期的 {name} ({version})" msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "有 \"{path}\" 存在,但是沒有安裝 s3cmd!" +#: ../fdroidserver/lint.py +#, fuzzy, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" 不是可接受的格式,轉換成: {formats}" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "\"{path}\" is not an accepted format, convert to: {formats}" msgstr "\"{path}\" 不是可接受的格式,轉換成: {formats}" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format @@ -108,6 +142,10 @@ msgstr "%s 選項不帶值" msgid "'keypass' not found in config.py!" msgstr "config.py 找不到 'keypass'!" +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" msgstr "config.py 找不到 'keystore'!" @@ -189,11 +227,11 @@ msgstr "/issues 有遺漏" msgid "A URL is required as an argument!" msgstr "需要 URL 作為參數!" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add PGP signatures using GnuPG for packages in repo" msgstr "在軟體庫中加入使用 GnuPG 套件包的 gpg 簽署" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" msgstr "從原始程式碼增加一個新的應用程式" @@ -226,6 +264,19 @@ msgstr "另外鏡像完整的檔案區段" msgid "Also warn about formatting issues, like rewritemeta -l" msgstr "還要提醒格式化問題,如 rewritemeta -l" +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +#, fuzzy +msgid "Android DEX code" +msgstr "未找到 Android SDK!" + #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format msgid "Android SDK '{path}' does not have '{dirname}' installed!" @@ -286,7 +337,12 @@ msgstr "分支 '{branch}' 被用於建立 '{versionName}'的提交" msgid "Branch '{branch}' used as commit in srclib '{srclib}'" msgstr "分支 '{branch}' 用於 srclib '{srclib}' 的提交" -#: ../fdroid +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" msgstr "從原始程式碼編譯成套裝軟體" @@ -341,6 +397,11 @@ msgstr "無法讀取 \"{path}\"!" msgid "Cannot resolve app id {appid}" msgstr "無法解析 {appid} id" +#: ../fdroidserver/rewritemeta.py +#, fuzzy, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "無法讀取 \"{path}\"!" + #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" msgstr "無法同時使用 --list 和 --to" @@ -359,7 +420,7 @@ msgstr "'%s' 類別無效" msgid "Categories are not set" msgstr "類別未設定" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" msgstr "檢查應用程式更新" @@ -388,7 +449,7 @@ msgstr "清除更新 - 不使用快取,重新處理全部的 APK" msgid "Comma separated list of categories." msgstr "以逗號分隔類別清單。" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" msgstr "不能承認命令「%s」。\n" @@ -397,11 +458,25 @@ msgstr "不能承認命令「%s」。\n" msgid "Commit changes" msgstr "提交變更" +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" msgstr "在您的系統上找不到 '{command}'" +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version code" +msgstr "找到不最新版的代碼" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Could not find latest version name" +msgstr "找不到最新版本名稱" + #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" @@ -411,6 +486,16 @@ msgstr "無法找到 {path} 來移除" msgid "Could not open apk file for analysis" msgstr "無法開啟 apk 檔案作分析" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +#, fuzzy +msgid "Couldn't find Application ID" +msgstr "找不到包 ID" + #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py msgid "Couldn't find latest version code" @@ -486,6 +571,16 @@ msgstr "DEBUG_KEYSTORE 未作設定或是不完整" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "從軟體庫刪除缺少中介資料的 APK 和/或 OBB" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Deleting unknown file: {path}" @@ -510,6 +605,10 @@ msgstr "描述中有一個列表 (%s) 但它並未被編排 (*) 或作編號 (#) msgid "Description of length {length} is over the {limit} char limit" msgstr "描述的長度 {length} 已超過 {limit} 個字符限制" +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" msgstr "不要部署新檔案到倉庫中" @@ -544,7 +643,7 @@ msgstr "不要更新軟體庫,在沒有網路連線時測試構建很有用" msgid "Don't use rsync checksums" msgstr "不使用 rsync 檢驗和" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" msgstr "下載小型軟體庫完整的鏡像" @@ -592,6 +691,11 @@ msgstr "出錯:未支援 CI 類型,歡迎補強!" msgid "Empty build flag at {linedesc}" msgstr "{linedesc} 空白的編譯標誌" +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + #: ../fdroidserver/init.py #, python-format msgid "" @@ -607,14 +711,19 @@ msgstr "" msgid "Error while attempting to publish log: %s" msgstr "在嘗試刊登日誌時出錯:%s" -#: ../fdroidserver/import.py +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "Error while getting repo address" msgstr "在接取軟體庫的地址時出錯" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" msgstr "自 APKs 捽取出簽名" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "讀取 {path} 失敗:錯誤訊息{error}" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "Failed fetching signatures for '{apkfilename}': {error}" @@ -676,6 +785,11 @@ msgstr "從 VM 提取 buildserverid:{buildserverid}" msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" msgstr "抓取 '{apkfilename}' 的簽署資料 -> '{sigdir}'" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py @@ -687,6 +801,11 @@ msgstr "已完成" msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Flattr 捐款方式在 FlattrID 標誌下" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Flattr 捐款方式在 FlattrID 標誌下" + #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" msgstr "禁用 HTML 標籤" @@ -700,11 +819,20 @@ msgstr "強制停用應用程式的構建,並且忽視掃描問題而繼續。 msgid "Force halting build after {0} sec timeout!" msgstr "在 {0} 秒超時後強制停止構建!" +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "找到 \"{path}\" 圖像不包含 \"{name}\" 應用的中介資料!" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" msgstr "引數中找到無效的 appids" @@ -714,6 +842,11 @@ msgstr "引數中找到無效的 appids" msgid "Found invalid versionCodes for some apps" msgstr "有些應用的版本代號無效" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "{path} 找到多筆簽名證書" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Found multiple metadata files for {appid}" @@ -737,6 +870,11 @@ msgstr "軟體庫查無簽名證書。" msgid "Found non-file at %s" msgstr "%s 中找到 non-file" +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "複製 {apkfilename} 到 {path}" + #: ../fdroidserver/update.py #, python-brace-format msgid "Generated skeleton metadata for {appid}" @@ -759,6 +897,11 @@ msgstr "Git 抓取失敗" msgid "Git remote set-head failed" msgstr "Git 遠端 set-head 失敗" +#: ../fdroidserver/common.py +#, fuzzy, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git 遠端 set-head 失敗" + #: ../fdroidserver/common.py msgid "Git reset failed" msgstr "Git 重置失敗" @@ -775,6 +918,25 @@ msgstr "Git 子模組更新失敗" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS 必須與 Subversion 網址一起使用!" +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " msgstr "忽略無中介資料的套件包: " @@ -793,6 +955,18 @@ msgstr "忽略在 '{path}' 的 {ext} 檔案" msgid "Include APKs that are signed with disabled algorithms like MD5" msgstr "包含 APKs 其簽名為有弱點的演算法,如 MD5" +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + #: ../fdroidserver/common.py msgid "Initialising submodules" msgstr "初始化子模組" @@ -801,21 +975,31 @@ msgstr "初始化子模組" msgid "Install all signed applications available" msgstr "安裝所有已簽署可用的應用程式" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Install built packages on devices" msgstr "在裝置上安裝構建套件包" +#: ../fdroidserver/install.py +#, fuzzy, python-format +msgid "Installing %s..." +msgstr "安裝 %s…" + #: ../fdroidserver/install.py #, python-format msgid "Installing %s…" msgstr "安裝 %s…" +#: ../fdroidserver/install.py +#, fuzzy, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "在 {dev} 安裝 '{apkfilename}' …" + #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" msgstr "在 {dev} 安裝 '{apkfilename}' …" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" msgstr "與軟體庫 HTTP 伺服器互動" @@ -880,6 +1064,21 @@ msgstr "無效的套件包稱 {0}" msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "無效的重新導向到非 HTTPS:{before}->{after}。 " +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "讀取所有的中介資料檔案並退出" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" @@ -895,11 +1094,19 @@ msgstr "JAR 簽名驗證失敗:{path}" msgid "JAR signature verified: {path}" msgstr "JAR 簽名已驗證:{path}" +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py msgid "Java JDK not found! Install in standard location or set java_paths!" msgstr "找不到 Java JDK!請安裝在標準的位置或是設定 java_paths!" +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" msgstr "找不到 Java jarsigner!請安裝在標準的位置或是設定 java_paths!" @@ -917,6 +1124,11 @@ msgstr "金鑰庫的簽署金鑰:\t" msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgstr "最近採用的提交 '{commit}' 似乎是一個標籤,但更新的檢查模式為 '{ucm}'" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Liberapay 捐款方式在 LiberapayID 標誌下" + #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" msgstr "Liberapay 捐款方式在 LiberapayID 標誌下" @@ -941,6 +1153,10 @@ msgstr "軟體庫鏡像異常。" msgid "Malformed serverwebroot line:" msgstr "異常的 serverwebroot 行:" +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + #: ../fdroidserver/gpgsign.py msgid "Missing output directory" msgstr "輸出目錄消失" @@ -980,6 +1196,11 @@ msgid "No git submodules available" msgstr "無可用的 git 子模組" #: ../fdroidserver/import.py +#, fuzzy +msgid "No gradle project could be found. Specify --subdir?" +msgstr "找無 android 或 kivy 專案。指定子目錄嗎?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." msgstr "查無資訊。" @@ -1008,7 +1229,7 @@ msgstr "%s 沒有已簽署的 apk" msgid "No signed output directory - nothing to do" msgstr "輸出目錄無簽署 - 無須採取動作" -#: ../fdroidserver/update.py +#: ../fdroidserver/update.py ../fdroidserver/common.py #, python-brace-format msgid "No signing certificates found in {path}" msgstr "{path} 找不到簽署證書" @@ -1028,6 +1249,10 @@ msgstr "應用 {appid} 無版本代號 {versionCode}" msgid "No unsigned directory - nothing to do" msgstr "無未簽署目錄 - 無須採取行動" +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + #: ../fdroidserver/signindex.py msgid "Nothing to do" msgstr "無須採取動作" @@ -1060,7 +1285,7 @@ msgstr "OBB 的套件包名稱與支援的 APK 並不相符:" msgid "Old APK signature failed to verify: {path}" msgstr "舊的 APK 簽名無法驗證:{path}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Old, deprecated name for fdroid deploy" msgstr "舊的,棄用的 fdroid 部署名稱" @@ -1077,6 +1302,11 @@ msgstr "僅印出與 Play Store 的不同處" msgid "Only process apps with auto-updates" msgstr "只處理具有自動更新的應用程式" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Flattr 捐款方式在 FlattrID 標誌下" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" @@ -1086,6 +1316,16 @@ msgstr "選項" msgid "Output JSON report to file named after APK." msgstr "將 json 報告輸出到以 apk 命名的檔案。" +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + #: ../fdroidserver/import.py msgid "Overall license of the project." msgstr "該專案的整體授權。" @@ -1099,6 +1339,11 @@ msgstr "覆蓋軟體庫 APK 的路徑 (預設:./repo)" msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" msgstr "覆蓋在 {apkfilename} 中的空白 versionName 從詮釋資料:{version}" +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Parsing manifest at '{path}'" @@ -1192,11 +1437,11 @@ msgstr "推二進制的透明日誌到{url}" msgid "Pushing to {url}" msgstr "發佈到 {url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" msgstr "快速啟動新的儲存庫" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Read all the metadata files and exit" msgstr "讀取所有的中介資料檔案並退出" @@ -1255,7 +1500,7 @@ msgstr "重設超過最大像素的所有圖示之尺寸並且退出" msgid "Restrict output to warnings and errors" msgstr "將輸出限定為警告和錯誤" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" msgstr "重寫所有的中介資料檔案" @@ -1294,7 +1539,11 @@ msgstr "在 {path} 裡執行 wget" msgid "Scan only the latest version of each package" msgstr "只掃描每個套件包的最新版本" -#: ../fdroid +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" msgstr "掃描套件包的原始碼" @@ -1317,12 +1566,16 @@ msgstr[0] "掃瞄器發現 {} 問題" msgid "Set clock to that time using:" msgstr "設定時鐘到那時使用:" +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" msgstr "設定開啟的檔案限制為 {integer}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" msgstr "為非正式編譯庫建立一個應用編譯" @@ -1342,11 +1595,11 @@ msgstr "設置一個模擬器,在其上安裝 APK 並執行 drozer 掃描" msgid "Setup an emulator, install the apk on it and perform a drozer scan" msgstr "設置一個模擬器,在其上安裝 apk 並執行 drozer 掃描" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign and place packages in the repo" msgstr "簽署並放置套件包在軟體庫中" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Sign indexes created using update --nosign" msgstr "簽署使用更新建立的索引 --nosign" @@ -1404,6 +1657,11 @@ msgstr "傾湧出比正常情況下更多的資訊" msgid "Striping mystery signature from {apkfilename}" msgstr "正從 {apkfilename} 除去隱秘簽名" +#: ../fdroidserver/nightly.py +#, fuzzy, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "正從 {apkfilename} 除去隱秘簽名" + #: ../fdroidserver/lint.py #, python-format msgid "Summary '%s' is just the app's name" @@ -1462,6 +1720,10 @@ msgstr "local_copy_dir \"{path}\" 根目錄不存在!" msgid "There is a keyalias collision - publishing halted" msgstr "發生主要別名衝突 - 發佈中止" +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + #: ../fdroidserver/import.py #, python-format msgid "This repo already has local metadata: %s" @@ -1475,6 +1737,10 @@ msgstr "要使用 awsbucket, awssecretkey 與 awsaccesskeyid 必須在 config.py msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgstr "UCM 已被設定但它似乎尚未曾執行更新檢查" +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" msgstr "不應使用 URL 縮短網址" @@ -1488,12 +1754,21 @@ msgstr "URL 標題就是 URL,請用括號:[URL]" msgid "URL {url} in Description: {error}" msgstr "描述中的 URL {url} : {error}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "無效的執照標籤 \"%s\"!請使用 https://spdx.org/license-list 標籤" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unexpected text on same line as {field} in {linedesc}" msgstr "在 {linedesc} 在同一行的 {field} 出現未預期的文字" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" msgstr "發現未知的異常!" @@ -1513,6 +1788,11 @@ msgstr "未知的中介資料格式:%s" msgid "Unknown metadata format: {path}" msgstr "未知的中介資料格式t:{path}" +#: ../fdroidserver/metadata.py +#, fuzzy, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "未知的中介資料格式t:{path}" + #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " msgstr "不明的 aapt 版本,可能會出問題: " @@ -1591,19 +1871,29 @@ msgstr "在 %s 未使用的 extlib" msgid "Unused file at %s" msgstr "在 %s 未使用的檔案" +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scandelete path: %s" +msgstr "在 %s 未使用的檔案" + +#: ../fdroidserver/scanner.py +#, fuzzy, python-format +msgid "Unused scanignore path: %s" +msgstr "在 %s 未使用的檔案" + #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" msgstr "更新 Check Name 被設定成已知的應用 id - 它可以被移除" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "為新的套件包更新軟體庫資訊" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the binary transparency log for a URL" msgstr "為網址更新二進制的透明日誌" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Update the stats of the repo" msgstr "更新軟體庫的統計" @@ -1626,6 +1916,16 @@ msgstr "UpdateCheckData 必須使用 HTTPS URL:{url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData 不是有效的 URL:{url}" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, fuzzy, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "從緩存讀取 {apkfilename}" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" @@ -1661,6 +1961,14 @@ msgstr "新增的 apk 使用日期,來自 apk 而不是目前時間" msgid "Using \"{path}\" for configuring s3cmd." msgstr "使用 \"{path}\" 對 s3cmd 組態。" +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" msgstr "使用 Java 的 jarsigner,這並不建議用於驗證 APK!使用 apksigner" @@ -1680,7 +1988,7 @@ msgstr "使用現有的金鑰庫 \"{path}\"" msgid "Using s3cmd to sync with: {url}" msgstr "使用 s3cmd 來同步:{url}" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" msgstr "正確的命令是:" @@ -1688,7 +1996,7 @@ msgstr "正確的命令是:" msgid "Verify against locally cached copy rather than redownloading." msgstr "使用本機快取複本來驗證而非重新下載。" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" msgstr "驗證下載套裝軟體的完整性" @@ -1696,7 +2004,12 @@ msgstr "驗證下載套裝軟體的完整性" msgid "Verifying index signature:" msgstr "正在驗證索引簽名:" -#: ../fdroid +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "關於中介資料可能錯誤的警告" @@ -1704,6 +2017,10 @@ msgstr "關於中介資料可能錯誤的警告" msgid "When configured for signed indexes, create only unsigned indexes at this stage" msgstr "當已組態為簽名的索引時,只能在此階段建立無簽名的索引" +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + msgid "X.509 'Distiguished Name' used when generating keys" msgstr "產生金鑰時使用 X.509 '專有名稱'" @@ -1715,6 +2032,10 @@ msgstr "產生金鑰時使用 X.509 的'專有名稱'" msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" msgstr "可以使用 ANDROID_HOME 來設定 SDK 的路徑,i.e.:" +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" @@ -1737,6 +2058,10 @@ msgstr "模糊選項:%(option)s 可以相配 %(matches)s" msgid "ambiguous option: %s (%s?)" msgstr "不明確的選項:%s (%s?)" +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId 格式為 APPID" @@ -1758,16 +2083,30 @@ msgstr "applicationId 具有任選的 versionCode 在此格式為 APPID [:VERCOD msgid "argument \"-\" with mode %r" msgstr "引數 \"-\" 為帶 %r 模式" +#: ../fdroidserver/nightly.py +#, fuzzy +msgid "attempting bare SSH connection to test deploy key:" +msgstr "試圖顯露 ssh 連線來測試佈署金鑰:" + #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" msgstr "試圖顯露 ssh 連線來測試佈署金鑰:" +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "can't open '%s': %s" msgstr "無法打開 '%s':%s" +#: ../fdroidserver/build.py +#, fuzzy, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "找不到 {path} 的 appid!" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "cannot have multiple subparser arguments" @@ -1792,6 +2131,10 @@ msgstr "複製 {url}" msgid "command to execute, either 'init' or 'update'" msgstr "命令執行,'init' 或 'update' 中的任何一個" +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "complex" @@ -1809,6 +2152,19 @@ msgstr[0] "相衝突的選項字串:%s" msgid "copying {apkfilename} into {path}" msgstr "複製 {apkfilename} 到 {path}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "created {path}" @@ -1824,12 +2180,21 @@ msgstr "刪除:repo/{apkfilename}" msgid "deployed build logs to '{path}'" msgstr "已將構建記錄部署到「{path}」" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format msgid "dest= is required for options like %r" msgstr "dest= 如 %r 選項為必須" +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1861,7 +2226,7 @@ msgstr "構建記錄部署到「{path}」失敗" msgid "fdroid [-h|--help|--version] []" msgstr "用法:fdroid [-h|--help|--version] <命令> []" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" msgstr "用法:fdroid [-h|--help|--version] <命令> []" @@ -1882,6 +2247,10 @@ msgstr "強制中介資料錯誤(預設值)作警告或忽略。" msgid "git svn clone failed" msgstr "Git svn 複製失敗" +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py #, python-format @@ -1959,7 +2328,7 @@ msgstr "無 APK 被供應" msgid "no such option: %s" msgstr "沒這樣的選項:%s" -#: ../fdroid +#: ../fdroid ../fdroidserver/__main__.py msgid "no version info found!" msgstr "未發現版本資訊!" @@ -2047,6 +2416,11 @@ msgstr "覆寫現有的 {path}" msgid "positional arguments" msgstr "位置參數" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + #: ../fdroidserver/signatures.py #, python-brace-format msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" @@ -2057,11 +2431,19 @@ msgstr "拒絕透過不安全的 HTTP 連線下載 (使用 HTTPS 或指明 --no- msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "拒絕透過不安全 http 連線下載 (使用 https 或指明 --no-https-check): {apkfilename}" +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd 同步索引 {path} 到 {url} 並刪除" +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" @@ -2094,6 +2476,10 @@ msgstr "略過來源 tarball: {path}" msgid "srclibs missing name and/or @" msgstr "srclibs 缺失名稱或 @" +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" @@ -2129,7 +2515,7 @@ msgid "unsafe permissions on '{config_file}' (should be 0600)!" msgstr "'{config_file}' 檔案不安全的權限(應為 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid -#: /usr/lib/python3.7/argparse.py +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " msgstr "使用: " @@ -2142,6 +2528,10 @@ msgstr "用法:fdroid [-h|--help|--version] <命令> []" msgid "using Apache libcloud to sync with {url}" msgstr "使用 Apache libcloud 來同步 {url}" +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2204,16 +2594,31 @@ msgstr "{appid}:{field} 必須是一個 '{type}',但它是一個 '{fieldtype msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" msgstr "{appid}:{field} 必須是一個 '{type}',但它是一個 '{fieldtype}'!" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-brace-format msgid "{field} not terminated in {name}" msgstr "{field} 未終結在 {name}" +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{name} \"{path}\" does not exist! Correct it in config.py." msgstr "{name} \"{path}\" 不存在! 請更正 config.py." +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" @@ -2229,11 +2634,21 @@ msgstr "{path} 有不正確的檔案簽章「{pattern}」,可能是 Janus 漏 msgid "{path} is zero size!" msgstr "{path} 為零尺寸!" +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} 未以 \"fdroid\" 結尾,檢查 URL 路徑!" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} 未以 \"fdroid\" 結尾,檢查 URL 路徑!" + #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" @@ -2244,6 +2659,16 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} 編譯成功" +#, fuzzy +#~ msgid "Add PGP signatures for packages in repo using GnuPG" +#~ msgstr "在軟體倉庫中加入套件包的 gpg 簽署" + +#~ msgid "Add gpg signatures for packages in repo" +#~ msgstr "在軟體倉庫中加入套件包的 gpg 簽署" + +#~ msgid "Clean update - don't uses caches, reprocess all apks" +#~ msgstr "清除更新 - 不使用快取,重新處理全部的 apk" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "以對話方式詢問需要更新的內容。" @@ -2256,16 +2681,6 @@ msgstr[0] "{} 編譯成功" #~ msgid "Specify editor to use in interactive mode. Default is {path}" #~ msgstr "指定編輯器在互動模式使用。預設 {path}" -#, fuzzy -#~ msgid "Add PGP signatures for packages in repo using GnuPG" -#~ msgstr "在軟體倉庫中加入套件包的 gpg 簽署" - -#~ msgid "Add gpg signatures for packages in repo" -#~ msgstr "在軟體倉庫中加入套件包的 gpg 簽署" - -#~ msgid "Clean update - don't uses caches, reprocess all apks" -#~ msgstr "清除更新 - 不使用快取,重新處理全部的 apk" - #~ msgid "app-id in the form APPID" #~ msgstr "app-id,格式為 APPID" From e7edd96a02d7aa50849c5df9efc888079ec96451 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 12:43:32 +0200 Subject: [PATCH 0534/2775] gitlab-ci: use Alpine 3.11 for lint_format_safety_bandit_checks This should provide a current version of pip to make safety stop complaining. 3.12/3.11 breaks bandit, probably because of Python 3.8 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 148885d2..29422aaf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -145,7 +145,7 @@ pip_install: - fdroid update --help lint_format_safety_bandit_checks: - image: alpine:3.7 + image: alpine:3.10 # cannot upgrade until bandit supports Python 3.8 variables: LANG: C.UTF-8 script: From 465ec2e84e543a9720810eee40b457cc6cdd10f6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 17 Sep 2020 11:43:16 +0200 Subject: [PATCH 0535/2775] mirror-to-mirror.sh: also sync to ftp.lysator.liu.se, in parallel This is the deployed script for pushing to the primary mirrors. It starts with the 'repo' section and runs all the rsyncs in parallel to each primary mirror. Once the 'repo' syncs are done, it does the same process for the 'archive' syncs. [skip ci] --- examples/mirror-to-mirror.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/mirror-to-mirror.sh b/examples/mirror-to-mirror.sh index fa7e88b5..ecb4c10e 100644 --- a/examples/mirror-to-mirror.sh +++ b/examples/mirror-to-mirror.sh @@ -14,11 +14,15 @@ flock -n 200 set -e cd /home/fdroid for section in repo archive; do - for host in fdroid@mirror.f-droid.org; do - # be super careful with the trailing slashes here! if one is wrong, it'll delete the entire section! - rsync --archive --delay-updates --progress --delete \ - /home/fdroid/public_html/${section} \ - ${host}:/srv/fdroid-mirror.at.or.at/htdocs/fdroid/ + echo "Started $section at `date`:" + for host in fdroid@mirror.f-droid.org fdroid@ftp-push.lysator.liu.se; do + set -x + # be super careful with the trailing slashes here! if one is wrong, it'll delete the entire section! + rsync --archive --delay-updates --progress --delete \ + /home/fdroid/public_html/${section} \ + ${host}:/srv/fdroid-mirror.at.or.at/htdocs/fdroid/ & + set +x done + wait done ) 200>/var/lock/root_fdroidmirrortomirror From 9f394ead4b4457dcfdbb0872977e739fa88d1952 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 20:53:06 +0200 Subject: [PATCH 0536/2775] fix test suite for non-GNU: remove GNUisms * date --date= does not exist on BSD --- tests/run-tests | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/run-tests b/tests/run-tests index 77d2734d..5a5cc232 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -620,8 +620,7 @@ echo "com.politedroid_4.apk com.politedroid 2016-01-01" > stats/known_apks.txt echo "com.politedroid_5.apk com.politedroid 2017-01-01" >> stats/known_apks.txt echo "com.politedroid_6.apk com.politedroid 2018-01-01" >> stats/known_apks.txt sed -i -e 's/ArchivePolicy:.*/ArchivePolicy: 1 versions/' metadata/com.politedroid.yml -# Get the java ms timestamp from UTC time -timestamp=$(date -u --date=2017-01-01 +%s)000 +timestamp=1483228800 # $(date -u --date=2017-01-01 +%s)000 $fdroid update --pretty --nosign grep -F "\"added\": $timestamp" repo/index-v1.json From 4d972ea61546333156b6710de2799cee1f125ff2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 15:01:04 +0200 Subject: [PATCH 0537/2775] travis-ci: update jobs to run on current and oldest supported macOS --- .travis.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0a10bcb0..a012541b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,15 +5,11 @@ language: java matrix: include: - os: osx - osx_image: xcode10.2 + osx_image: xcode12 env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk env: ANDROID_HOME=/usr/local/share/android-sdk - os: osx - osx_image: xcode9.3 - env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk - env: ANDROID_HOME=/usr/local/share/android-sdk - - os: osx - osx_image: xcode8.3 + osx_image: xcode10.3 env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk env: ANDROID_HOME=/usr/local/share/android-sdk @@ -49,7 +45,7 @@ install: - travis_retry brew cask install adoptopenjdk8 - travis_retry brew cask install android-sdk - - export AAPT_VERSION=`sed -n "s,^MINIMUM_AAPT_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py` + - export AAPT_VERSION=`sed -n "s,^MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION\s*=\s*['\"]\(.*\)[['\"],\1,p" fdroidserver/common.py` - mkdir -p "$ANDROID_HOME/licenses" - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license" - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> "$ANDROID_HOME/licenses/android-sdk-license" From 9c852d4e8d06e2afb24f48af7323bd50e972b55a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 14:55:32 +0200 Subject: [PATCH 0538/2775] first alpha 2.0 release 2.0a0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 44cec5bd..363f686a 100755 --- a/setup.py +++ b/setup.py @@ -53,7 +53,7 @@ with open("README.md", "r") as fh: long_description = fh.read() setup(name='fdroidserver', - version='1.2a', + version='2.0a0', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From 5e1377c77a11c3d3089e3b3378fcca98d98c37a8 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 11:28:09 +0200 Subject: [PATCH 0539/2775] standardize on "Application ID" in UI text --- fdroidserver/build.py | 2 +- fdroidserver/checkupdates.py | 2 +- fdroidserver/common.py | 2 +- fdroidserver/install.py | 2 +- fdroidserver/lint.py | 4 +-- fdroidserver/metadata.py | 6 +++-- fdroidserver/publish.py | 2 +- fdroidserver/rewritemeta.py | 2 +- fdroidserver/scanner.py | 2 +- fdroidserver/update.py | 6 ++--- fdroidserver/verify.py | 2 +- locale/fdroidserver.pot | 51 ++++++++++++++++++++++++++---------- 12 files changed, 54 insertions(+), 29 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index b3d4cd54..96337813 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -873,7 +873,7 @@ def parse_commandline(): parser = argparse.ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") common.setup_global_opts(parser) - parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) + parser.add_argument("appid", nargs='*', help=_("application ID with optional versionCode in the form APPID[:VERCODE]")) parser.add_argument("-l", "--latest", action="store_true", default=False, help=_("Build only the latest version of each package")) parser.add_argument("-s", "--stop", action="store_true", default=False, diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 52f1ceb4..3adc29af 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -599,7 +599,7 @@ def main(): # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] [APPID [APPID ...]]") common.setup_global_opts(parser) - parser.add_argument("appid", nargs='*', help=_("applicationId to check for updates")) + parser.add_argument("appid", nargs='*', help=_("application ID of file to operate on")) parser.add_argument("--auto", action="store_true", default=False, help=_("Process auto-updates")) parser.add_argument("--autoonly", action="store_true", default=False, diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 610e0f74..82607ead 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1656,7 +1656,7 @@ def parse_androidmanifests(paths, app): max_version = "Unknown" if max_package: - msg = _("Invalid package name {0}").format(max_package) + msg = _("Invalid application ID {appid}").format(appid=max_package) if not is_valid_package_name(max_package): raise FDroidException(msg) elif not is_strict_application_id(max_package): diff --git a/fdroidserver/install.py b/fdroidserver/install.py index c4e4b7dd..0e50c27b 100644 --- a/fdroidserver/install.py +++ b/fdroidserver/install.py @@ -50,7 +50,7 @@ def main(): # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") common.setup_global_opts(parser) - parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) + parser.add_argument("appid", nargs='*', help=_("application ID with optional versionCode in the form APPID[:VERCODE]")) parser.add_argument("-a", "--all", action="store_true", default=False, help=_("Install all signed applications available")) options = parser.parse_args() diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index f94d0e28..41d38551 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -278,7 +278,7 @@ def check_old_links(app): def check_useless_fields(app): if app.UpdateCheckName == app.id: - yield _("Update Check Name is set to the known app id - it can be removed") + yield _("UpdateCheckName is set to the known application ID, it can be removed") filling_ucms = re.compile(r'^(Tags.*|RepoManifest.*)') @@ -575,7 +575,7 @@ def main(): parser.add_argument('--force-yamllint', action="store_true", default=False, help=_("When linting the entire repository yamllint is disabled by default. " "This option forces yamllint regardless.")) - parser.add_argument("appid", nargs='*', help=_("applicationId in the form APPID")) + parser.add_argument("appid", nargs='*', help=_("application ID of file to operate on")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index d93d8b91..79195289 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -1189,11 +1189,13 @@ class DescriptionResolver: if appid in self.apps: if self.apps[appid].Name: return "fdroid.app:" + appid, self.apps[appid].Name - raise MetaDataException("Cannot resolve app id " + appid) + raise MetaDataException(_('Cannot resolve application ID {appid}') + .format(appid=appid)) class DummyDescriptionResolver(DescriptionResolver): def resolve_description_link(self, appid): if appid in self.apps: return "fdroid.app:" + appid, "Dummy name - don't know yet" - _warn_or_exception(_("Cannot resolve app id {appid}").format(appid=appid)) + _warn_or_exception(_('Cannot resolve application ID {appid}') + .format(appid=appid)) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index 50492fe2..41d70300 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -225,7 +225,7 @@ def main(): "[APPID[:VERCODE] [APPID[:VERCODE] ...]]") common.setup_global_opts(parser) parser.add_argument("appid", nargs='*', - help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) + help=_("application ID with optional versionCode in the form APPID[:VERCODE]")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 5b1c1927..3b89e6bf 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -54,7 +54,7 @@ def main(): common.setup_global_opts(parser) parser.add_argument("-l", "--list", action="store_true", default=False, help=_("List files that would be reformatted")) - parser.add_argument("appid", nargs='*', help=_("applicationId in the form APPID")) + parser.add_argument("appid", nargs='*', help=_("application ID of file to operate on")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 8b1a31cf..2757526c 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -373,7 +373,7 @@ def main(): # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") common.setup_global_opts(parser) - parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) + parser.add_argument("appid", nargs='*', help=_("application ID with optional versionCode in the form APPID[:VERCODE]")) parser.add_argument("-f", "--force", action="store_true", default=False, help=_("Force scan of disabled apps and builds.")) parser.add_argument("--json", action="store_true", default=False, diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 5936e502..0849442b 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1356,7 +1356,7 @@ def scan_apk(apk_file): raise BuildException(_("{appid} from {path} is not a valid Java Package Name!") .format(appid=apk['packageName'], path=apk_file)) elif not common.is_strict_application_id(apk['packageName']): - logging.warning(_("{appid} from {path} is not a valid Android Package Name!") + logging.warning(_("{appid} from {path} is not a valid Android application ID!") .format(appid=apk['packageName'], path=apk_file)) # Get the signature, or rather the signing key fingerprints @@ -2126,7 +2126,7 @@ def create_metadata_from_template(apk): metatxt, flags=re.IGNORECASE | re.MULTILINE) else: - logging.warning(_('{appid} does not have a name! Using package name instead.') + logging.warning(_('{appid} does not have a name! Using application ID instead.') .format(appid=apk['packageName'])) metatxt = re.sub(r'^(((Auto)?Name|Summary):).*$', r'\1 ' + apk['packageName'], @@ -2152,7 +2152,7 @@ def create_metadata_from_template(apk): if 'name' in apk and apk['name'] != '': app['Name'] = apk['name'] else: - logging.warning(_('{appid} does not have a name! Using package name instead.') + logging.warning(_('{appid} does not have a name! Using application ID instead.') .format(appid=apk['packageName'])) app['Name'] = apk['packageName'] with open(os.path.join('metadata', apk['packageName'] + '.yml'), 'w') as f: diff --git a/fdroidserver/verify.py b/fdroidserver/verify.py index bd1433d2..664d06d4 100644 --- a/fdroidserver/verify.py +++ b/fdroidserver/verify.py @@ -121,7 +121,7 @@ def main(): # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") common.setup_global_opts(parser) - parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) + parser.add_argument("appid", nargs='*', help=_("application ID with optional versionCode in the form APPID[:VERCODE]")) parser.add_argument("--reuse-remote-apk", action="store_true", default=False, help=_("Verify against locally cached copy rather than redownloading.")) parser.add_argument("--output-json", action="store_true", default=False, diff --git a/locale/fdroidserver.pot b/locale/fdroidserver.pot index 7c621b18..dbe2eebd 100644 --- a/locale/fdroidserver.pot +++ b/locale/fdroidserver.pot @@ -5,9 +5,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" +"Project-Id-Version: fdroidserver 1.1-681-gc19e8952\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -371,24 +371,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -483,6 +474,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -998,6 +990,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1864,8 +1861,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "Update Check Name is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1899,6 +1897,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2045,6 +2047,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2538,6 +2551,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2548,6 +2566,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" From b23cf9f8ad15d8c38593c2544f3a166475c4dc13 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 11:52:22 +0200 Subject: [PATCH 0540/2775] use YAML names for referring to metadata fields in messages --- fdroidserver/checkupdates.py | 6 +++--- fdroidserver/lint.py | 4 ++-- locale/bn/LC_MESSAGES/fdroidserver.po | 2 +- locale/bo/LC_MESSAGES/fdroidserver.po | 4 ++-- locale/cs/LC_MESSAGES/fdroidserver.po | 2 +- locale/de/LC_MESSAGES/fdroidserver.po | 4 ++-- locale/es/LC_MESSAGES/fdroidserver.po | 2 +- locale/es_AR/LC_MESSAGES/fdroidserver.po | 2 +- locale/es_MX/LC_MESSAGES/fdroidserver.po | 2 +- locale/fa/LC_MESSAGES/fdroidserver.po | 2 +- locale/fdroidserver.pot | 6 +++--- locale/fr/LC_MESSAGES/fdroidserver.po | 2 +- locale/hu/LC_MESSAGES/fdroidserver.po | 2 +- locale/it/LC_MESSAGES/fdroidserver.po | 2 +- locale/ja/LC_MESSAGES/fdroidserver.po | 2 +- locale/kab/LC_MESSAGES/fdroidserver.po | 2 +- locale/ko/LC_MESSAGES/fdroidserver.po | 2 +- locale/ml/LC_MESSAGES/fdroidserver.po | 2 +- locale/nb_NO/LC_MESSAGES/fdroidserver.po | 4 ++-- locale/pl/LC_MESSAGES/fdroidserver.po | 4 ++-- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 4 ++-- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 4 ++-- locale/ru/LC_MESSAGES/fdroidserver.po | 2 +- locale/sk/LC_MESSAGES/fdroidserver.po | 2 +- locale/sq/LC_MESSAGES/fdroidserver.po | 4 ++-- locale/sv/LC_MESSAGES/fdroidserver.po | 2 +- locale/tr/LC_MESSAGES/fdroidserver.po | 4 ++-- locale/ug/LC_MESSAGES/fdroidserver.po | 2 +- locale/uk/LC_MESSAGES/fdroidserver.po | 2 +- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 2 +- locale/zh_Hant/LC_MESSAGES/fdroidserver.po | 4 ++-- 31 files changed, 45 insertions(+), 45 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 3adc29af..d2833b81 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -487,12 +487,12 @@ def checkupdates_app(app): name = _getappname(app) ver = _getcvname(app) logging.info('...updating to version %s' % ver) - commitmsg = 'Update CV of %s to %s' % (name, ver) + commitmsg = 'Update CurrentVersion of %s to %s' % (name, ver) if options.auto: mode = app.AutoUpdateMode if not app.CurrentVersionCode: - logging.warning("Can't auto-update app with no current version code: " + app.id) + logging.warning("Can't auto-update app with no CurrentVersionCode: " + app.id) elif mode in ('None', 'Static'): pass elif mode.startswith('Version '): @@ -502,7 +502,7 @@ def checkupdates_app(app): try: suffix, pattern = pattern[1:].split(' ', 1) except ValueError: - raise MetaDataException("Invalid AUM: " + mode) + raise MetaDataException("Invalid AutoUpdateMode: " + mode) gotcur = False latest = None diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 41d38551..a2e6578d 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -242,7 +242,7 @@ def check_ucm_tags(app): and lastbuild.versionCode == app.CurrentVersionCode and not lastbuild.forcevercode and any(s in lastbuild.commit for s in '.,_-/')): - yield _("Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'")\ + yield _("Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'")\ .format(commit=lastbuild.commit, ucm=app.UpdateCheckMode) @@ -287,7 +287,7 @@ filling_ucms = re.compile(r'^(Tags.*|RepoManifest.*)') def check_checkupdates_ran(app): if filling_ucms.match(app.UpdateCheckMode): if not app.AutoName and not app.CurrentVersion and app.CurrentVersionCode == '0': - yield _("UCM is set but it looks like checkupdates hasn't been run yet") + yield _("UpdateCheckMode is set but it looks like checkupdates hasn't been run yet") def check_empty_fields(app): diff --git a/locale/bn/LC_MESSAGES/fdroidserver.po b/locale/bn/LC_MESSAGES/fdroidserver.po index 8af6283e..f809bf43 100644 --- a/locale/bn/LC_MESSAGES/fdroidserver.po +++ b/locale/bn/LC_MESSAGES/fdroidserver.po @@ -1717,7 +1717,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/bo/LC_MESSAGES/fdroidserver.po b/locale/bo/LC_MESSAGES/fdroidserver.po index 4aceece8..7db00157 100644 --- a/locale/bo/LC_MESSAGES/fdroidserver.po +++ b/locale/bo/LC_MESSAGES/fdroidserver.po @@ -1736,8 +1736,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "awsbucket, awssecretkey དང་། awsaccesskeyid བེད་སྤྱོད་བྱེད་པའི་ཆེད་དུ་ config.py ནང་དུ་ངེས་པར་དུ་སྒྲིག་དགོས།!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCMསྒྲིག་བཀོད་བྱས་ཟིན་ཡང་གསར་བསྒྱུར་འཚོལ་བ་དེ་འགོ་འཛུགས་མིན་འདུག" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckModeསྒྲིག་བཀོད་བྱས་ཟིན་ཡང་གསར་བསྒྱུར་འཚོལ་བ་དེ་འགོ་འཛུགས་མིན་འདུག" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" diff --git a/locale/cs/LC_MESSAGES/fdroidserver.po b/locale/cs/LC_MESSAGES/fdroidserver.po index af51ae76..2bbe38bc 100644 --- a/locale/cs/LC_MESSAGES/fdroidserver.po +++ b/locale/cs/LC_MESSAGES/fdroidserver.po @@ -1722,7 +1722,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index 8894de30..6fa96719 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -1737,8 +1737,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Um awsbucket zu benutzen, müssen awssecretkey und awsaccesskeyid auch in der config.py gesetzt sein!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM ist gesetzt, aber es sieht so aus, als ob checkupdates noch nicht ausgeführt wurde" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode ist gesetzt, aber es sieht so aus, als ob checkupdates noch nicht ausgeführt wurde" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index 96dd69ed..7c0787fb 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -1737,7 +1737,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/es_AR/LC_MESSAGES/fdroidserver.po b/locale/es_AR/LC_MESSAGES/fdroidserver.po index 223c571d..3051859d 100644 --- a/locale/es_AR/LC_MESSAGES/fdroidserver.po +++ b/locale/es_AR/LC_MESSAGES/fdroidserver.po @@ -1738,7 +1738,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/es_MX/LC_MESSAGES/fdroidserver.po b/locale/es_MX/LC_MESSAGES/fdroidserver.po index c25e861c..06690259 100644 --- a/locale/es_MX/LC_MESSAGES/fdroidserver.po +++ b/locale/es_MX/LC_MESSAGES/fdroidserver.po @@ -1721,7 +1721,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/fa/LC_MESSAGES/fdroidserver.po b/locale/fa/LC_MESSAGES/fdroidserver.po index 974e4056..ef1cb43f 100644 --- a/locale/fa/LC_MESSAGES/fdroidserver.po +++ b/locale/fa/LC_MESSAGES/fdroidserver.po @@ -1719,7 +1719,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/fdroidserver.pot b/locale/fdroidserver.pot index dbe2eebd..cb5017a6 100644 --- a/locale/fdroidserver.pot +++ b/locale/fdroidserver.pot @@ -1104,7 +1104,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1715,7 +1715,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py @@ -1863,7 +1863,7 @@ msgstr "" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known application ID - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 8436749a..b63ed756 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -1748,7 +1748,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/hu/LC_MESSAGES/fdroidserver.po b/locale/hu/LC_MESSAGES/fdroidserver.po index 2b736420..7b520df0 100644 --- a/locale/hu/LC_MESSAGES/fdroidserver.po +++ b/locale/hu/LC_MESSAGES/fdroidserver.po @@ -1724,7 +1724,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index ad493220..4d2c68c3 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -1735,7 +1735,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/ja/LC_MESSAGES/fdroidserver.po b/locale/ja/LC_MESSAGES/fdroidserver.po index 06a01427..a9fe7a47 100644 --- a/locale/ja/LC_MESSAGES/fdroidserver.po +++ b/locale/ja/LC_MESSAGES/fdroidserver.po @@ -1714,7 +1714,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/kab/LC_MESSAGES/fdroidserver.po b/locale/kab/LC_MESSAGES/fdroidserver.po index 173b59b4..ca1e28e2 100644 --- a/locale/kab/LC_MESSAGES/fdroidserver.po +++ b/locale/kab/LC_MESSAGES/fdroidserver.po @@ -1717,7 +1717,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/ko/LC_MESSAGES/fdroidserver.po b/locale/ko/LC_MESSAGES/fdroidserver.po index 4e70572f..340cdab5 100644 --- a/locale/ko/LC_MESSAGES/fdroidserver.po +++ b/locale/ko/LC_MESSAGES/fdroidserver.po @@ -1723,7 +1723,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/ml/LC_MESSAGES/fdroidserver.po b/locale/ml/LC_MESSAGES/fdroidserver.po index c2f1b635..06d11bc2 100644 --- a/locale/ml/LC_MESSAGES/fdroidserver.po +++ b/locale/ml/LC_MESSAGES/fdroidserver.po @@ -1717,7 +1717,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index dbdd63d9..a10512c3 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -1787,8 +1787,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "For å bruke AWS-spann, må \"awssecretkey\" og \"awsaccesskeyid\" også være satt i config.py." #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM er satt, men det ser ut til at checkupdates ikke har blitt kjørt enda." +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode er satt, men det ser ut til at checkupdates ikke har blitt kjørt enda." #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index d897ec44..ff90bdea 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -1739,8 +1739,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Aby użyć awsbucket, awssecretkey i awsaccesskeyid muszą być również ustawione w config.py!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM jest ustawione, ale wygląda na to, że checkupdates nie zostało jeszcze uruchomione" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode jest ustawione, ale wygląda na to, że checkupdates nie zostało jeszcze uruchomione" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index ed984f9b..30f0a62b 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -1738,8 +1738,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser definidos no config.py!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM é definido, mas parece que checkupdates ainda não foi executado" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index 3fc24a50..4e88f9bc 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -1739,8 +1739,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser definidos no config.py!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM é definido, mas parece que checkupdates ainda não foi executado" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 3a6e3072..d5df27c7 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -1743,7 +1743,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Необходимо определить переменные awsbucket, awssecretkey и awsaccesskeyid в config.py!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "Режим проверки обновлений (Update Check Mode) выбран, но проверка еще ни разу не выполнялась" #: ../fdroidserver/lint.py diff --git a/locale/sk/LC_MESSAGES/fdroidserver.po b/locale/sk/LC_MESSAGES/fdroidserver.po index 7a6bcc26..06141fa4 100644 --- a/locale/sk/LC_MESSAGES/fdroidserver.po +++ b/locale/sk/LC_MESSAGES/fdroidserver.po @@ -1719,7 +1719,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/sq/LC_MESSAGES/fdroidserver.po b/locale/sq/LC_MESSAGES/fdroidserver.po index ef73e829..80340a99 100644 --- a/locale/sq/LC_MESSAGES/fdroidserver.po +++ b/locale/sq/LC_MESSAGES/fdroidserver.po @@ -1736,8 +1736,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Për të përdorur awsbucket, te config.py duhen ujdisur edhe awssecretkey dhe awsaccesskey!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM është ujdisur, por duket sikur checkupdates s’është xhiruar ende" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode është ujdisur, por duket sikur checkupdates s’është xhiruar ende" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" diff --git a/locale/sv/LC_MESSAGES/fdroidserver.po b/locale/sv/LC_MESSAGES/fdroidserver.po index e24ac13a..70f6ba3c 100644 --- a/locale/sv/LC_MESSAGES/fdroidserver.po +++ b/locale/sv/LC_MESSAGES/fdroidserver.po @@ -1718,7 +1718,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index 27722576..3a328e6f 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -1736,8 +1736,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Awsbucket kullanmak için, awssecretkey ve awsaccesskeyid de config.py içinde ayarlanmalı!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM ayarlı ancak checkupdates henüz çalıştırılmamış gibi görünüyor" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode ayarlı ancak checkupdates henüz çalıştırılmamış gibi görünüyor" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" diff --git a/locale/ug/LC_MESSAGES/fdroidserver.po b/locale/ug/LC_MESSAGES/fdroidserver.po index f76ca690..fda6cb7f 100644 --- a/locale/ug/LC_MESSAGES/fdroidserver.po +++ b/locale/ug/LC_MESSAGES/fdroidserver.po @@ -1718,7 +1718,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index 0cda8b8d..e52b8b03 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -1740,7 +1740,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Для використання awsbucket, awssecretkey та awsaccesskeyid також слід налаштувати config.py!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "Режим перевірки оновлень встановлено, але схоже, що ще не запущено перевірку" #: ../fdroidserver/lint.py diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index a7dc2150..1da742bd 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -1729,7 +1729,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index d24bca1b..5daf4083 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -1734,8 +1734,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "要使用 awsbucket, awssecretkey 與 awsaccesskeyid 必須在 config.py 進行設定!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM 已被設定但它似乎尚未曾執行更新檢查" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode 已被設定但它似乎尚未曾執行更新檢查" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" From fede58a71078ddf07aac074c67aeea3854cd0569 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 12:17:02 +0200 Subject: [PATCH 0541/2775] use ArgumentParser's own "usage" line in help output --- fdroidserver/btlog.py | 2 +- fdroidserver/checkupdates.py | 2 +- fdroidserver/gpgsign.py | 2 +- fdroidserver/lint.py | 2 +- fdroidserver/mirror.py | 2 +- fdroidserver/nightly.py | 2 +- fdroidserver/readmeta.py | 2 +- fdroidserver/rewritemeta.py | 3 +-- fdroidserver/signatures.py | 4 +--- fdroidserver/signindex.py | 3 +-- 10 files changed, 10 insertions(+), 14 deletions(-) diff --git a/fdroidserver/btlog.py b/fdroidserver/btlog.py index 43ea2313..08993aec 100755 --- a/fdroidserver/btlog.py +++ b/fdroidserver/btlog.py @@ -148,7 +148,7 @@ For more info on this idea: def main(): global options - parser = ArgumentParser(usage="%(prog)s [options]") + parser = ArgumentParser() common.setup_global_opts(parser) parser.add_argument("--git-repo", default=os.path.join(os.getcwd(), 'binary_transparency'), diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index d2833b81..604f4e1a 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -597,7 +597,7 @@ def main(): global config, options # Parse command line... - parser = ArgumentParser(usage="%(prog)s [options] [APPID [APPID ...]]") + parser = ArgumentParser() common.setup_global_opts(parser) parser.add_argument("appid", nargs='*', help=_("application ID of file to operate on")) parser.add_argument("--auto", action="store_true", default=False, diff --git a/fdroidserver/gpgsign.py b/fdroidserver/gpgsign.py index a224c3f7..86258b63 100644 --- a/fdroidserver/gpgsign.py +++ b/fdroidserver/gpgsign.py @@ -47,7 +47,7 @@ def main(): global config, options # Parse command line... - parser = ArgumentParser(usage="%(prog)s [options]") + parser = ArgumentParser() common.setup_global_opts(parser) options = parser.parse_args() diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index a2e6578d..dd48e05f 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -568,7 +568,7 @@ def main(): global config, options # Parse command line... - parser = ArgumentParser(usage="%(prog)s [options] [APPID [APPID ...]]") + parser = ArgumentParser() common.setup_global_opts(parser) parser.add_argument("-f", "--format", action="store_true", default=False, help=_("Also warn about formatting issues, like rewritemeta -l")) diff --git a/fdroidserver/mirror.py b/fdroidserver/mirror.py index 2510e3d0..983a9dcd 100644 --- a/fdroidserver/mirror.py +++ b/fdroidserver/mirror.py @@ -41,7 +41,7 @@ def _run_wget(path, urls): def main(): global options - parser = ArgumentParser(usage=_("%(prog)s [options] url")) + parser = ArgumentParser() common.setup_global_opts(parser) parser.add_argument("url", nargs='?', help=_('Base URL to mirror, can include the index signing key ' diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index daca2082..671c217a 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -88,7 +88,7 @@ def _ssh_key_from_debug_keystore(keystore=KEYSTORE_FILE): def main(): - parser = ArgumentParser(usage="%(prog)s") + parser = ArgumentParser() common.setup_global_opts(parser) parser.add_argument("--keystore", default=KEYSTORE_FILE, help=_("Specify which debug keystore file to use.")) diff --git a/fdroidserver/readmeta.py b/fdroidserver/readmeta.py index 7ec1cb05..f9688658 100644 --- a/fdroidserver/readmeta.py +++ b/fdroidserver/readmeta.py @@ -25,7 +25,7 @@ options = None def main(): - parser = ArgumentParser(usage="%(prog)s") + parser = ArgumentParser() common.setup_global_opts(parser) metadata.add_metadata_arguments(parser) options = parser.parse_args() diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 3b89e6bf..5a6a10a3 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -49,8 +49,7 @@ def main(): global config, options - # Parse command line... - parser = ArgumentParser(usage="%(prog)s [options] [APPID [APPID ...]]") + parser = ArgumentParser() common.setup_global_opts(parser) parser.add_argument("-l", "--list", action="store_true", default=False, help=_("List files that would be reformatted")) diff --git a/fdroidserver/signatures.py b/fdroidserver/signatures.py index 79bea6a1..78f4bcd3 100644 --- a/fdroidserver/signatures.py +++ b/fdroidserver/signatures.py @@ -87,9 +87,7 @@ def extract(options): def main(): - - # Parse command line... - parser = ArgumentParser(usage="%(prog)s [options] APK [APK...]") + parser = ArgumentParser() common.setup_global_opts(parser) parser.add_argument("APK", nargs='*', help=_("signed APK, either a file-path or HTTPS URL.")) diff --git a/fdroidserver/signindex.py b/fdroidserver/signindex.py index 693b127e..2c5859d5 100644 --- a/fdroidserver/signindex.py +++ b/fdroidserver/signindex.py @@ -91,8 +91,7 @@ def main(): global config, options - # Parse command line... - parser = ArgumentParser(usage="%(prog)s [options]") + parser = ArgumentParser() common.setup_global_opts(parser) options = parser.parse_args() From 0d5fde334df7fb8d130b52c78d6e5d30825f37a3 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 7 Oct 2020 16:02:08 +0200 Subject: [PATCH 0542/2775] fix keytool not working with default smartcardoptions This broke in 74af61f255fc492fbdfe061e71084b86f58bcc28. Keytool has still a different opinion from both apksigner and jarsigner about the providerName argument. apksigner doesn't support it at all, jarsigner ignores it but keytool fails without it. :-/ So we add it back to the default argument list but filter it out before calling apksigner. --- examples/config.py | 2 +- fdroidserver/common.py | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/config.py b/examples/config.py index 7b43976c..fc30af15 100644 --- a/examples/config.py +++ b/examples/config.py @@ -131,7 +131,7 @@ The repository of older versions of applications from the main demo repository. # You should not need to change these at all, unless you have a very # customized setup for using smartcards in Java with keytool/jarsigner -# smartcardoptions = "-storetype PKCS11 \ +# smartcardoptions = "-storetype PKCS11 -providerName SunPKCS11-OpenSC \ # -providerClass sun.security.pkcs11.SunPKCS11 \ # -providerArg opensc-fdroid.cfg" diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 610e0f74..4131f5af 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -323,7 +323,8 @@ def read_config(opts, config_file='config.py'): config['smartcardoptions'] = re.sub(r'\s+', r' ', config['smartcardoptions']).split(' ') elif not smartcardoptions and 'keystore' in config and config['keystore'] == 'NONE': # keystore='NONE' means use smartcard, these are required defaults - config['smartcardoptions'] = ['-storetype', 'PKCS11', '-providerClass', + config['smartcardoptions'] = ['-storetype', 'PKCS11', '-providerName', + 'SunPKCS11-OpenSC', '-providerClass', 'sun.security.pkcs11.SunPKCS11', '-providerArg', 'opensc-fdroid.cfg'] @@ -3082,15 +3083,21 @@ def sign_apk(unsigned_path, signed_path, keyalias): apk = _get_androguard_APK(unsigned_path) if apk.get_effective_target_sdk_version() >= 30: if config['keystore'] == 'NONE': - # NOTE: apksigner doesn't like -providerName/--provider-name at all, don't use + # NOTE: apksigner doesn't like -providerName/--provider-name at all, don't use that. # apksigner documents the options as --ks-provider-class and --ks-provider-arg # those seem to be accepted but fail when actually making a signature with # weird internal exceptions. Those options actually work. # From: https://geoffreymetais.github.io/code/key-signing/#scripting + apksigner_smartcardoptions = config['smartcardoptions'].copy() + if '-providerName' in apksigner_smartcardoptions: + pos = config['smartcardoptions'].index('-providerName') + # remove -providerName and it's argument + del apksigner_smartcardoptions[pos] + del apksigner_smartcardoptions[pos] replacements = {'-storetype': '--ks-type', '-providerClass': '--provider-class', '-providerArg': '--provider-arg'} - signing_args = [replacements.get(n, n) for n in config['smartcardoptions']] + signing_args = [replacements.get(n, n) for n in apksigner_smartcardoptions] else: signing_args = ['--key-pass', 'env:FDROID_KEY_PASS'] if not find_apksigner(): From 283f10dec1f8b9517c9a59b962860a28898a60d5 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 10:02:05 +0200 Subject: [PATCH 0543/2775] index: generate repo icon if missing, and add tests --- fdroidserver/index.py | 17 +++++++++++++++-- tests/index.TestCase | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 6d247141..d89e5cb8 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -593,8 +593,21 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing # Copy the repo icon into the repo directory... icon_dir = os.path.join(repodir, 'icons') - iconfilename = os.path.join(icon_dir, os.path.basename(common.config['repo_icon'])) - shutil.copyfile(common.config['repo_icon'], iconfilename) + repo_icon = common.config.get('repo_icon', common.default_config['repo_icon']) + iconfilename = os.path.join(icon_dir, os.path.basename(repo_icon)) + if os.path.exists(repo_icon): + shutil.copyfile(common.config['repo_icon'], iconfilename) + else: + logging.warning(_('repo_icon %s does not exist, generating placeholder.') + % repo_icon) + os.makedirs(os.path.dirname(iconfilename), exist_ok=True) + try: + import qrcode + qrcode.make(common.config['repo_url']).save(iconfilename) + except Exception: + exampleicon = os.path.join(common.get_examples_dir(), + common.default_config['repo_icon']) + shutil.copy(exampleicon, iconfilename) def extract_pubkey(): diff --git a/tests/index.TestCase b/tests/index.TestCase index 5fb56f10..10a5b9a6 100755 --- a/tests/index.TestCase +++ b/tests/index.TestCase @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import datetime import inspect import logging import optparse @@ -29,17 +30,25 @@ from testcommon import TmpCwd GP_FINGERPRINT = 'B7C2EEFD8DAC7806AF67DFCD92EB18126BC08312A7F2D6F3862E46013C7A6135' +class Options: + nosign = True + pretty = False + verbose = False + + class IndexTest(unittest.TestCase): def setUp(self): logging.basicConfig(level=logging.DEBUG) self.basedir = os.path.join(localmodule, 'tests') + os.chmod(os.path.join(self.basedir, 'config.py'), 0o600) self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) if not os.path.exists(self.tmpdir): os.makedirs(self.tmpdir) os.chdir(self.basedir) fdroidserver.common.config = None + fdroidserver.common.options = Options config = fdroidserver.common.read_config(fdroidserver.common.options) config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') fdroidserver.common.config = config @@ -215,6 +224,29 @@ class IndexTest(unittest.TestCase): self.maxDiff = None self.assertEqual(json.dumps(i, indent=2), json.dumps(o, indent=2)) + def test_make_v0(self): + tmptestsdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, + dir=self.tmpdir) + os.chdir(tmptestsdir) + os.mkdir('repo') + repo_icons_dir = os.path.join('repo', 'icons') + self.assertFalse(os.path.isdir(repo_icons_dir)) + repodict = { + 'address': 'https://example.com/fdroid/repo', + 'description': 'This is just a test', + 'icon': 'blahblah', + 'name': 'test', + 'timestamp': datetime.datetime.now(), + 'version': 12, + } + requestsdict = {'install': [], 'uninstall': []} + fdroidserver.common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff' + fdroidserver.index.make_v0({}, [], 'repo', repodict, requestsdict, []) + self.assertTrue(os.path.isdir(repo_icons_dir)) + self.assertTrue(os.path.exists(os.path.join(repo_icons_dir, + fdroidserver.common.default_config['repo_icon']))) + self.assertTrue(os.path.exists(os.path.join('repo', 'index.xml'))) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) @@ -222,7 +254,8 @@ if __name__ == "__main__": parser = optparse.OptionParser() parser.add_option("-v", "--verbose", action="store_true", default=False, help="Spew out even more information than normal") - (fdroidserver.common.options, args) = parser.parse_args(['--verbose']) + (options, args) = parser.parse_args() + Options.verbose = options.verbose newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(IndexTest)) From 790b5a2888444e9f69c9dba8b724f18c40c81980 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 10:04:30 +0200 Subject: [PATCH 0544/2775] update: use "app" as dict not App instance in apply_info_from_latest_apk This allows update.apply_info_from_latest_apk() to be used as part of the API. This way "app" can be a dict or an App instance. --- fdroidserver/index.py | 2 +- fdroidserver/update.py | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index d89e5cb8..078b64fb 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -61,7 +61,7 @@ def make(apps, apks, repodir, archive): common.assert_config_keystore(common.config) # Historically the index has been sorted by App Name, so we enforce this ordering here - sortedids = sorted(apps, key=lambda appid: apps[appid].Name.upper()) + sortedids = sorted(apps, key=lambda appid: apps[appid]['Name'].upper()) sortedapps = collections.OrderedDict() for appid in sortedids: sortedapps[appid] = apps[appid] diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 0849442b..3f2903d1 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1971,26 +1971,26 @@ def apply_info_from_latest_apk(apps, apks): bestver = apk['versionCode'] bestapk = apk - if app.NoSourceSince: + if app['NoSourceSince']: apk['antiFeatures'].add('NoSourceSince') - if not app.added: + if not app['added']: logging.debug("Don't know when " + appid + " was added") - if not app.lastUpdated: + if not app['lastUpdated']: logging.debug("Don't know when " + appid + " was last updated") if bestver == UNSET_VERSION_CODE: - if app.Name is None: - app.Name = app.AutoName or appid - app.icon = None + if app['Name'] is None: + app['Name'] = app['AutoName'] or appid + app['icon'] = None logging.debug("Application " + appid + " has no packages") else: - if app.Name is None: - app.Name = bestapk['name'] - app.icon = bestapk['icon'] if 'icon' in bestapk else None - if app.CurrentVersionCode is None: - app.CurrentVersionCode = str(bestver) + if app['Name'] is None: + app['Name'] = bestapk['name'] + app['icon'] = bestapk['icon'] if 'icon' in bestapk else None + if app['CurrentVersionCode'] is None: + app['CurrentVersionCode'] = str(bestver) def make_categories_txt(repodir, categories): From 3c64996089376e5c10b7010d7c2bbe97ffe319b7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 10:08:49 +0200 Subject: [PATCH 0545/2775] update: test if options is instantated before using attributes This makes it possible to use process_apks(), get_cache(), and anything calling disabled_algorithms_allowed() as an API without having to set options up beforehand. --- fdroidserver/update.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 3f2903d1..6ffb0973 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -123,7 +123,9 @@ def get_all_icon_dirs(repodir): def disabled_algorithms_allowed(): - return options.allow_disabled_algorithms or config['allow_disabled_algorithms'] + return ((options is not None and options.allow_disabled_algorithms) + or (config is not None and config['allow_disabled_algorithms']) + or common.default_config['allow_disabled_algorithms']) def status_update_json(apps, apks): @@ -521,7 +523,7 @@ def get_cache(): """ apkcachefile = get_cache_file() ada = disabled_algorithms_allowed() - if not options.clean and os.path.exists(apkcachefile): + if options is not None and not options.clean and os.path.exists(apkcachefile): with open(apkcachefile) as fp: apkcache = json.load(fp, object_pairs_hook=collections.OrderedDict) if apkcache.get("METADATA_VERSION") != METADATA_VERSION \ @@ -1778,7 +1780,7 @@ def process_apks(apkcache, repodir, knownapks, use_date_from_apk=False): for icon_dir in get_all_icon_dirs(repodir): if os.path.exists(icon_dir): - if options.clean: + if options is not None and options.clean: shutil.rmtree(icon_dir) os.makedirs(icon_dir) else: From 05cd8c68109e533ed0e57154c05e6a6067803b70 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Oct 2020 10:22:32 +0200 Subject: [PATCH 0546/2775] scanner: expose "usual suspects" patterns for use in an API --- fdroidserver/scanner.py | 85 +++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 2757526c..8230831e 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -40,6 +40,47 @@ json_per_build = DEFAULT_JSON_PER_BUILD MAVEN_URL_REGEX = re.compile(r"""\smaven\s*{.*?(?:setUrl|url)\s*=?\s*(?:uri)?\(?\s*["']?([^\s"']+)["']?[^}]*}""", re.DOTALL) +CODE_SIGNATURES = { + # The `apkanalyzer dex packages` output looks like this: + # M d 1 1 93 + # The first column has P/C/M/F for package, class, method or field + # The second column has x/k/r/d for removed, kept, referenced and defined. + # We already filter for defined only in the apkanalyzer call. 'r' will be + # for things referenced but not distributed in the apk. + exp: re.compile(r'.[\s]*d[\s]*[0-9]*[\s]*[0-9*][\s]*[0-9]*[\s]*' + exp, re.IGNORECASE) for exp in [ + r'(com\.google\.firebase[^\s]*)', + r'(com\.google\.android\.gms[^\s]*)', + r'(com\.google\.tagmanager[^\s]*)', + r'(com\.google\.analytics[^\s]*)', + r'(com\.android\.billing[^\s]*)', + ] +} + +# Common known non-free blobs (always lower case): +NON_FREE_GRADLE_LINES = { + exp: re.compile(r'.*' + exp, re.IGNORECASE) for exp in [ + r'flurryagent', + r'paypal.*mpl', + r'admob.*sdk.*android', + r'google.*ad.*view', + r'google.*admob', + r'google.*play.*services', + r'crittercism', + r'heyzap', + r'jpct.*ae', + r'youtube.*android.*player.*api', + r'bugsense', + r'crashlytics', + r'ouya.*sdk', + r'libspen23', + r'firebase', + r'''["']com.facebook.android['":]''', + r'cloudrail', + r'com.tencent.bugly', + r'appcenter-push', + ] +} + def get_gradle_compile_commands(build): compileCommands = ['compile', @@ -59,25 +100,10 @@ def get_gradle_compile_commands(build): def scan_binary(apkfile): - usual_suspects = { - # The `apkanalyzer dex packages` output looks like this: - # M d 1 1 93 - # The first column has P/C/M/F for package, class, method or field - # The second column has x/k/r/d for removed, kept, referenced and defined. - # We already filter for defined only in the apkanalyzer call. 'r' will be - # for things referenced but not distributed in the apk. - exp: re.compile(r'.[\s]*d[\s]*[0-9]*[\s]*[0-9*][\s]*[0-9]*[\s]*' + exp, re.IGNORECASE) for exp in [ - r'(com\.google\.firebase[^\s]*)', - r'(com\.google\.android\.gms[^\s]*)', - r'(com\.google\.tagmanager[^\s]*)', - r'(com\.google\.analytics[^\s]*)', - r'(com\.android\.billing[^\s]*)', - ] - } logging.info("Scanning APK for known non-free classes.") result = common.SdkToolsPopen(["apkanalyzer", "dex", "packages", "--defined-only", apkfile], output=False) problems = 0 - for suspect, regexp in usual_suspects.items(): + for suspect, regexp in CODE_SIGNATURES.items(): matches = regexp.findall(result.output) if matches: for m in set(matches): @@ -95,31 +121,6 @@ def scan_source(build_dir, build=metadata.Build()): count = 0 - # Common known non-free blobs (always lower case): - usual_suspects = { - exp: re.compile(r'.*' + exp, re.IGNORECASE) for exp in [ - r'flurryagent', - r'paypal.*mpl', - r'admob.*sdk.*android', - r'google.*ad.*view', - r'google.*admob', - r'google.*play.*services', - r'crittercism', - r'heyzap', - r'jpct.*ae', - r'youtube.*android.*player.*api', - r'bugsense', - r'crashlytics', - r'ouya.*sdk', - r'libspen23', - r'firebase', - r'''["']com.facebook.android['":]''', - r'cloudrail', - r'com.tencent.bugly', - r'appcenter-push', - ] - } - whitelisted = [ 'firebase-jobdispatcher', # https://github.com/firebase/firebase-jobdispatcher-android/blob/master/LICENSE 'com.firebaseui', # https://github.com/firebase/FirebaseUI-Android/blob/master/LICENSE @@ -130,7 +131,7 @@ def scan_source(build_dir, build=metadata.Build()): return any(wl in s for wl in whitelisted) def suspects_found(s): - for n, r in usual_suspects.items(): + for n, r in NON_FREE_GRADLE_LINES.items(): if r.match(s) and not is_whitelisted(s): yield n From 602cf30c1ee48365442fb51975f8e1e05c55013e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 7 Oct 2020 18:40:03 +0200 Subject: [PATCH 0547/2775] update: fix bug where only last appid was added to antiFeatures status appid will never be present in `antiFeatures[af]`, so the entry was being reinitalized each time. --- fdroidserver/update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 6ffb0973..1708700a 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -149,7 +149,7 @@ def status_update_json(apps, apks): antiFeatures = output['antiFeatures'] # JSON camelCase if af not in antiFeatures: antiFeatures[af] = dict() - if appid not in antiFeatures[af]: + if 'apps' not in antiFeatures[af]: antiFeatures[af]['apps'] = set() antiFeatures[af]['apps'].add(appid) From 75cdb1fd9795f7e8bd50b7cf1fd13723d83cd262 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 6 Oct 2020 11:31:22 +0200 Subject: [PATCH 0548/2775] update: remove -b / --buildreport which has done nothing since 2013 The functionality was removed in 48296df5b0bd2a93d37f72ffe10cf6f955f21767 --- completion/bash-completion | 4 ++-- fdroidserver/update.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index 5f21621e..1686abba 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -125,8 +125,8 @@ __complete_install() { } __complete_update() { - opts="-c -v -q -b -i -I -e -w" - lopts="--create-metadata --verbose --quiet --buildreport + opts="-c -v -q -i -I -e -w" + lopts="--create-metadata --verbose --quiet --icons --wiki --pretty --clean --delete-unknown --nosign --rename-apks --use-date-from-apk" case "${prev}" in diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 1708700a..2a0cca1a 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -2270,8 +2270,6 @@ def main(): help=_("Add skeleton metadata files for APKs that are missing them")) parser.add_argument("--delete-unknown", action="store_true", default=False, help=_("Delete APKs and/or OBBs without metadata from the repo")) - parser.add_argument("-b", "--buildreport", action="store_true", default=False, - help=_("Report on build data status")) parser.add_argument("-I", "--icons", action="store_true", default=False, help=_("Resize all the icons exceeding the max pixel size and exit")) parser.add_argument("-w", "--wiki", default=False, action="store_true", From 00c2cc969a47f9e3f7e294910b31d365dd9a9ba7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 6 Oct 2020 11:39:46 +0200 Subject: [PATCH 0549/2775] update: deprecate --wiki option, the wiki is going away --- completion/bash-completion | 8 ++++---- fdroidserver/update.py | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/completion/bash-completion b/completion/bash-completion index 1686abba..751e5b24 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -81,9 +81,9 @@ __complete_options() { } __complete_build() { - opts="-v -q -l -s -t -f -a -w" + opts="-v -q -l -s -t -f -a" - lopts="--verbose --quiet --latest --stop --test --server --reset-server --skip-scan --scan-binary --no-tarball --force --all --wiki --no-refresh" + lopts="--verbose --quiet --latest --stop --test --server --reset-server --skip-scan --scan-binary --no-tarball --force --all --no-refresh" case "${prev}" in :) __vercode @@ -125,9 +125,9 @@ __complete_install() { } __complete_update() { - opts="-c -v -q -i -I -e -w" + opts="-c -v -q -i -I -e" lopts="--create-metadata --verbose --quiet - --icons --wiki --pretty --clean --delete-unknown + --icons --pretty --clean --delete-unknown --nosign --rename-apks --use-date-from-apk" case "${prev}" in -e|--editor) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 2a0cca1a..9a2f80d4 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -19,6 +19,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import argparse import sys import os import shutil @@ -2273,7 +2274,7 @@ def main(): parser.add_argument("-I", "--icons", action="store_true", default=False, help=_("Resize all the icons exceeding the max pixel size and exit")) parser.add_argument("-w", "--wiki", default=False, action="store_true", - help=_("Update the wiki")) + help=argparse.SUPPRESS) parser.add_argument("--pretty", action="store_true", default=False, help=_("Produce human-readable XML/JSON for index files")) parser.add_argument("--clean", action="store_true", default=False, @@ -2443,6 +2444,7 @@ def main(): # Update the wiki... if options.wiki: + logging.warning(_('wiki support is deprecated and will be removed in the next release!')) update_wiki(apps, apks + archapks) status_update_json(apps, apks + archapks) From ae3c9c055214653750af386f63bd0e7241ea98d7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 6 Oct 2020 16:35:07 +0200 Subject: [PATCH 0550/2775] change make_current_version_link to default to False This is semi-broken and barely used, it should be off by default for 2.0. --- CHANGELOG.md | 1 + fdroidserver/common.py | 2 +- tests/run-tests | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e34660ad..3c4f69a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Removed * removed support for txt and json metadata ([!772](https://gitlab.com/fdroid/fdroidserver/-/merge_requests/772)) +* `make_current_version_link` is now off by default ## [1.1.4] - 2019-08-15 ### Fixed diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 2cdf0098..677baf04 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -124,7 +124,7 @@ default_config = { 'sync_from_local_copy_dir': False, 'allow_disabled_algorithms': False, 'per_app_repos': False, - 'make_current_version_link': True, + 'make_current_version_link': False, 'current_version_name_source': 'Name', 'deploy_process_logs': False, 'update_stats': False, diff --git a/tests/run-tests b/tests/run-tests index 5a5cc232..66b00ed7 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -165,6 +165,7 @@ if which zipalign || ls -1 $ANDROID_HOME/build-tools/*/zipalign; then cd $REPOROOT cp $WORKSPACE/tests/keystore.jks $REPOROOT/ $fdroid init --keystore keystore.jks --repo-keyalias=sova + echo 'make_current_version_link = True' >> config.py echo 'keystorepass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py echo 'keypass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py From daadcdd12a713ad15a63e644b5b7aa1ffe23d308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 8 Oct 2020 16:37:25 +0200 Subject: [PATCH 0551/2775] log vm status when vagrant up fails --- fdroidserver/vmtools.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index bd8aae60..b32502f0 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -209,7 +209,22 @@ class FDroidBuildVm(): self.vgrnt.up(provision=provision, provider=self.provider) self.srvuuid = self._vagrant_fetch_uuid() except subprocess.CalledProcessError as e: - raise FDroidBuildVmException("could not bring up vm '%s'" % self.srvname) from e + statusline = "" + try: + # try to get some additional info about the vagrant vm + status = self.vgrnt.status() + if len(status) > 0: + statusline = "VM status: name={n}, state={s}, provider={p}"\ + .format(n=status[0].name, + s=status[0].state, + p=status[0].provider) + except subprocess.CalledProcessError: + pass + raise FDroidBuildVmException(value="could not bring up vm '{vmname}'" + .format(vmname=self.srvname), + detail="{err}\n{statline}" + .format(err=str(e), statline=statusline) + ) from e def suspend(self): global lock From 261a5cca44910aeea825671ceb0f2198ed9c07ed Mon Sep 17 00:00:00 2001 From: Izzy Date: Tue, 13 Oct 2020 17:07:37 +0200 Subject: [PATCH 0552/2775] add framagit.org to known git repo locations --- fdroidserver/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 2cdf0098..f0d820ef 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1804,7 +1804,7 @@ def get_app_from_url(url): app.RepoType = 'git' app.SourceCode = url app.IssueTracker = url + '/issues' - elif parsed.netloc == 'gitlab.com': + elif parsed.netloc == 'gitlab.com' or parsed.netloc == 'framagit.org': # git can be fussy with gitlab URLs unless they end in .git if url.endswith('.git'): url = url[:-4] From 7fbf08fbbed62df7bb3c35c4348a998857882347 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Wed, 14 Oct 2020 22:41:27 +0200 Subject: [PATCH 0553/2775] add gradle 6.7 --- gradlew-fdroid | 3 ++- makebuildserver | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 1b32b4e1..01ce7fbb 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -141,6 +141,7 @@ get_sha() { '6.5.1') echo '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a' ;; '6.6') echo 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025' ;; '6.6.1') echo '7873ed5287f47ca03549ab8dcb6dc877ac7f0e3d7b1eb12685161d10080910ac' ;; + '6.7') echo '8ad57759019a9233dc7dc4d1a530cefe109dc122000d57f7e623f8cf4ba9dfc4' ;; *) exit 1 esac } @@ -161,7 +162,7 @@ d_plugin_k=(4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 d_plugin_v=(6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.6.1 6.6 6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.7 6.6.1 6.6 6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 56ea7b2e..bc192229 100755 --- a/makebuildserver +++ b/makebuildserver @@ -395,6 +395,8 @@ CACHE_FILES = [ '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a'), ('https://services.gradle.org/distributions/gradle-6.6.1-bin.zip', '7873ed5287f47ca03549ab8dcb6dc877ac7f0e3d7b1eb12685161d10080910ac'), + ('https://services.gradle.org/distributions/gradle-6.7-bin.zip', + '8ad57759019a9233dc7dc4d1a530cefe109dc122000d57f7e623f8cf4ba9dfc4'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 8c32cd2b43d2b6b7b68c907374dc29c2b906e4f6 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 16 Oct 2020 14:27:47 +0200 Subject: [PATCH 0554/2775] AGP 4.1 requires gradle 6.5 --- gradlew-fdroid | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index 01ce7fbb..a7acb6fe 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -158,8 +158,8 @@ contains() { # (key) should accept. plugin versions are actually prefixes and catch sub- # versions as well. Pairs are taken from: # https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle -d_plugin_k=(4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2) -d_plugin_v=(6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) +d_plugin_k=(4.1 4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 1.3 1.2 1.1 1.0 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2) +d_plugin_v=(6.5 6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about plugin_v=(6.7 6.6.1 6.6 6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) From 03b1adbe2baab4c68d231441447c16c253b56a37 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Fri, 16 Oct 2020 22:50:29 +0200 Subject: [PATCH 0555/2775] don't include .idsig files into the index .idsig files contain an apksig v4 (https://source.android.com/security/apksigning/v4) new versions of apksigner make this signature by default and it ends up in /repo. Without this patch it would be included into the index as a file to be downloaded by users. F-Droid Client crashes when it encounters such an apk entry. It's fine to have these signature files in the repo though, maybe fdroidclient can make use of them at some point in the future (they are intended to support streaming app installations). --- fdroidserver/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 04867a7f..ee093778 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3731,6 +3731,7 @@ def is_repo_file(filename): return os.path.isfile(filename) \ and not filename.endswith(b'.asc') \ and not filename.endswith(b'.sig') \ + and not filename.endswith(b'.idsig') \ and not filename.endswith(b'.log.gz') \ and os.path.basename(filename) not in [ b'index.jar', From a216c0487e55ea644b3ab5758af8e594d7d48391 Mon Sep 17 00:00:00 2001 From: Izzy Date: Tue, 20 Oct 2020 22:55:52 +0200 Subject: [PATCH 0556/2775] accepted_formats has been removed from fdroidserver (only yml remains anyway) --- examples/config.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/config.py b/examples/config.py index fc30af15..f074fb15 100644 --- a/examples/config.py +++ b/examples/config.py @@ -309,10 +309,6 @@ The repository of older versions of applications from the main demo repository. # --server option on dedicated secure build server hosts. # build_server_always = True -# By default, fdroid will use YAML .yml and the custom .txt metadata formats. It -# is also possible to have metadata in JSON by adding 'json'. -# accepted_formats = ('txt', 'yml') - # Limit in number of characters that fields can take up # Only the fields listed here are supported, defaults shown # char_limits = { From a16ca66abf04e20f27667394cbc200a3d622c2c8 Mon Sep 17 00:00:00 2001 From: Massimiliano Caniparoli Date: Sat, 17 Oct 2020 07:19:28 +0200 Subject: [PATCH 0557/2775] Translated using Weblate: Italian (it) by Massimiliano Caniparoli Currently translated at 34.3% (194 of 565 strings) Co-authored-by: Massimiliano Caniparoli Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/it/ Translation: F-Droid/F-Droid Server --- locale/it/LC_MESSAGES/fdroidserver.po | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index 4d2c68c3..49c1fbdd 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -4,13 +4,14 @@ # random r , 2020. # Luca Zambarda , 2020. # IvanDan , 2020. +# Massimiliano Caniparoli , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-09-19 17:03+0000\n" -"Last-Translator: IvanDan \n" +"PO-Revision-Date: 2020-10-01 11:26+0000\n" +"Last-Translator: Massimiliano Caniparoli \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" @@ -28,6 +29,12 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Questo è un repository di app da usare con FDroid. Le applicazioni in questo\n" +" repository sono binari ufficiali compilati dagli sviluppatori originali \n" +" dell'applicazione, oppure sono binari compilati dai sorgenti da f-droid.org\n" +" usando i tool su https://gitlab.com/fdroid.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -38,7 +45,6 @@ msgstr "" "Chiave pubblica SSH da usare come chiave di deploy:" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" @@ -61,7 +67,7 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" non ha un file di metadata corrispondente!" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." msgstr "\"{apkfilename}\" è già installato su {dev}." @@ -81,9 +87,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" esiste ma s3cmd non è installato!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" non è un formato accettato, convertire a: {formats}" +msgstr "\"{path}\" non è un formato accettato (usa: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -93,7 +99,7 @@ msgstr "\"{path}\" non è un formato accettato, convertire a: {formats}" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" non è un URL valido!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py From 2fba27ab926a9556dbd5552240f131fda3e0a03c Mon Sep 17 00:00:00 2001 From: Bart Groeneveld Date: Sat, 17 Oct 2020 07:19:28 +0200 Subject: [PATCH 0558/2775] Translated using Weblate: Dutch (nl) by Bart Groeneveld Currently translated at 3.3% (19 of 565 strings) Added translation using Weblate: Dutch (nl) by Bart Groeneveld Co-authored-by: Bart Groeneveld Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/nl/ Translation: F-Droid/F-Droid Server --- locale/nl/LC_MESSAGES/fdroidserver.po | 2647 +++++++++++++++++++++++++ 1 file changed, 2647 insertions(+) create mode 100644 locale/nl/LC_MESSAGES/fdroidserver.po diff --git a/locale/nl/LC_MESSAGES/fdroidserver.po b/locale/nl/LC_MESSAGES/fdroidserver.po new file mode 100644 index 00000000..1e2353a2 --- /dev/null +++ b/locale/nl/LC_MESSAGES/fdroidserver.po @@ -0,0 +1,2647 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# Bart Groeneveld , 2020. +msgid "" +msgstr "" +"Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" +"Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"PO-Revision-Date: 2020-10-01 20:58+0000\n" +"Last-Translator: Bart Groeneveld \n" +"Language-Team: Dutch \n" +"Language: nl\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 4.3-dev\n" + +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH Public Key to be used as Deploy Key:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "" +"\n" +"{path} encoded for the DEBUG_KEYSTORE secret variable:" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "\"%s/\" has no matching metadata file!" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains outdated {name} ({version})" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains recent {name} ({version})" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "\"{path}\" exists but s3cmd is not installed!" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "\"{path}\" is not an accepted format, convert to: {formats}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%(option)s option requires %(number)d argument" +msgid_plural "%(option)s option requires %(number)d arguments" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/mirror.py +#, python-format +msgid "%(prog)s [options] url" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%(prog)s: error: %(message)s\n" +msgstr "%(prog)s: fout: %(message)s\n" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "%d problems found" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "%prog [options]" +msgstr "%prog [opties]" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%r is not callable" +msgstr "%r kan niet aangeroepen worden" + +#: ../fdroidserver/lint.py +#, python-format +msgid "%s is not an accepted build field" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%s option does not take a value" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keypass' not found in config.py!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystore' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystorepass' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'repo_keyalias' not found in config.py!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "'required' is an invalid argument for positionals" +msgstr "" + +#: ../fdroidserver/common.py +msgid "'sdk_path' not set in 'config.py'!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "'{apkfilename}' is already installed on {dev}." +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{path}' failed to execute!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "...checkupdate failed for {appid} : {error}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid ".__call__() not defined" +msgstr ".__call__() niet gedefinieerd" + +#: ../fdroidserver/metadata.py +msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "/issues is missing" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "A URL is required as an argument!" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Add PGP signatures using GnuPG for packages in repo" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Add a new application from its source code" +msgstr "Voeg een nieuwe toepassing toe vanuit broncode" + +#: ../fdroidserver/update.py +msgid "Add a repo signing key to an unsigned repo" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Add skeleton metadata files for APKs that are missing them" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Adding new repo for only {name}" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Alias of the repo signing key in the keystore" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Allows a different revision (or git branch) to be specified for the initial import" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Also mirror the full archive section" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Also warn about formatting issues, like rewritemeta -l" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + +#: ../fdroidserver/common.py ../fdroidserver/build.py +#, python-brace-format +msgid "Android SDK '{path}' does not have '{dirname}' installed!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Android SDK not found!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' is not a directory!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android build-tools path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "AndroidManifest.xml has no date" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "App is in '{repo}' but has a link to {url}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Appending .git is not necessary" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Archiving {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in srclib '{srclib}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +#, fuzzy +msgid "Build a package from source" +msgstr "Bouw een pakket vanaf de bron" + +#: ../fdroidserver/build.py +msgid "Build all applications available" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Build generated by `fdroid import` - remove disable line once ready" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Build metadata git repo has uncommited changes!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build only the latest version of each package" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "Built repo based in \"%s\" with this config:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Can't build due to {} error while scanning" +msgid_plural "Can't build due to {} errors while scanning" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find a packageName for {path}!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find an appid for {path}!" +msgstr "" + +#: ../fdroidserver/vmtools.py +#, python-brace-format +msgid "Cannot read \"{path}\"!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot resolve app id {appid}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Cannot use --list and --to at the same time" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Categories '%s' is not valid" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Categories are not set" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Check for updates to applications" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean after all scans have finished" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean before the scans start and rebuild the container" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean up all containers and then exit" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Clean update - don't uses caches, reprocess all APKs" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Comma separated list of categories." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +#, c-format, python-format +msgid "Command '%s' not recognised.\n" +msgstr "Opdracht '%s' wordt niet herkend.\n" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes" +msgstr "" + +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not find '{command}' on your system" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not find {path} to remove it" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Could not open apk file for analysis" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/import.py +msgid "Couldn't find latest version code" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/import.py +msgid "Couldn't find latest version name" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find package ID" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Cowardily refusing to overwrite existing signing key setup!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create a repo signing key in a keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create skeleton metadata files that are missing" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Created new container \"{name}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Creating log directory" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating new S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Creating output directory" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Creating signed index with this key (SHA256):" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/verify.py +#: ../fdroidserver/publish.py +msgid "Creating temporary directory" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Creating unsigned index in preparation for signing" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "DEBUG_KEYSTORE is not set or the value is incomplete" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Delete APKs and/or OBBs without metadata from the repo" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Deleting unknown file: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description '%s' is just the app's summary" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Description has a duplicate line" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description has a list (%s) but it isn't bulleted (*) nor numbered (#)" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Description of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not deploy the new files to the repo" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Do not include \"{path}\" in URL!" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Do not prompt for Android SDK path, just fail" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not remove the private keys generated from the keystore" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't create a source tarball, useful when testing a build" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Don't do anything logs-related" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't refresh the repository, useful when testing a build with no internet connection" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/upload.py +msgid "Don't use rsync checksums" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Download complete mirrors of small repos" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Download logs we don't have" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Downloading the repository already failed once, not trying again." +msgstr "" + +#: ../fdroidserver/verify.py +#, python-brace-format +msgid "Downloading {url} failed. {error}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Duplicate build recipe found for versionCode {versionCode} in {linedesc}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Duplicate link in '{field}': {url}" +msgstr "" + +#: ../fdroid +msgid "Dynamically scan APKs post build" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "" +"ERROR: this command should never be used to mirror f-droid.org!\n" +"A full mirror of f-droid.org requires more than 200GB." +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "ERROR: unsupported CI type, patches welcome!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Empty build flag at {linedesc}" +msgstr "" + +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"Enter the path to the Android SDK (%s) here:\n" +"> " +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/upload.py +#, python-format +msgid "Error while attempting to publish log: %s" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py +msgid "Error while getting repo address" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Extract signatures from APKs" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Failed fetching signatures for '{apkfilename}': {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed reading {path}: {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed resizing {path}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Failed to align application" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Failed to create S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to get APK manifest information" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, deleting {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, skipping {path}" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Failed to install '{apkfilename}' on {dev}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/common.py +msgid "Failed to sign application" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to zipalign application" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Fetched buildserverid from VM: {buildserverid}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py +#: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "Finished" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID flag" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Forbidden HTML tags" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Force halting build after {0} sec timeout!" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Found invalid appids in arguments" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Found invalid versionCodes for some apps" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Found multiple metadata files for {appid}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found multiple signing certificates for repository." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found multiple signing certificates in {path}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found no signing certificates for repository." +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Found non-file at %s" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Generated skeleton metadata for {appid}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git checkout of '%s' failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git clean failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git fetch failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git remote set-head failed" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git reset failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule sync failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule update failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "HTTPS must be used with Subversion URLs!" +msgstr "" + +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Ignoring package without metadata: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Ignoring stale cache data for {apkfilename}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Ignoring {ext} file at '{path}'" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Include APKs that are signed with disabled algorithms like MD5" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Initialising submodules" +msgstr "" + +#: ../fdroidserver/install.py +msgid "Install all signed applications available" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Install built packages on devices" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s…" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}…" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Interact with the repo HTTP server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Invalid APK" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid VercodeOperation: {field}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid boolean '%s'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build flag at {line} in {linedesc}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build format: {value} in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid bulleted list" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid metadata in %s:%d" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Invalid metadata in: " +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Invalid name for published file: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid package name {0}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid redirect to non-HTTPS: {before} -> {after} " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature failed to verify: {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature verified: {path}" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#: ../fdroidserver/mirror.py +msgid "Java JDK not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Java jarsigner not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Javascript in HTML src attributes" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Keystore for signing key:\t" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the LiberapayID flag" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "List files that would be reformatted" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Locale included in f-droid.org URL" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Make the build stop on exceptions" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Malformed repository mirrors." +msgstr "" + +#: ../fdroidserver/server.py +msgid "Malformed serverwebroot line:" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + +#: ../fdroidserver/gpgsign.py +msgid "Missing output directory" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Name '%s' is just the auto name - remove it" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No 'config.py' found, using defaults." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No Android SDK found!" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No android or kivy project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No attached devices found" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "No commit specified for {versionName} in {linedesc}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "No fingerprint in URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No git submodules available" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py +msgid "No information found." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is Free Software" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is for Android" +msgstr "" + +#: ../fdroidserver/server.py +msgid "No option set! Edit your config.py to set at least one of these:" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No packages specified" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "No signed apk available for %s" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No signed output directory - nothing to do" +msgstr "" + +#: ../fdroidserver/update.py ../fdroidserver/common.py +#, python-brace-format +msgid "No signing certificates found in {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "No such package: %s" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No such versionCode {versionCode} for app {appid}" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +msgid "No unsigned directory - nothing to do" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Nothing to do" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Nothing to do for {appid}." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Now set these in config.py:" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "OBB file has newer versionCode({integer}) than any APK:" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB filename must start with \"main.\" or \"patch.\":" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB's packagename does not match a supported APK:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Old APK signature failed to verify: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Old, deprecated name for fdroid deploy" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Only PNG and JPEG are supported for graphics, found: {path}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only print differences with the Play Store" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only process apps with auto-updates" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Options" +msgstr "Opties" + +#: ../fdroidserver/verify.py +msgid "Output JSON report to file named after APK." +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Overall license of the project." +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Override path for repo APKs (default: ./repo)" +msgstr "" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" +msgstr "" + +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Parsing manifest at '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Password required with username" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Path to main Android project subdirectory, if not in root." +msgstr "" + +msgid "Path to main android project subdirectory, if not in root." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Path to the git repo to use as the log" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the keystore for the repo signing key" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Prepare Drozer to run a scan" +msgstr "" + +msgid "Prepare drozer to run a scan" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Print the secret variable to the terminal for easy copy/paste" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Problem with description of {appid}: {error}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Problem with xml at '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Process auto-updates" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#, python-brace-format +msgid "Processing {apkfilename}" +msgstr "" + +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#, python-brace-format +msgid "Processing {appid}" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable XML/JSON for index files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable index.xml" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Project URL to import from." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Punctuation should be avoided" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Push the log to this git remote repository" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing binary transparency log to {url}" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing to {url}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Quickly start a new repository" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Read all the metadata files and exit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading '{config_file}'" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading minSdkVersion failed: \"{apkfilename}\"" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Reading {apkfilename} from cache" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Removing specified files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Rename APK files that do not match package.name_123.apk" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Report on build data status" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Reset and create a brand new build server, even if the existing one appears to be ok." +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Resigning {apkfilename} with provided debug.keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Resize all the icons exceeding the max pixel size and exit" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Restrict output to warnings and errors" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Rewrite all the metadata files" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Rewrite to a specific format: " +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}'" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}' to '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Run on git repo that has uncommitted changes" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Run rewritemeta to fix formatting" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Running first pass with MD5 checking disabled" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Running wget in {path}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Scan only the latest version of each package" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Scan the source code of a package" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:{versionCode}:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Scanner found {} problem" +msgid_plural "Scanner found {} problems" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/common.py +msgid "Set clock to that time using:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Set open file limit to {integer}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Set up an app build for a nightly build repo" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setting open file limit failed: " +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Setting {0} sec timeout for this build" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setup an emulator, install the APK on it and perform a Drozer scan" +msgstr "" + +msgid "Setup an emulator, install the apk on it and perform a drozer scan" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Sign and place packages in the repo" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Sign indexes created using update --nosign" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Skip scanning the source code for binaries and other problems" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping '{apkfilename}' with invalid signature!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping index generation for {appid}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: disabled" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: no builds specified" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify a local folder to sync the repo to" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify an identity file to provide to SSH for rsyncing" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Specify that we're running on the build server" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Specify which debug keystore file to use." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Spew out even more information than normal" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Striping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Summary '%s' is just the app's name" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Summary of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "System clock is older than date in {path}!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "The OBB version code must come after \"{name}.\":" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "The base URL for the repo to log (default: https://f-droid.org)" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "The directory to write the mirror to" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "The file to be included in the repo (path or glob)" +msgstr "" + +#: ../fdroidserver/server.py +msgid "The only commands currently supported are 'init' and 'update'" +msgstr "" + +#: ../fdroidserver/index.py +msgid "The repository's fingerprint does not match." +msgstr "" + +#: ../fdroidserver/common.py +msgid "The repository's index could not be verified." +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "The root dir for local_copy_dir \"{path}\" does not exist!" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "There is a keyalias collision - publishing halted" +msgstr "" + +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + +#: ../fdroidserver/import.py +#, python-format +msgid "This repo already has local metadata: %s" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "URL shorteners should not be used" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "URL title is just the URL, use brackets: [URL]" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "URL {url} in Description: {error}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unexpected text on same line as {field} in {linedesc}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Unknown exception found!" +msgstr "Onbekende uitzondering gevonden!" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Unknown file '{filename}' in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Unknown metadata format: %s" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Unknown version of aapt, might cause problems: " +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary leading space" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary trailing space" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised app field '{fieldname}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unrecognised app field: " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised build flag '{build_flag}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised field '{field}' in {linedesc}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported file type \"{extension}\" for repo graphic" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported graphics file found: {path}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Unsupported metadata format, use: --to [{supported}]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated build in {name}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated continuation in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused extlib at %s" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused file at %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Update Check Name is set to the known app id - it can be removed" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update repo information for new packages" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update the binary transparency log for a URL" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update the stats of the repo" +msgstr "" + +#: ../fdroidserver/update.py ../fdroidserver/build.py +msgid "Update the wiki" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "UpdateCheckData has invalid URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must use HTTPS URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData not a valid URL: {url}" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Usage" +msgstr "Gebruik" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "Usage: %s\n" +msgstr "Gebruik: %s\n" + +#: ../fdroidserver/lint.py +msgid "Use /HEAD instead of /master to point at a file in the default branch" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use `fdroid update -c` to create it." +msgstr "" + +#: ../fdroidserver/build.py +msgid "Use build server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use date from APK instead of current time for newly added APKs" +msgstr "" + +msgid "Use date from apk instead of current time for newly added apks" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Using androguard from \"{path}\"" +msgstr "" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Using existing keystore \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using s3cmd to sync with: {url}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Valid commands are:" +msgstr "Geldige opdrachten zijn:" + +#: ../fdroidserver/verify.py +msgid "Verify against locally cached copy rather than redownloading." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Verify the integrity of downloaded packages" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Verifying index signature:" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Warn about possible metadata errors" +msgstr "" + +#: ../fdroidserver/update.py +msgid "When configured for signed indexes, create only unsigned indexes at this stage" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + +msgid "X.509 'Distiguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/init.py +msgid "X.509 'Distinguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/common.py +msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "adding IdentityFile to {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "adding to {name}: {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ambiguous option: %(option)s could match %(matches)s" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "ambiguous option: %s (%s?)" +msgstr "" + +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +msgid "applicationId in the form APPID" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "applicationId to check for updates" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/dscanner.py ../fdroidserver/build.py +#: ../fdroidserver/scanner.py ../fdroidserver/install.py +msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "argument \"-\" with mode %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "attempting bare ssh connection to test deploy key:" +msgstr "" + +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "can't open '%s': %s" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "cannot have multiple subparser arguments" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "cannot merge actions - two groups are named %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "cannot publish update, did you set the deploy key?" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "cloning {url}" +msgstr "" + +#: ../fdroidserver/server.py +msgid "command to execute, either 'init' or 'update'" +msgstr "" + +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "complex" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "conflicting option string: %s" +msgid_plural "conflicting option strings: %s" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "copying {apkfilename} into {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "created {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "deleting: repo/{apkfilename}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed build logs to '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "dest= is required for options like %r" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "expected %s argument" +msgid_plural "expected %s arguments" +msgstr[0] "" +msgstr[1] "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at least one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at most one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected one argument" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "failed deploying build logs to '{path}'" +msgstr "" + +#: ../fdroid +msgid "fdroid [-h|--help|--version] []" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "fdroid [] [-h|--help|--version|]" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "floating-point" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force errors to be warnings, or ignore" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force metadata errors (default) to be warnings, or to be ignored." +msgstr "" + +#: ../fdroidserver/common.py +msgid "git svn clone failed" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ignored explicit argument %r" +msgstr "" + +#: ../fdroidserver/index.py +msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "integer" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid %(type)s value: %(value)r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid choice: %(value)r (choose from %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid conflict_resolution value: %r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be an absolute path!" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be directory, not a file!" +msgstr "" + +#: ../fdroidserver/index.py +#, python-format +msgid "mirror '%s' does not end with 'fdroid'!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "mutually exclusive arguments must be optional" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "no \"icon\" in {appid}" +msgstr "" + +#: ../fdroidserver/signatures.py +msgid "no APK supplied" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "no such option: %s" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "no version info found!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "not allowed with argument %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "one of the arguments %s is required" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "only accepts strings, lists, and tuples" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "option %s: If you really want to install all the signed apps, use --all" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid %s value: %r" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid choice: %r (choose from %s)" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s not recognized" +msgstr "optie -%s wordt niet herkend" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s requires argument" +msgstr "optie -%s vereist een argument" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s must not have an argument" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not a unique prefix" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not recognized" +msgstr "optie --%s wordt niet herkend" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s requires argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "optional arguments" +msgstr "optionele argumenten" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "overwriting existing {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "positional arguments" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "s3cmd sync indexes {path} to {url} and delete" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "show program's version number and exit" +msgstr "toon versienummer van programma en sluit af" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.5/optparse.py +#: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py +msgid "show this help message and exit" +msgstr "toon dit hulpbericht en sluit af" + +#: ../fdroidserver/signatures.py +msgid "signed APK, either a file-path or HTTPS URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: log content is empty" +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: not enabled in config" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "skipping source tarball: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "srclibs missing name and/or @" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "the following arguments are required: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unexpected option string: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unknown parser %(parser_name)r (choices: %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unrecognized arguments: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "unsafe permissions on '{config_file}' (should be 0600)!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py +msgid "usage: " +msgstr "gebruik: " + +#: ../fdroid +msgid "usage: fdroid [-h|--help|--version] []" +msgstr "gebruik: fdroid [-h|--help|--version] []" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "using Apache libcloud to sync with {url}" +msgstr "" + +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "{0} app, {1} key aliases" +msgid_plural "{0} apps, {1} key aliases" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} ({appid}) has no metadata!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using package name instead." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android Package Name!" +msgstr "" + +#: ../fdroidserver/metadata.py ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Java Package Name!" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{appid} is missing {name}" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: Unknown extlib {path} in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "{appid}: no builds specified, running on current source state" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{field} not terminated in {name}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{name} \"{path}\" does not exist! Correct it in config.py." +msgstr "" + +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "{path} does not exist! Create it by running:" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} is zero size!" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{url} does not end with \"fdroid\", check the URL path!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "{} build failed" +msgid_plural "{} builds failed" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/build.py +msgid "{} build succeeded" +msgid_plural "{} builds succeeded" +msgstr[0] "" +msgstr[1] "" From 5cf54fe50f4ace208e6a3bef09a4a40650a7ffe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Sat, 17 Oct 2020 07:19:29 +0200 Subject: [PATCH 0559/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Turki?= =?UTF-8?q?sh=20(tr)=20by=20O=C4=9Fuz=20Ersen=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (565 of 565 strings) Translated using Weblate: Turkish (tr) by Oğuz Ersen Currently translated at 89.3% (505 of 565 strings) Co-authored-by: Oğuz Ersen Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/tr/ Translation: F-Droid/F-Droid Server --- locale/tr/LC_MESSAGES/fdroidserver.po | 231 +++++++++++++------------- 1 file changed, 113 insertions(+), 118 deletions(-) diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index 3a328e6f..79c8ebef 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-07-20 20:29+0000\n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" "Language: tr\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/common.py msgid "" @@ -25,6 +25,12 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Bu, FDroid ile kullanılacak uygulamaların bir deposudur. Bu depodaki\n" +" uygulamalar ya gerçek uygulama geliştiricileri tarafından oluşturulan\n" +" resmi ikili dosyalardır ya da https://gitlab.com/fdroid adresindeki araçlar\n" +" kullanılarak f-droid.org tarafından kaynaktan oluşturulan ikili dosyalardır.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -35,13 +41,12 @@ msgstr "" "Dağıtım Anahtarı olarak kullanılacak SSH Açık Anahtar:" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" msgstr "" "\n" -"Dağıtım Anahtarı olarak kullanılacak SSH Açık Anahtar:" +"Dağıtım anahtarı olarak kullanılacak SSH ortak anahtarı:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -58,9 +63,9 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" eşleşen üst veri dosyasına sahip değil!" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." -msgstr "'{apkfilename}' zaten {dev} üzerinde kurulu." +msgstr "\"{apkfilename}\" zaten {dev} üzerinde kurulu." #: ../fdroidserver/update.py #, python-brace-format @@ -78,9 +83,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" var ancak s3cmd kurulu değil!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" kabul edilebilir bir biçim değil, şuna dönüştürün: {formats}" +msgstr "\"{path}\" desteklenen bir dosya biçimi değil (şunu kullanın: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -90,7 +95,7 @@ msgstr "\"{path}\" kabul edilebilir bir biçim değil, şuna dönüştürün: {f #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" geçerli bir URL değil!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -144,7 +149,7 @@ msgstr "'keypass' config.py içinde bulunamadı!" #: ../fdroidserver/common.py msgid "'keystore' is NONE and 'smartcardoptions' is blank!" -msgstr "" +msgstr "'keystore' seçeneği NONE ve 'smartcardoptions' seçeneği boş!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" @@ -266,16 +271,15 @@ msgstr "Ayrıca biçimlendirme sorunları hakkında uyar, rewritemeta -l gibi" #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "Android AAR kütüphanesi" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Android APK dosyası" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "Android SDK bulunamadı!" +msgstr "Android DEX kodu" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -340,7 +344,7 @@ msgstr "Srclib '{srclib}' içine işleme için dal '{branch}' kullanıldı" #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Bozuk simgesel bağlantı: {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -399,9 +403,9 @@ msgid "Cannot resolve app id {appid}" msgstr "App id {appid} çözülemiyor" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "\"{path}\" okunamıyor!" +msgstr "\"{path}\" yeniden yazılamıyor" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -461,7 +465,7 @@ msgstr "Değişiklikleri işle" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Çakışan argümanlar: '--verbose' ve '--quiet' aynı anda belirtilemez." #: ../fdroidserver/common.py #, python-brace-format @@ -469,12 +473,10 @@ msgid "Could not find '{command}' on your system" msgstr "'{command}' sisteminizde bulunamadı" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version code" msgstr "Son sürüm kodu bulunamadı" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version name" msgstr "Son sürüm adı bulunamadı" @@ -490,12 +492,11 @@ msgstr "İnceleme için apk dosyası açılamadı" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not parse size \"{size}\", wrong type \"{type}\"" -msgstr "" +msgstr "\"{size}\" boyutu ayrıştırılamadı, yanlış tür \"{type}\"" #: ../fdroidserver/import.py -#, fuzzy msgid "Couldn't find Application ID" -msgstr "Paket ID bulunamadı" +msgstr "Uygulama kimliği bulunamadı" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -575,12 +576,12 @@ msgstr "Depodan üst verisi olmayan APKları ve/veya OBBleri sil" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Arşiv siliniyor, depo çok büyük ({size}, en fazla {limit})" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "git-mirror geçmişi siliniyor, depo çok büyük ({size}, en fazla {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -608,7 +609,7 @@ msgstr "{length} uzunluğundaki açıklama, {limit} karakter sınırının üst #: ../fdroidserver/import.py msgid "Do not add 'disable:' to the generated build entries" -msgstr "" +msgstr "Oluşturulan derleme girdilerine 'disable:' ekleme" #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" @@ -695,7 +696,7 @@ msgstr "{linedesc} satırında boş inşa bayrağı" #: ../fdroidserver/__main__.py #, python-brace-format msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." -msgstr "" +msgstr "Kodlama '{enc}' olarak ayarlandı, fdroid kodlama sorunlarıyla karşılaşabilir. En iyi sonuçlar için lütfen 'UTF-8' olarak ayarlayın." #: ../fdroidserver/init.py #, python-format @@ -721,9 +722,9 @@ msgid "Extract signatures from APKs" msgstr "APK'lardan imzaları ayıkla" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Failed copying {path}: {error}" -msgstr "{path} okunamadı: {error}" +msgstr "{path} kopyalanamadı: {error}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -789,7 +790,7 @@ msgstr "'{apkfilename}' için imzalar alındı -> '{sigdir}'" #: ../fdroidserver/update.py #, python-brace-format msgid "File disappeared while processing it: {path}" -msgstr "" +msgstr "Dosya işlenirken kayboldu: {path}" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -803,9 +804,8 @@ msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Flattr bağış yöntemleri FlattrID bayrağında olmalı" #: ../fdroidserver/lint.py -#, fuzzy msgid "Flattr donation methods belong in the FlattrID: field" -msgstr "Flattr bağış yöntemleri FlattrID bayrağında olmalı" +msgstr "Flattr bağış yöntemleri FlattrID: alanında olmalı" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" @@ -822,7 +822,7 @@ msgstr "İnşa, {0} saniye zaman aşımından sonra zorla durduruluyor!" #: ../fdroidserver/scanner.py msgid "Force scan of disabled apps and builds." -msgstr "" +msgstr "Devre dışı bırakılan uygulamaların ve derlemelerin taranmasını zorla." #: ../fdroidserver/update.py #, python-brace-format @@ -832,7 +832,7 @@ msgstr "\"{name}\" uygulaması için üst verisi olmayan \"{path}\" grafiği bul #: ../fdroidserver/update.py #, python-brace-format msgid "Found bad funding file \"{path}\" for \"{name}\":" -msgstr "" +msgstr "\"{name}\" için hatalı ödeme dosyası \"{path}\" bulundu:" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" @@ -844,9 +844,9 @@ msgid "Found invalid versionCodes for some apps" msgstr "Bazı uygulamalar için geçersiz versionCodes bulundu" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found multiple JAR Signature Block Files in {path}" -msgstr "{path} içinde birden çok imzalama sertifikası bulundu" +msgstr "{path} içinde birden fazla JAR İmza Blok Dosyası bulundu" #: ../fdroidserver/metadata.py #, python-brace-format @@ -872,9 +872,9 @@ msgid "Found non-file at %s" msgstr "%s konumunda dosya olmayan bulundu" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "{apkfilename} {path} içine kopyalanıyor" +msgstr "{url} adresinde {apkfilename} bulundu" #: ../fdroidserver/update.py #, python-brace-format @@ -899,9 +899,9 @@ msgid "Git remote set-head failed" msgstr "Git remote set-head başarısız" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Git remote set-head başarısız" +msgstr "Git remote set-head başarısız: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -909,11 +909,11 @@ msgstr "Git reset başarısız" #: ../fdroidserver/common.py msgid "Git submodule sync failed" -msgstr "Git submodule sync başarısız" +msgstr "Git alt modülü eşzamanlaması başarısız oldu" #: ../fdroidserver/common.py msgid "Git submodule update failed" -msgstr "Git submodule update başarısız" +msgstr "Git alt modülü güncellemesi başarısız oldu" #: ../fdroidserver/common.py msgid "HTTPS must be used with Subversion URLs!" @@ -921,22 +921,22 @@ msgstr "Subversion URL'leriyle HTTPS kullanılmalı!" #: ../fdroidserver/server.py msgid "If a git mirror gets to big, allow the archive to be deleted" -msgstr "" +msgstr "Git yansısı çok büyük olursa, arşivin silinmesine izin ver" #: ../fdroidserver/server.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Bu yükleme başarısız olursa, {url} adresine elle yüklemeyi deneyin" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." -msgstr "" +msgstr "Kullanımdan kaldırıldığı için '{metapath}' üst verilerindeki '{field}' yok sayılıyor." #: ../fdroidserver/update.py #, python-format msgid "Ignoring FUNDING.yml entry longer than 2048: %s" -msgstr "" +msgstr "2048'den uzun FUNDING.yml girdisi yok sayılıyor: %s" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -958,19 +958,19 @@ msgstr "MD5 gibi devre dışı algoritmalarla imzalanmış APK'ları dahil et" #: ../fdroidserver/mirror.py msgid "Include the PGP signature .asc files in the mirror" -msgstr "" +msgstr "PGP imzası .asc dosyalarını yansıya dahil et" #: ../fdroidserver/mirror.py msgid "Include the build logs in the mirror" -msgstr "" +msgstr "Derleme günlüklerini yansıya dahil et" #: ../fdroidserver/mirror.py msgid "Include the source tarballs in the mirror" -msgstr "" +msgstr "Kaynak tar arşivlerini yansıya dahil et" #: ../fdroidserver/common.py msgid "Initialising submodules" -msgstr "Altmodüller başlatılıyor" +msgstr "Alt modüller başlatılıyor" #: ../fdroidserver/install.py msgid "Install all signed applications available" @@ -981,9 +981,9 @@ msgid "Install built packages on devices" msgstr "İnşa edilen paketleri aygıtlara kur" #: ../fdroidserver/install.py -#, fuzzy, python-format +#, python-format msgid "Installing %s..." -msgstr "%s kuruluyor…" +msgstr "%s kuruluyor..." #: ../fdroidserver/install.py #, python-format @@ -991,9 +991,9 @@ msgid "Installing %s…" msgstr "%s kuruluyor…" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Installing '{apkfilename}' on {dev}..." -msgstr "'{apkfilename}' {dev} üstüne kuruluyor…" +msgstr "{dev} üzerinde '{apkfilename}' kuruluyor..." #: ../fdroidserver/install.py #, python-brace-format @@ -1066,19 +1066,19 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "HTTPS olmayanlara geçersiz yönlendirme: {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Tüm üst veri dosyalarını oku ve çık" +msgstr "Geçersiz scrlib üst verisi: '{file}' dosyası yok" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: could not parse '{file}'" -msgstr "" +msgstr "Geçersiz srclib üst verisi: '{file}' ayrıştırılamadı" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" -msgstr "" +msgstr "Geçersiz srclib üst verisi: '{file}' içinde bilinmeyen anahtar '{key}'" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1097,7 +1097,7 @@ msgstr "JAR imzası doğrulandı: {path}" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "Java JAR dosyası" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1106,7 +1106,7 @@ msgstr "Java JDK bulunmadı! Standart konumda kurun veya java_paths'i ayarlayın #: ../fdroidserver/scanner.py msgid "Java compiled class" -msgstr "" +msgstr "Java derlenmiş sınıf" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1126,9 +1126,8 @@ msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ msgstr "Son kullanılan işleme '{commit}' bir etiket gibi görünüyor, ama güncelleme denetleme kipi '{ucm}'" #: ../fdroidserver/lint.py -#, fuzzy msgid "Liberapay donation methods belong in the Liberapay: field" -msgstr "Liberapay bağış yöntemleri LiberapayID bayrağında olmalı" +msgstr "Liberapay bağış yöntemleri Liberapay: alanında olmalı" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" @@ -1156,7 +1155,7 @@ msgstr "Bozuk serverwebroot satırı:" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." -msgstr "" +msgstr "Tüm dosya türlerini, tam depoyu ve arşivi yansıla." #: ../fdroidserver/gpgsign.py msgid "Missing output directory" @@ -1194,12 +1193,11 @@ msgstr "URL'de parmak izi yok." #: ../fdroidserver/common.py msgid "No git submodules available" -msgstr "Kullanılabilir git submodules yok" +msgstr "Kullanılabilir git alt modülü yok" #: ../fdroidserver/import.py -#, fuzzy msgid "No gradle project could be found. Specify --subdir?" -msgstr "Android veya kivy projesi bulunamadı. --subdir belirtin?" +msgstr "Gradle projesi bulunamadı. --subdir belirtin?" #: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." @@ -1252,7 +1250,7 @@ msgstr "İmzalanmamış dizin yok - yapılacak işlem yok" #: ../fdroidserver/common.py msgid "Not a valid size definition: \"{}\"" -msgstr "" +msgstr "Geçerli bir boyut tanımı değil: \"{}\"" #: ../fdroidserver/signindex.py msgid "Nothing to do" @@ -1304,9 +1302,8 @@ msgid "Only process apps with auto-updates" msgstr "Yalnızca kendiliğinden güncellemesi olan uygulamaları işle" #: ../fdroidserver/lint.py -#, fuzzy msgid "OpenCollective donation methods belong in the OpenCollective: field" -msgstr "Flattr bağış yöntemleri FlattrID bayrağında olmalı" +msgstr "OpenCollective bağış yöntemleri OpenCollective: alanında olmalı" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1319,13 +1316,13 @@ msgstr "APK'den sonra adlandırılmış dosyaya JSON raporu yazdırın." #: ../fdroidserver/scanner.py msgid "Output JSON to stdout." -msgstr "" +msgstr "Standart çıkışa JSON yazdır." #: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py #: ../fdroidserver/update.py ../fdroidserver/signindex.py #: ../fdroidserver/checkupdates.py msgid "Outputting JSON" -msgstr "" +msgstr "JSON yazdırılıyor" #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1343,7 +1340,7 @@ msgstr "{apkfilename} içindeki boş versionName değerine üst verideki yazıl #: ../fdroidserver/import.py #, python-brace-format msgid "Package \"{appid}\" already exists" -msgstr "" +msgstr "\"{appid}\" paketi zaten var" #: ../fdroidserver/common.py #, python-brace-format @@ -1542,7 +1539,7 @@ msgstr "Her paketin sadece en son sürümünü tara" #: ../fdroidserver/build.py msgid "Scan the resulting APK(s) for known non-free classes." -msgstr "" +msgstr "Bilinen özgür olmayan sınıflar için ortaya çıkan APK'leri tara." #: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" @@ -1570,7 +1567,7 @@ msgstr "Saati o zamana şunu kullanarak ayarla:" #: ../fdroidserver/nightly.py msgid "Set maximum releases in repo before older ones are archived" -msgstr "" +msgstr "Eskileri arşivlenmeden önce depodaki en yüksek sürümleri ayarla" #: ../fdroidserver/build.py #, python-brace-format @@ -1660,7 +1657,7 @@ msgid "Striping mystery signature from {apkfilename}" msgstr "Gizemli imza {apkfilename} dosyasından kaldırılıyor" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Stripping mystery signature from {apkfilename}" msgstr "Gizemli imza {apkfilename} dosyasından kaldırılıyor" @@ -1724,7 +1721,7 @@ msgstr "Bir keyalias çakışması var - yayımlama durdu" #: ../fdroidserver/common.py msgid "These are the apps that have been archived from the main repo." -msgstr "" +msgstr "Bunlar ana depodan arşivlenmiş uygulamalardır." #: ../fdroidserver/import.py #, python-format @@ -1741,7 +1738,7 @@ msgstr "UpdateCheckMode ayarlı ancak checkupdates henüz çalıştırılmamış #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" -msgstr "" +msgstr "URL https:// veya http:// ile başlamalı" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" @@ -1757,13 +1754,12 @@ msgid "URL {url} in Description: {error}" msgstr "Açıklamada URL {url}: {error}" #: ../fdroidserver/lint.py -#, fuzzy msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" -msgstr "Geçersiz lisans etiketi \"%s\"! Yalnızca https://spdx.org/license-list adresindeki etiketleri kullanın" +msgstr "Beklenmeyen lisans etiketi \"{}\"! Yalnızca https://spdx.org/license-list adresindeki FSF veya OSI onaylı etiketleri kullanın" #: ../fdroidserver/lint.py msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" -msgstr "" +msgstr "Beklenmeyen lisans etiketi \"{}\"! Yalnızca yapılandırma dosyanızda yapılandırılan lisans etiketlerini kullanın" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1791,9 +1787,9 @@ msgid "Unknown metadata format: {path}" msgstr "Bilinmeyen üst veri biçimi: {path}" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path} (use: *.yml)" -msgstr "Bilinmeyen üst veri biçimi: {path}" +msgstr "Bilinmeyen üst veri biçimi: {path} (şunu kullanın: *.yml)" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1874,14 +1870,14 @@ msgid "Unused file at %s" msgstr "%s konumunda kullanılmayan dosya" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scandelete path: %s" -msgstr "%s konumunda kullanılmayan dosya" +msgstr "Kullanılmayan scandelete yolu: %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scanignore path: %s" -msgstr "%s konumunda kullanılmayan dosya" +msgstr "Kullanılmayan scanignore yolu: %s" #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" @@ -1921,12 +1917,12 @@ msgstr "UpdateCheckData geçerli bir URL değil: {url}" #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" -msgstr "" +msgstr "{apkfilename}, androidobservatory.org'a yükleniyor" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Uploading {apkfilename} to virustotal" -msgstr "{apkfilename} önbellekten okunuyor" +msgstr "{apkfilename} virustotal'e yükleniyor" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1965,11 +1961,11 @@ msgstr "s3cmd yapılandırması için \"{path}\" kullanılıyor." #: ../fdroidserver/common.py msgid "Using APK Signature v2" -msgstr "" +msgstr "APK İmza v2 kullanılıyor" #: ../fdroidserver/common.py msgid "Using APK Signature v3" -msgstr "" +msgstr "APK İmza v3 kullanılıyor" #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" @@ -2009,7 +2005,7 @@ msgstr "İndeks imzası doğrulanıyor:" #: ../fdroidserver/server.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." -msgstr "" +msgstr "VirusTotal API anahtarı 32MB'den büyük dosyaları yükleyemiyor, {path} yüklemek için {url} kullanın." #: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" @@ -2021,7 +2017,7 @@ msgstr "İmzalı indeksler için yapılandırıldığında, bu aşamada sadece i #: ../fdroidserver/lint.py msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." -msgstr "" +msgstr "Tüm depo denetlenirken yamllint öntanımlı olarak devre dışı bırakılır. Bu seçenek, yamllint kullanımını ne olursa olsun zorlar." msgid "X.509 'Distiguished Name' used when generating keys" msgstr "Anahtarlar üretilirken X.509 'Distinguished Name' kullanılır" @@ -2036,7 +2032,7 @@ msgstr "SDK'nızın konumunu ayarlamak için ANDROID_HOME'u kullanabilirsiniz:" #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "" +msgstr "ZIP dosya arşivi" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2062,7 +2058,7 @@ msgstr "belirsiz şeçenek: %s (%s?)" #: ../fdroidserver/common.py msgid "apksigner not found, it's required for signing!" -msgstr "" +msgstr "apksigner bulunamadı, imzalamak için gereklidir!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2086,9 +2082,8 @@ msgid "argument \"-\" with mode %r" msgstr "%r kipiyle \"-\" argümanı" #: ../fdroidserver/nightly.py -#, fuzzy msgid "attempting bare SSH connection to test deploy key:" -msgstr "Dağıtım anahtarını sınamak için çıplak ssh bağlantısı deneniyor:" +msgstr "Dağıtım anahtarını sınamak için çıplak SSH bağlantısı deneniyor:" #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" @@ -2096,7 +2091,7 @@ msgstr "Dağıtım anahtarını sınamak için çıplak ssh bağlantısı deneni #: ../fdroidserver/common.py msgid "can not parse scrlib spec (not a string): '{}'" -msgstr "" +msgstr "scrlib belirtimi ayrıştırılamıyor (bir dizge değil): '{}'" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2105,9 +2100,9 @@ msgid "can't open '%s': %s" msgstr "'%s' açılamıyor: %s" #: ../fdroidserver/build.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "cannot find required srclibs: \"{path}\"" -msgstr "{path} için bir appid bulunamıyor!" +msgstr "gerekli srclibs bulunamıyor: \"{path}\"" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2135,7 +2130,7 @@ msgstr "çalıştırılacak komut, 'init' ya da 'update'" #: ../fdroidserver/__main__.py msgid "commands from plugin modules:" -msgstr "" +msgstr "eklenti modüllerinden komutlar:" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2158,15 +2153,15 @@ msgstr "{apkfilename} {path} içine kopyalanıyor" #: ../fdroidserver/metadata.py #, python-brace-format msgid "could not parse '{path}'" -msgstr "" +msgstr "'{path}' ayrıştırılamadı" #: ../fdroidserver/common.py msgid "could not parse srclib spec (no ref specified): '{}'" -msgstr "" +msgstr "srclib belirtimi ayrıştırılamadı (referans belirtilmedi): '{}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (too many '@' signs): '{}'" -msgstr "" +msgstr "srclib belirtimi ayrıştırılamadı (çok fazla '@' işareti): '{}'" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2186,7 +2181,7 @@ msgstr "'{path}' için günlükleri oluşturdu" #: ../fdroidserver/common.py #, python-brace-format msgid "deployed process log {path} to {dest}" -msgstr "" +msgstr "{path} işlem günlüğü {dest}'e dağıtıldı" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2196,7 +2191,7 @@ msgstr "dest= %r gibi seçenekler için gerekli" #: ../fdroidserver/scanner.py msgid "executable binary, possibly code" -msgstr "" +msgstr "çalıştırılabilir ikili dosya, muhtemelen kod" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2253,7 +2248,7 @@ msgstr "git svn clone başarısız" #: ../fdroidserver/scanner.py msgid "gzip file archive" -msgstr "" +msgstr "gzip dosya arşivi" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2423,7 +2418,7 @@ msgstr "konumsal argümanlar" #: ../fdroidserver/common.py #, python-brace-format msgid "process log deploy {path} to {dest} failed!" -msgstr "" +msgstr "{path} işlem günlüğünü {dest}'e dağıtma başarısız oldu!" #: ../fdroidserver/signatures.py #, python-brace-format @@ -2437,7 +2432,7 @@ msgstr "güvensiz http bağlantısı ile indirmeyi reddet (https kullanın veya #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." -msgstr "" +msgstr "ruamel.yaml kurulu değil, üst veriler yazılamıyor." #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -2446,7 +2441,7 @@ msgstr "s3cmd sync {path} konumunu {url} adresine indeksler ve siler" #: ../fdroidserver/scanner.py msgid "shared library" -msgstr "" +msgstr "paylaşımlı kütüphane" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2482,7 +2477,7 @@ msgstr "srclibs'de ad ve/veya @ eksik" #: ../fdroidserver/scanner.py msgid "static library" -msgstr "" +msgstr "statik kütüphane" #: ../fdroidserver/common.py #, python-brace-format @@ -2534,7 +2529,7 @@ msgstr "{url} ile eşitleme için Apache libcloud kullanılıyor" #: ../fdroidserver/server.py msgid "virustotal.com is rate limiting, waiting to retry..." -msgstr "" +msgstr "virustotal.com hızı sınırlıyor, yeniden deneme bekleniyor..." #: ../fdroidserver/publish.py #, python-brace-format @@ -2602,7 +2597,7 @@ msgstr "{appid}: {field} bir '{type}' olmalı, fakat o bir '{fieldtype}'!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{build_flag} must be an integer, found: {value}" -msgstr "" +msgstr "{build_flag} bir tam sayı olmalıdır, bulunan: {value}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2612,7 +2607,7 @@ msgstr "{field} alanı {name} içinde sonlandırılmamış" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{file} is blank or corrupt!" -msgstr "" +msgstr "{file} boş veya bozuk!" #: ../fdroidserver/update.py #, python-brace-format @@ -2622,7 +2617,7 @@ msgstr "{name} \"{path}\" yok! config.py içinde düzeltin." #: ../fdroidserver/import.py #, python-brace-format msgid "{path} already exists, ignoring import results!" -msgstr "" +msgstr "{path} zaten var, içe aktarma sonuçları yok sayılıyor!" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2642,7 +2637,7 @@ msgstr "{path} boyutu sıfır!" #: ../fdroidserver/server.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" -msgstr "" +msgstr "{path} 200MB'den fazla, elle yükleyin: {url}" #: ../fdroidserver/mirror.py #, python-brace-format @@ -2650,9 +2645,9 @@ msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} \"fdroid\" ile bitmiyor, URL konumunu doğrulayın!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{url} does not start with \"http\"!" -msgstr "{url} \"fdroid\" ile bitmiyor, URL konumunu doğrulayın!" +msgstr "{url} \"http\" ile başlamıyor!" #: ../fdroidserver/build.py msgid "{} build failed" From 48fa684d641e9765a0426ae509de74e1a2f3eeeb Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Sat, 17 Oct 2020 07:19:29 +0200 Subject: [PATCH 0560/2775] Translated using Weblate: Portuguese (Brazil) (pt_BR) by Rafael Fontenelle Currently translated at 93.2% (527 of 565 strings) Co-authored-by: Rafael Fontenelle Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translation: F-Droid/F-Droid Server --- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 139 +++++++++++------------ 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 30f0a62b..efb7cd81 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -3,13 +3,14 @@ # Wellington Terumi Uemura , 2020. # André Marcelo Alvarenga , 2020. # Hans-Christoph Steiner , 2020. +# Rafael Fontenelle , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-10-01 09:00+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-10-01 20:58+0000\n" +"Last-Translator: Rafael Fontenelle \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -27,6 +28,13 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Este é um repositório de aplicativos a serem usados com o FDroid. Os\n" +" aplicativos neste repositório são binários oficiais compilados pelos\n" +" desenvolvedores do aplicativo original ou são binários compilados a\n" +" partir da fonte por f-droid.org usando as ferramentas em\n" +" https://gitlab.com/fdroid.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -37,13 +45,12 @@ msgstr "" "Chave pública SSH para ser usada como chave de implantar:" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" msgstr "" "\n" -"Chave pública SSH para ser usada como chave de implantar:" +"Chave pública SSH para ser usada como chave de implantação:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -60,9 +67,9 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" não tem arquivo de metadados correspondente!" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." -msgstr "'{apkfilename}' já está instalado no {dev}." +msgstr "\"{apkfilename}\" já está instalado em {dev}." #: ../fdroidserver/update.py #, python-brace-format @@ -80,9 +87,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe, mas s3cmd não está instalado!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" +msgstr "\"{path}\" não é um formato aceito (use: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -92,7 +99,7 @@ msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" não é uma URL válida!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -146,7 +153,7 @@ msgstr "'keypass' não foi encontrada em config.py!" #: ../fdroidserver/common.py msgid "'keystore' is NONE and 'smartcardoptions' is blank!" -msgstr "" +msgstr "\"keystore\" é NONE e \"smartcardoptions\" está vazia!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" @@ -268,16 +275,15 @@ msgstr "Também avisar sobre problemas de formatação, como rewritemeta -l" #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "Biblioteca AAR do Android" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Arquivo APK do Android" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "Nenhum 'Android SDK' foi encontrado!" +msgstr "Código DEX do Android" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -342,7 +348,7 @@ msgstr "Ramificação '{branch}' usada como commit em srclib '{srclib}'" #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Link simbólico quebrado: {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -401,9 +407,9 @@ msgid "Cannot resolve app id {appid}" msgstr "Impossível resolver o ID de Aplicativo '{appid}'" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "Impossível ler \"{path}\"!" +msgstr "Não é possível reescrever \"{path}\"" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -463,7 +469,7 @@ msgstr "Enviar mudanças" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Argumentos conflitantes: \"--verbose\" e \"--quiet\" não podem ser especificados ao mesmo tempo." #: ../fdroidserver/common.py #, python-brace-format @@ -471,14 +477,12 @@ msgid "Could not find '{command}' on your system" msgstr "Impossível encontrar '{command}' em seu sistema" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version code" -msgstr "Impossível encontrar o código da versão mais recente" +msgstr "Não foi possível encontrar o código da versão mais recente" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version name" -msgstr "Impossível encontrar o nome da versão mais recente" +msgstr "Não foi possível encontrar o nome da versão mais recente" #: ../fdroidserver/update.py #, python-brace-format @@ -492,12 +496,11 @@ msgstr "Impossível abrir o arquivo de APK para analisá-lo" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not parse size \"{size}\", wrong type \"{type}\"" -msgstr "" +msgstr "Não foi possível analisar o tamanho \"{size}\", tipo incorreto \"{type}\"" #: ../fdroidserver/import.py -#, fuzzy msgid "Couldn't find Application ID" -msgstr "Impossível encontrar o ID do pacote" +msgstr "Não foi possível encontrar o ID do aplicativo" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -577,12 +580,12 @@ msgstr "Apagar os APKs e/ou OBBs sem metadados do repositório" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Excluindo o pacote, o repositório está grande demais ({size} máx {limit})" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Excluindo histórico de git-mirror, o repositório está grande demais ({size} máx {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -610,7 +613,7 @@ msgstr "A descrição de tamanho {length} está acima do limite de {limit} carac #: ../fdroidserver/import.py msgid "Do not add 'disable:' to the generated build entries" -msgstr "" +msgstr "Não adicione \"disable:\" para as entradas de compilação geradas" #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" @@ -697,7 +700,7 @@ msgstr "Bandeira de construção vazia no {linedesc}" #: ../fdroidserver/__main__.py #, python-brace-format msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." -msgstr "" +msgstr "A codificação está definida para \"{enc}\", fdroid pode ter problemas de codificação. Defina-a para \"UTF-8\" para melhores resultados." #: ../fdroidserver/init.py #, python-format @@ -723,9 +726,9 @@ msgid "Extract signatures from APKs" msgstr "Extrair assinaturas de APKs" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Failed copying {path}: {error}" -msgstr "Falha ao ler {path}: {error}" +msgstr "Falha ao copiar {path}: {error}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -791,7 +794,7 @@ msgstr "As assinaturas buscadas para '{apkfilename}' -> '{sigdir}'" #: ../fdroidserver/update.py #, python-brace-format msgid "File disappeared while processing it: {path}" -msgstr "" +msgstr "O arquivo desapareceu enquanto era processado: {path}" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -805,9 +808,8 @@ msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Métodos de doação Flattr pertencem ao sinalizador FlattrID" #: ../fdroidserver/lint.py -#, fuzzy msgid "Flattr donation methods belong in the FlattrID: field" -msgstr "Métodos de doação Flattr pertencem ao sinalizador FlattrID" +msgstr "Métodos de doação Flattr pertencem ao campo FlattrID" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" @@ -824,7 +826,7 @@ msgstr "Forçar a parada da compilação após tempo limite de {0} segundos!" #: ../fdroidserver/scanner.py msgid "Force scan of disabled apps and builds." -msgstr "" +msgstr "Força varredura de aplicativos e compilações desativadas." #: ../fdroidserver/update.py #, python-brace-format @@ -834,7 +836,7 @@ msgstr "Foi encontrado o gráfico \"{path}\" sem metadados para o aplicativo \"{ #: ../fdroidserver/update.py #, python-brace-format msgid "Found bad funding file \"{path}\" for \"{name}\":" -msgstr "" +msgstr "Encontrado arquivo inválido \"{path}\" de financiamento para \"{name}\":" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" @@ -846,9 +848,9 @@ msgid "Found invalid versionCodes for some apps" msgstr "Encontrado versões de códigos inválidas para alguns aplicativos" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found multiple JAR Signature Block Files in {path}" -msgstr "Encontrado vários certificados de assinatura em {path}" +msgstr "Encontrados vários arquivos de bloqueio de assinatura JAR em {path}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -874,9 +876,9 @@ msgid "Found non-file at %s" msgstr "Arquivo não encontrado em %s" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "copiando {apkfilename} para {path}" +msgstr "Encontrado {apkfilename} em {url}" #: ../fdroidserver/update.py #, python-brace-format @@ -901,9 +903,9 @@ msgid "Git remote set-head failed" msgstr "Falha ao indicar o 'head' do Git remoto" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Falha ao indicar o 'head' do Git remoto" +msgstr "Git remote set-head falhou: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -923,22 +925,22 @@ msgstr "HTTPS deve ser usado com URLs do Subversion(SVN)!" #: ../fdroidserver/server.py msgid "If a git mirror gets to big, allow the archive to be deleted" -msgstr "" +msgstr "Se um espelho git ficar muito grande, permite que o arquivo seja excluído" #: ../fdroidserver/server.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Se o upload falhar, tente fazer o upload manualmente para {url}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." -msgstr "" +msgstr "Ignorando \"{field}\" em metadados \"{metapath}\" porque foi descontinuado." #: ../fdroidserver/update.py #, python-format msgid "Ignoring FUNDING.yml entry longer than 2048: %s" -msgstr "" +msgstr "Ignorando entrada de FUNDING.yml maior que 2048: %s" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -960,15 +962,15 @@ msgstr "Inclua APKs assinados com algoritmos desativados, como o MD5" #: ../fdroidserver/mirror.py msgid "Include the PGP signature .asc files in the mirror" -msgstr "" +msgstr "Inclui os arquivos de assinatura PGP (.asc) no espelho" #: ../fdroidserver/mirror.py msgid "Include the build logs in the mirror" -msgstr "" +msgstr "Inclui os logs de compilação no espelho" #: ../fdroidserver/mirror.py msgid "Include the source tarballs in the mirror" -msgstr "" +msgstr "Inclui os tarballs fonte no espelho" #: ../fdroidserver/common.py msgid "Initialising submodules" @@ -983,9 +985,9 @@ msgid "Install built packages on devices" msgstr "Instalar pacotes prontos nos dispositivos" #: ../fdroidserver/install.py -#, fuzzy, python-format +#, python-format msgid "Installing %s..." -msgstr "Instalando %s …" +msgstr "Instalando %s…" #: ../fdroidserver/install.py #, python-format @@ -993,9 +995,9 @@ msgid "Installing %s…" msgstr "Instalando %s …" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Installing '{apkfilename}' on {dev}..." -msgstr "Instalando '{apkfilename}' em {dev} …" +msgstr "Instalando \"{apkfilename}\" em {dev}…" #: ../fdroidserver/install.py #, python-brace-format @@ -1068,19 +1070,19 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Redirecionamento inválido para não HTTPS: {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Ler todos os arquivos de metadados e sair" +msgstr "Metadados de scrlib inválidos: \"{file}\" não existe" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: could not parse '{file}'" -msgstr "" +msgstr "Metadados de srclib inválidos: não foi possível analisar \"{file}\"" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" -msgstr "" +msgstr "Metadados de srclib inválidos: chave desconhecida \"{key}\" em \"{file}\"" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1099,7 +1101,7 @@ msgstr "Assinatura do JAR verificada: {path}" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "Arquivo JAR de Java" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1108,7 +1110,7 @@ msgstr "Java JDK não encontrado! Instale no local padrão ou defina java_paths! #: ../fdroidserver/scanner.py msgid "Java compiled class" -msgstr "" +msgstr "Classe Java compilada" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1128,9 +1130,8 @@ msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ msgstr "O último commit usado '{commit}' parece com uma tag, mas o Update Check Mode é '{ucm}'" #: ../fdroidserver/lint.py -#, fuzzy msgid "Liberapay donation methods belong in the Liberapay: field" -msgstr "Métodos de doação Liberapay pertencem à bandeira LiberapayID" +msgstr "Métodos de doação do Liberapay pertencem ao campo LiberapayID" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" @@ -1158,7 +1159,7 @@ msgstr "Linha mal-formada do 'serverwebroot':" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." -msgstr "" +msgstr "Espelha todo o repositório e pacotes, todos os tipos de arquivos." #: ../fdroidserver/gpgsign.py msgid "Missing output directory" @@ -1199,9 +1200,8 @@ msgid "No git submodules available" msgstr "Nenhum Submódulo Git disponível" #: ../fdroidserver/import.py -#, fuzzy msgid "No gradle project could be found. Specify --subdir?" -msgstr "Nenhum projeto android ou kivy foi encontrado. Especifique --subdir?" +msgstr "Nenhum projeto gradle foi encontrado. Especifique --subdir?" #: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." @@ -1254,7 +1254,7 @@ msgstr "Nenhum diretório não assinado - nada a fazer" #: ../fdroidserver/common.py msgid "Not a valid size definition: \"{}\"" -msgstr "" +msgstr "Não é uma definição de tamanho válida: \"{}\"" #: ../fdroidserver/signindex.py msgid "Nothing to do" @@ -1306,9 +1306,8 @@ msgid "Only process apps with auto-updates" msgstr "Processar apenas aplicativos com atualizações automáticas" #: ../fdroidserver/lint.py -#, fuzzy msgid "OpenCollective donation methods belong in the OpenCollective: field" -msgstr "Métodos de doação Flattr pertencem ao sinalizador FlattrID" +msgstr "Os métodos de doação opencollective pertencem ao campo OpenCollective" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1321,13 +1320,13 @@ msgstr "Exporte a saída do relatório JSON para um nome de arquivo após APK." #: ../fdroidserver/scanner.py msgid "Output JSON to stdout." -msgstr "" +msgstr "Emite JSON para stdout (saída padrão)." #: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py #: ../fdroidserver/update.py ../fdroidserver/signindex.py #: ../fdroidserver/checkupdates.py msgid "Outputting JSON" -msgstr "" +msgstr "Emitindo JSON" #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1345,7 +1344,7 @@ msgstr "Substituindo versionName em branco em {apkfilename} dos metadados: {vers #: ../fdroidserver/import.py #, python-brace-format msgid "Package \"{appid}\" already exists" -msgstr "" +msgstr "O pacote \"{appid}\" já existe" #: ../fdroidserver/common.py #, python-brace-format From d49dacc92452acb5e093afdd9bfd73735ea62fc3 Mon Sep 17 00:00:00 2001 From: melusine Date: Sat, 17 Oct 2020 07:19:30 +0200 Subject: [PATCH 0561/2775] Translated using Weblate: German (de) by melusine Currently translated at 86.5% (489 of 565 strings) Translated using Weblate: German (de) by melusine Currently translated at 85.6% (484 of 565 strings) Co-authored-by: melusine Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/de/ Translation: F-Droid/F-Droid Server --- locale/de/LC_MESSAGES/fdroidserver.po | 42 ++++++++++++++++----------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index 6fa96719..ab749f51 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -2,13 +2,14 @@ # Copyright (C) YEAR Free Software Foundation, Inc. # Oliver , 2020. # Fynn Godau , 2020. +# melusine , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-09-23 14:57+0000\n" -"Last-Translator: Fynn Godau \n" +"PO-Revision-Date: 2020-10-02 19:15+0000\n" +"Last-Translator: melusine \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" @@ -26,6 +27,13 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Dies ist eine Paketquelle für Anwendungen, die für die Benutzung\n" +" zusammen mit F-Droid gedacht ist. Die darin enthaltenen\n" +" Anwendungen sind entweder offizielle von den Entwicklern erstellte\n" +" Binärdateien oder werden von f-droid.org mithilfe des Werkzeugs auf\n" +" https://gitlab.com/fdroid aus dem Quellcode erstellt.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -91,7 +99,7 @@ msgstr "\"{path}\" ist kein akzeptiertes Format, umwandeln in: {formats}" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" ist keine gültige URL!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -267,11 +275,11 @@ msgstr "Auch vor Formatierungsfehler warnen, wie etwa \"rewritemeta -l\"" #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "Android AAR-Bibliothek" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Android APK-Datei" #: ../fdroidserver/scanner.py #, fuzzy @@ -341,7 +349,7 @@ msgstr "Zweig „{branch}” wird als Bestätigung in srclib verwendet „{srcli #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Kaputter Symlink: {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -462,7 +470,7 @@ msgstr "Änderungen übergeben" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Widersprüchliche Argumente: '--verbose' und '--quiet' können nicht gleichzeitig angegeben werden." #: ../fdroidserver/common.py #, python-brace-format @@ -491,7 +499,7 @@ msgstr "Konnte APK-Datei nicht für Analyse öffnen" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not parse size \"{size}\", wrong type \"{type}\"" -msgstr "" +msgstr "Konnte Größe \"{size}\" nicht parsen, falscher Typ \"{type}\"" #: ../fdroidserver/import.py #, fuzzy @@ -574,9 +582,9 @@ msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "APKs und/oder OBBs ohne Metadaten aus dem Repository löschen" #: ../fdroidserver/server.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Archiv löschen, Repo ist zu groß ({size} max {limit})" #: ../fdroidserver/server.py #, python-brace-format @@ -925,9 +933,9 @@ msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" #: ../fdroidserver/server.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Wenn dieser Upload fehlschlägt, versuchen Sie ihn manuell auf {url} hochzuladen." #: ../fdroidserver/metadata.py #, python-brace-format @@ -1098,7 +1106,7 @@ msgstr "JAR-Signatur verifiziert: {path}" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "Java JAR-Datei" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1107,7 +1115,7 @@ msgstr "Java JDK nicht gefunden! Installieren Sie es in einem Standardordner ode #: ../fdroidserver/scanner.py msgid "Java compiled class" -msgstr "" +msgstr "Java-kompilierte Klasse" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1253,7 +1261,7 @@ msgstr "Kein unsigniertes Verzeichnis - nichts zu tun" #: ../fdroidserver/common.py msgid "Not a valid size definition: \"{}\"" -msgstr "" +msgstr "Keine gültige Größendefinition: \"{}\"" #: ../fdroidserver/signindex.py msgid "Nothing to do" @@ -1326,7 +1334,7 @@ msgstr "" #: ../fdroidserver/update.py ../fdroidserver/signindex.py #: ../fdroidserver/checkupdates.py msgid "Outputting JSON" -msgstr "" +msgstr "JSON ausgeben" #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1344,7 +1352,7 @@ msgstr "Überschreiben von leeren Versionsnamen in {apkfilename} aus Metadaten: #: ../fdroidserver/import.py #, python-brace-format msgid "Package \"{appid}\" already exists" -msgstr "" +msgstr "Paket \"{appid}\" existiert bereits" #: ../fdroidserver/common.py #, python-brace-format From 8ee6ed5c46b136ac70eb99e2c2a994530f250ce3 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Sat, 17 Oct 2020 07:19:31 +0200 Subject: [PATCH 0562/2775] Translated using Weblate: Ukrainian (uk) by ihor_ck Currently translated at 100.0% (565 of 565 strings) Translated using Weblate: Ukrainian (uk) by ihor_ck Currently translated at 93.4% (528 of 565 strings) Co-authored-by: ihor_ck Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/uk/ Translation: F-Droid/F-Droid Server --- locale/uk/LC_MESSAGES/fdroidserver.po | 223 +++++++++++++------------- 1 file changed, 109 insertions(+), 114 deletions(-) diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index e52b8b03..7ccd4ba6 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-09-19 17:03+0000\n" +"PO-Revision-Date: 2020-10-02 19:15+0000\n" "Last-Translator: ihor_ck \n" "Language-Team: Ukrainian \n" "Language: uk\n" @@ -26,6 +26,12 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Це сховище застосунків для використання з FDroid. Застосунки в цьому\n" +" сховищі — це або офіційні двійкові файли, побудовані за розробниками оригінального\n" +" застосунку, або двійкові файли, побудовані з джерела f-droid.org за допомогою\n" +" інструментів з https://gitlab.com/fdroid.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -36,13 +42,12 @@ msgstr "" "Громадський ключ SSH буде використино як постановчий ключ (Deploy Key):" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" msgstr "" "\n" -"Громадський ключ SSH буде використино як постановчий ключ (Deploy Key):" +"Загальнодоступний ключ SSH буде використано як ключ розгортання:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -59,9 +64,9 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" не має відповідного файлу метаданих!" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." -msgstr "'{apkfilename}' вже встановлено на {dev}." +msgstr "\"{apkfilename}\" вже встановлено на {dev}." #: ../fdroidserver/update.py #, python-brace-format @@ -79,9 +84,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" існує, але s3cmd не встановлений!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" має непідтримуваний формат, конвертувати до: {formats}" +msgstr "\"{path}\" має непідтримуваний формат (скористайтеся: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -91,7 +96,7 @@ msgstr "\"{path}\" має непідтримуваний формат, конв #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" є недійсною URL-адресою!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -146,7 +151,7 @@ msgstr "'keypass' не знайдено в config.py!" #: ../fdroidserver/common.py msgid "'keystore' is NONE and 'smartcardoptions' is blank!" -msgstr "" +msgstr "'keystore' — NONE і 'smartcardoptions' порожній!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" @@ -268,16 +273,15 @@ msgstr "Також попередити про проблеми форматув #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "Бібліотека Android AAR" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Файл Android APK" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "Не знайдено Android SDK!" +msgstr "Код Android DEX" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -342,7 +346,7 @@ msgstr "Гілка '{branch}' використовується як поданн #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Недійсне посилання: {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -402,9 +406,9 @@ msgid "Cannot resolve app id {appid}" msgstr "Неможливо розв'язати id застосунку {appid}" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "Неправильно вказано шлях \"{path}\"!" +msgstr "Не вдалося перезаписати шлях \"{path}\"" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -464,7 +468,7 @@ msgstr "Прийняти зміни" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Конфліктні аргументи: \"---verbose\" і \"--quiet\" не можна вказати одночасно." #: ../fdroidserver/common.py #, python-brace-format @@ -472,14 +476,12 @@ msgid "Could not find '{command}' on your system" msgstr "Не вдалося знайти '{command}' у вашій системі" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version code" -msgstr "Не вдається знайти останню версію коду" +msgstr "Не вдалося знайти останню версію коду" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version name" -msgstr "Не вдається знайти найновішу назву версії" +msgstr "Не вдалося знайти найновішу назву версії" #: ../fdroidserver/update.py #, python-brace-format @@ -493,12 +495,11 @@ msgstr "Не вдалося відкрити файл apk для аналізу" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not parse size \"{size}\", wrong type \"{type}\"" -msgstr "" +msgstr "Не вдалося проаналізувати розмір \"{size}\", неправильний тип \"{type}\"" #: ../fdroidserver/import.py -#, fuzzy msgid "Couldn't find Application ID" -msgstr "Не вдається знайти ідентифікатор пакета" +msgstr "Не вдалося знайти ID застосунку" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -578,12 +579,12 @@ msgstr "Видалити APKs і/або OBBs без метаданих зі сх #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Видалення архіву, сховище завелике ({size} макс. {limit})" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Видалення історії git-mirror, сховище завелике ({size} макс {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -611,7 +612,7 @@ msgstr "Довжина опису {length} перевищує ліміт {limit} #: ../fdroidserver/import.py msgid "Do not add 'disable:' to the generated build entries" -msgstr "" +msgstr "Не додавайте 'disable:' до створених записів збірки" #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" @@ -698,7 +699,7 @@ msgstr "Порожній прапорець збірки на {linedesc}" #: ../fdroidserver/__main__.py #, python-brace-format msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." -msgstr "" +msgstr "Кодування встановлено на '{enc}' fdroid може отримати проблеми з кодуванням. Встановіть його на 'UTF-8' для найкращих результатів." #: ../fdroidserver/init.py #, python-format @@ -724,9 +725,9 @@ msgid "Extract signatures from APKs" msgstr "Експортування підписів з APK" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Failed copying {path}: {error}" -msgstr "Не вдалося розпізнати {path}: {error}" +msgstr "Не вдалося копіювати {path}: {error}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -792,7 +793,7 @@ msgstr "Отримані підписи для '{apkfilename}' -> '{sigdir}'" #: ../fdroidserver/update.py #, python-brace-format msgid "File disappeared while processing it: {path}" -msgstr "" +msgstr "Файл зник під час його обробки: {path}" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -806,9 +807,8 @@ msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Методи допомоги Flattr належать до прапора FlattrID" #: ../fdroidserver/lint.py -#, fuzzy msgid "Flattr donation methods belong in the FlattrID: field" -msgstr "Методи допомоги Flattr належать до прапора FlattrID" +msgstr "Належний до FlattrID метод допомоги Flattr: не вдалося" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" @@ -825,7 +825,7 @@ msgstr "Примусово зупиняти збірку після {0} сек. #: ../fdroidserver/scanner.py msgid "Force scan of disabled apps and builds." -msgstr "" +msgstr "Примусово сканувати вимкнені застосунки та збірки." #: ../fdroidserver/update.py #, python-brace-format @@ -835,7 +835,7 @@ msgstr "У \"{path}\" виявлено зображення без метада #: ../fdroidserver/update.py #, python-brace-format msgid "Found bad funding file \"{path}\" for \"{name}\":" -msgstr "" +msgstr "Знайдено пошкоджений файл фінансування \"{path}\" для \"{name}\":" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" @@ -847,9 +847,9 @@ msgid "Found invalid versionCodes for some apps" msgstr "Знайдено недійсні версії коду для деяких застосунків" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found multiple JAR Signature Block Files in {path}" -msgstr "Знайдено кілька сертифікатів для підписання на {path}" +msgstr "Знайдено кілька файлів блоку підписів JAR у {path}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -875,9 +875,9 @@ msgid "Found non-file at %s" msgstr "Знайдено не файл у %s" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "копіювання {apkfilename} у {path}" +msgstr "Знайдено {apkfilename} у {url}" #: ../fdroidserver/update.py #, python-brace-format @@ -902,9 +902,9 @@ msgid "Git remote set-head failed" msgstr "Не вдалося встановити пульт дистанційного керування Git" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Не вдалося встановити пульт дистанційного керування Git" +msgstr "Помилка зовнішнього налаштування Git: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -924,22 +924,22 @@ msgstr "HTTPS потрібно використовувати з URL-адрес #: ../fdroidserver/server.py msgid "If a git mirror gets to big, allow the archive to be deleted" -msgstr "" +msgstr "Якщо git mirror стає великим, дозволити видалити архів" #: ../fdroidserver/server.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Якщо це завантаження не вдалося, спробуйте завантажити власноруч на {url}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." -msgstr "" +msgstr "Нехтування метаданими '{field}' у метаданих '{metapath}', оскільки їх вилучено." #: ../fdroidserver/update.py #, python-format msgid "Ignoring FUNDING.yml entry longer than 2048: %s" -msgstr "" +msgstr "Нехтування записом FUNDING.yml з датою після 2048 року: %s" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -961,15 +961,15 @@ msgstr "Включити APK, які підписані без алгоритм #: ../fdroidserver/mirror.py msgid "Include the PGP signature .asc files in the mirror" -msgstr "" +msgstr "Включити у дзеркало файли .asc підпису PGP" #: ../fdroidserver/mirror.py msgid "Include the build logs in the mirror" -msgstr "" +msgstr "Включити журнали збірки в дзеркало" #: ../fdroidserver/mirror.py msgid "Include the source tarballs in the mirror" -msgstr "" +msgstr "Включити джерело tarballs в дзеркало" #: ../fdroidserver/common.py msgid "Initialising submodules" @@ -984,9 +984,9 @@ msgid "Install built packages on devices" msgstr "Встановити побудовані пакети на пристрої" #: ../fdroidserver/install.py -#, fuzzy, python-format +#, python-format msgid "Installing %s..." -msgstr "Встановлення %s…" +msgstr "Встановлення %s..." #: ../fdroidserver/install.py #, python-format @@ -994,9 +994,9 @@ msgid "Installing %s…" msgstr "Встановлення %s…" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Installing '{apkfilename}' on {dev}..." -msgstr "Встановлення '{apkfilename}' на {dev}…" +msgstr "Встановлення '{apkfilename}' на {dev}..." #: ../fdroidserver/install.py #, python-brace-format @@ -1069,19 +1069,19 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Недійсне переспрямування на не-HTTPS: {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Прочитайте всі файли метаданих і вийдіть" +msgstr "Недійсні метадані scrlib: '{file}' не існує" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: could not parse '{file}'" -msgstr "" +msgstr "Неправильні метадані srclib: не вдалося зчитати «{file}»" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" -msgstr "" +msgstr "Неприпустимі метадані srclib: невідомий ключ '{key}' у '{file}'" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1100,7 +1100,7 @@ msgstr "Підтверджено підпис JAR: {path}" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "Файл Java JAR" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1109,7 +1109,7 @@ msgstr "Java JDK не знайдено! Встановіть в усталено #: ../fdroidserver/scanner.py msgid "Java compiled class" -msgstr "" +msgstr "Java складений клас" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1129,9 +1129,8 @@ msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ msgstr "Останнє подання '{commit}' виглядає як мітка, але в режимі перевірки оновлення '{ucm}'" #: ../fdroidserver/lint.py -#, fuzzy msgid "Liberapay donation methods belong in the Liberapay: field" -msgstr "Методи допомоги Flattr належать до прапора FlattrID" +msgstr "Належний до Liberapay метод допомоги Liberapay: не вдалося" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" @@ -1159,7 +1158,7 @@ msgstr "Несправний шлях serverwebroot:" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." -msgstr "" +msgstr "Дзеркало всього сховища та архіву всіх типів файлів." #: ../fdroidserver/gpgsign.py msgid "Missing output directory" @@ -1200,9 +1199,8 @@ msgid "No git submodules available" msgstr "Немає доступних підмодулів git" #: ../fdroidserver/import.py -#, fuzzy msgid "No gradle project could be found. Specify --subdir?" -msgstr "Не знайдено жодного Android чи kivy проєкту. Вказати його у --subdir?" +msgstr "Не знайдено жодного проєкту gradle. Вказати його у --subdir?" #: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." @@ -1255,7 +1253,7 @@ msgstr "Немає непідписаної теки — нічого викон #: ../fdroidserver/common.py msgid "Not a valid size definition: \"{}\"" -msgstr "" +msgstr "Недійсне визначення розміру: \"{}\"" #: ../fdroidserver/signindex.py msgid "Nothing to do" @@ -1307,9 +1305,8 @@ msgid "Only process apps with auto-updates" msgstr "Обробляти застосунки лише за допомогою автоматичних оновлень" #: ../fdroidserver/lint.py -#, fuzzy msgid "OpenCollective donation methods belong in the OpenCollective: field" -msgstr "Методи допомоги Flattr належать до прапора FlattrID" +msgstr "Належний до OpenCollective метод допомоги OpenCollective: не вдалося" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1322,13 +1319,13 @@ msgstr "Виведіть JSON-звіт у назві файлу APK." #: ../fdroidserver/scanner.py msgid "Output JSON to stdout." -msgstr "" +msgstr "Вивід JSON на stdout." #: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py #: ../fdroidserver/update.py ../fdroidserver/signindex.py #: ../fdroidserver/checkupdates.py msgid "Outputting JSON" -msgstr "" +msgstr "Вивід JSON" #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1346,7 +1343,7 @@ msgstr "Перезапис порожнього versionName у {apkfilename} з #: ../fdroidserver/import.py #, python-brace-format msgid "Package \"{appid}\" already exists" -msgstr "" +msgstr "Пакунок \"{appid}\" вже існує" #: ../fdroidserver/common.py #, python-brace-format @@ -1545,7 +1542,7 @@ msgstr "Сканувати лише останню версію кожного #: ../fdroidserver/build.py msgid "Scan the resulting APK(s) for known non-free classes." -msgstr "" +msgstr "Перевірити отриманий файл APK на наявність відомих невільних класів." #: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" @@ -1574,7 +1571,7 @@ msgstr "Встановіть годинник на цей час, викорис #: ../fdroidserver/nightly.py msgid "Set maximum releases in repo before older ones are archived" -msgstr "" +msgstr "Встановити найбільшу кількість випусків у сховищі перед архівуванням старих" #: ../fdroidserver/build.py #, python-brace-format @@ -1664,7 +1661,7 @@ msgid "Striping mystery signature from {apkfilename}" msgstr "Видалення невідомого підпису для {apkfilename}" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Stripping mystery signature from {apkfilename}" msgstr "Видалення невідомого підпису для {apkfilename}" @@ -1728,7 +1725,7 @@ msgstr "Відбулося зіткнення keyalias ключів - припи #: ../fdroidserver/common.py msgid "These are the apps that have been archived from the main repo." -msgstr "" +msgstr "Це застосунки, заархівовані з основного сховища." #: ../fdroidserver/import.py #, python-format @@ -1745,7 +1742,7 @@ msgstr "Режим перевірки оновлень встановлено, #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" -msgstr "" +msgstr "URL-адреса має починатися з https:// або http://" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" @@ -1761,13 +1758,12 @@ msgid "URL {url} in Description: {error}" msgstr "URL {url} в описі: {error}" #: ../fdroidserver/lint.py -#, fuzzy msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" -msgstr "Недійсна мітка ліцензії \"%s\"! Використовуйте лише мітки з https://spdx.org/license-list" +msgstr "Недійсна мітка ліцензії \"{}\"! Використовуйте лише затверджені FSF чи OSI мітки з https://spdx.org/license-list" #: ../fdroidserver/lint.py msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" -msgstr "" +msgstr "Неочікувана мітка ліцензії \"{}\"! Використовуйте лише мітки ліцензій, налаштовані у файлі налаштувань" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1795,9 +1791,9 @@ msgid "Unknown metadata format: {path}" msgstr "Створення скелетів файлів метаданих: {path}" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path} (use: *.yml)" -msgstr "Створення скелетів файлів метаданих: {path}" +msgstr "Невідомий формат метаданих: {path} (використовуйте: *.yml)" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1878,14 +1874,14 @@ msgid "Unused file at %s" msgstr "Невикористаний файл у %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scandelete path: %s" -msgstr "Невикористаний файл у %s" +msgstr "Невикористаний шлях scandelete: %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scanignore path: %s" -msgstr "Невикористаний файл у %s" +msgstr "Невикористаний шлях scanignore: %s" #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" @@ -1925,12 +1921,12 @@ msgstr "UpdateCheckData не є дійсною URL-адресою: {url}" #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" -msgstr "" +msgstr "Завантаження {apkfilename} на androidobservatory.org" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Uploading {apkfilename} to virustotal" -msgstr "Читання {apkfilename} з кешу" +msgstr "Завантаження {apkfilename} до virustotal" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1969,11 +1965,11 @@ msgstr "Використання \"{path}\" для налаштування s3cm #: ../fdroidserver/common.py msgid "Using APK Signature v2" -msgstr "" +msgstr "Використання підпису APK v2" #: ../fdroidserver/common.py msgid "Using APK Signature v3" -msgstr "" +msgstr "Використання підпису APK v3" #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" @@ -2013,7 +2009,7 @@ msgstr "Перевірка підпису індексу:" #: ../fdroidserver/server.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." -msgstr "" +msgstr "Ключ API VirusTotal не може завантажити файли, розмір яких понад 32 МБ, використовуйте {url} для завантаження {path}." #: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" @@ -2025,7 +2021,7 @@ msgstr "Коли налаштовано для підписаних індекс #: ../fdroidserver/lint.py msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." -msgstr "" +msgstr "Під час перевірки всього сховища, yamllint типово вимкнено. Цей параметр змушує нехтувати yamllint." msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Distiguished Name' використовується при створенні ключів" @@ -2040,7 +2036,7 @@ msgstr "За допомогою ANDROID_HOME можна встановити ш #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "" +msgstr "ZIP-архів" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2066,7 +2062,7 @@ msgstr "неоднозначний параметр: %s (%s?)" #: ../fdroidserver/common.py msgid "apksigner not found, it's required for signing!" -msgstr "" +msgstr "apksigner не знайдено, це потрібно для підписання!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2090,7 +2086,6 @@ msgid "argument \"-\" with mode %r" msgstr "аргумент \"-\" в режимі %r" #: ../fdroidserver/nightly.py -#, fuzzy msgid "attempting bare SSH connection to test deploy key:" msgstr "спроба відкритого з'єднання ssh для перевірки ключа розгортання:" @@ -2100,7 +2095,7 @@ msgstr "спроба відкритого з'єднання ssh для пере #: ../fdroidserver/common.py msgid "can not parse scrlib spec (not a string): '{}'" -msgstr "" +msgstr "не вдається проаналізувати специфікацію scrlib (не рядок): '{}'" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2109,9 +2104,9 @@ msgid "can't open '%s': %s" msgstr "не може відкрити '%s': %s" #: ../fdroidserver/build.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "cannot find required srclibs: \"{path}\"" -msgstr "Не вдається знайти appid за шляхом {path}!" +msgstr "не вдалося знайти потрібні srclibs: \"{path}\"" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2139,7 +2134,7 @@ msgstr "команда виконати, 'init' або 'update'" #: ../fdroidserver/__main__.py msgid "commands from plugin modules:" -msgstr "" +msgstr "команди з модулів плагіна:" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2163,15 +2158,15 @@ msgstr "копіювання {apkfilename} у {path}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "could not parse '{path}'" -msgstr "" +msgstr "не вдалося проаналізувати '{path}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (no ref specified): '{}'" -msgstr "" +msgstr "не вдалося проаналізувати специфікацію srclib (посилання не вказано): '{}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (too many '@' signs): '{}'" -msgstr "" +msgstr "не вдалося проаналізувати специфікацію srclib (занадто багато знаків '@'): '{}'" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2191,7 +2186,7 @@ msgstr "розгорнуто журнали збірки до '{path}'" #: ../fdroidserver/common.py #, python-brace-format msgid "deployed process log {path} to {dest}" -msgstr "" +msgstr "розгорнуто журнал процесів {path} до {dest}" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2201,7 +2196,7 @@ msgstr "dest= потрібен для таких варіантів, як %r" #: ../fdroidserver/scanner.py msgid "executable binary, possibly code" -msgstr "" +msgstr "виконуваний двійковий файл, можливо, код" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2259,7 +2254,7 @@ msgstr "Не вдалося клонувати git svn" #: ../fdroidserver/scanner.py msgid "gzip file archive" -msgstr "" +msgstr "gzip-архів" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2429,7 +2424,7 @@ msgstr "позиційні аргументи" #: ../fdroidserver/common.py #, python-brace-format msgid "process log deploy {path} to {dest} failed!" -msgstr "" +msgstr "не вдалося розгорнути журнал процесів {path} до {dest}!" #: ../fdroidserver/signatures.py #, python-brace-format @@ -2443,7 +2438,7 @@ msgstr "відмовитись від завантаження через нез #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." -msgstr "" +msgstr "ruamel.yaml не встановлено, не вдається записати метадані." #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -2452,7 +2447,7 @@ msgstr "s3cmd синхронізувати індекси з {path} до {url} #: ../fdroidserver/scanner.py msgid "shared library" -msgstr "" +msgstr "спільна бібліотека" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2488,7 +2483,7 @@ msgstr "srclibs відсутнє ім’я та/чи @" #: ../fdroidserver/scanner.py msgid "static library" -msgstr "" +msgstr "статична бібліотека" #: ../fdroidserver/common.py #, python-brace-format @@ -2540,7 +2535,7 @@ msgstr "Apache libcloud: синхронізація з {url}" #: ../fdroidserver/server.py msgid "virustotal.com is rate limiting, waiting to retry..." -msgstr "" +msgstr "virustotal.com обмежує швидкість, очікування повторної спроби..." #: ../fdroidserver/publish.py #, python-brace-format @@ -2609,7 +2604,7 @@ msgstr "{appid}: {field} повинно бути '{type}', а не '{fieldtype}' #: ../fdroidserver/metadata.py #, python-brace-format msgid "{build_flag} must be an integer, found: {value}" -msgstr "" +msgstr "{build_flag} має бути цілим числом, знайдено: {value}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2619,7 +2614,7 @@ msgstr "{field} не припинено в {name}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{file} is blank or corrupt!" -msgstr "" +msgstr "{file} порожній або пошкоджений!" #: ../fdroidserver/update.py #, python-brace-format @@ -2629,7 +2624,7 @@ msgstr "{name} \"{path}\" не існує! Виправте його в config.p #: ../fdroidserver/import.py #, python-brace-format msgid "{path} already exists, ignoring import results!" -msgstr "" +msgstr "{path} вже існує, нехтування результатами імпорту!" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2649,7 +2644,7 @@ msgstr "{path} не має розміру!" #: ../fdroidserver/server.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" -msgstr "" +msgstr "{path} понад 200 МБ, вивантажити власноруч: {url}" #: ../fdroidserver/mirror.py #, python-brace-format @@ -2657,9 +2652,9 @@ msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} не закінчується на \"fdroid\", перевірте шлях URL!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{url} does not start with \"http\"!" -msgstr "{url} не закінчується на \"fdroid\", перевірте шлях URL!" +msgstr "{url} не починається на \"http\"!" #: ../fdroidserver/build.py msgid "{} build failed" From 534cb2106dd63525ec24871a4f2cfce25ff5f61c Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 17 Oct 2020 07:19:31 +0200 Subject: [PATCH 0563/2775] Translated using Weblate: Chinese (Simplified) (zh_Hans) by Eric Currently translated at 33.6% (190 of 565 strings) Co-authored-by: Eric Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hans/ Translation: F-Droid/F-Droid Server --- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 41 ++++++++++------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index 1da742bd..8b0e9a62 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-07-16 09:41+0000\n" +"PO-Revision-Date: 2020-10-02 19:15+0000\n" "Last-Translator: Eric \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/common.py msgid "" @@ -39,13 +39,12 @@ msgstr "" "SSH 公钥被用来作为布署密钥:" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" msgstr "" "\n" -"SSH 公钥被用来作为布署密钥:" +"SSH 公钥将被用作布署密钥:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -62,7 +61,7 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" 没有匹配的元数据文件!" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." msgstr "'{apkfilename}'已安装在{dev}上。" @@ -82,9 +81,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\"存在,但未安装 s3cmd!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" 不是可接受的格式, 需转换成 : {formats}" +msgstr "\"{path}\"不是可接受的文件格式 (使用:metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -276,9 +275,8 @@ msgid "Android APK file" msgstr "" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "未找到 Android SDK!" +msgstr "安卓DEX代码" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -471,14 +469,12 @@ msgid "Could not find '{command}' on your system" msgstr "" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version code" -msgstr "仅编译每个包的最新版本" +msgstr "找不到最新版本代码" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version name" -msgstr "仅编译每个包的最新版本" +msgstr "找不到最新的版本名" #: ../fdroidserver/update.py #, python-brace-format @@ -495,9 +491,8 @@ msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" #: ../fdroidserver/import.py -#, fuzzy msgid "Couldn't find Application ID" -msgstr "未能匹配应用程序" +msgstr "找不到应用程序ID" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -1063,9 +1058,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "读取全部元数据文件并退出" +msgstr "无效的scrlib元数据:'{file}'不存在" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1783,9 +1778,9 @@ msgid "Unknown metadata format: {path}" msgstr "未知元数据格式:{path}" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path} (use: *.yml)" -msgstr "未知元数据格式:{path}" +msgstr "未知元数据格式:{path} (使用:*.yml)" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1980,7 +1975,7 @@ msgstr "" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" -msgstr "" +msgstr "正使用 s3cmd 与 {url} 同步" #: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" @@ -1988,7 +1983,7 @@ msgstr "有效的命令为:" #: ../fdroidserver/verify.py msgid "Verify against locally cached copy rather than redownloading." -msgstr "" +msgstr "和本地缓存的副本进行验证,而不是重新下载。" #: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" @@ -1996,7 +1991,7 @@ msgstr "验证已下载包的完整性" #: ../fdroidserver/index.py msgid "Verifying index signature:" -msgstr "" +msgstr "验证目录签名中:" #: ../fdroidserver/server.py #, python-brace-format @@ -2402,7 +2397,7 @@ msgstr "可用参数" #: ../fdroidserver/nightly.py #, python-brace-format msgid "overwriting existing {path}" -msgstr "" +msgstr "正在覆盖现有{path}" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py From f10bda4e6e3390b8c10fab42e37ff09dd69f327f Mon Sep 17 00:00:00 2001 From: Jo Date: Sat, 17 Oct 2020 07:19:32 +0200 Subject: [PATCH 0564/2775] Translated using Weblate: Spanish (es) by Jo Currently translated at 56.6% (320 of 565 strings) Co-authored-by: Jo Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es/ Translation: F-Droid/F-Droid Server --- locale/es/LC_MESSAGES/fdroidserver.po | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index 7c0787fb..c85fe5b5 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -2,22 +2,24 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Maximiliano Castañón , 2020. +# Jo , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-06-28 04:34+0000\n" -"Last-Translator: Maximiliano Castañón \n" +"PO-Revision-Date: 2020-10-02 19:15+0000\n" +"Last-Translator: Jo \n" "Language-Team: Spanish \n" "Language: es\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 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/common.py +#, fuzzy msgid "" "\n" " This is a repository of apps to be used with FDroid. Applications in this\n" @@ -26,6 +28,12 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Este es un repositorio de aplicaciones para usar con FDroid. Las aplicaciones en este\n" +" repositorio son binarios oficiales construidos por los desarrolladores originales de la \n" +" aplicación, o son binarios creados a partir de la fuente por f-droid.org utilizando las\n" +" herramientas en https://gitlab.com/fdroid.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -91,7 +99,7 @@ msgstr "\"{path}\" no es un formato reconocido, convertir a: {formats}" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" no es una URL válida!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py From 9285f072c0658972fa0b5d1a583c26844a6d2fba Mon Sep 17 00:00:00 2001 From: Wellington Terumi Uemura Date: Sat, 17 Oct 2020 07:19:32 +0200 Subject: [PATCH 0565/2775] Translated using Weblate: Portuguese (Brazil) (pt_BR) by Wellington Terumi Uemura Currently translated at 100.0% (565 of 565 strings) Co-authored-by: Wellington Terumi Uemura Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translation: F-Droid/F-Droid Server --- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 96 ++++++++++++------------ 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index efb7cd81..829f7d47 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-10-01 20:58+0000\n" -"Last-Translator: Rafael Fontenelle \n" +"PO-Revision-Date: 2020-10-02 19:15+0000\n" +"Last-Translator: Wellington Terumi Uemura \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -1543,7 +1543,7 @@ msgstr "Escanear apenas a versão mais recente de cada pacote" #: ../fdroidserver/build.py msgid "Scan the resulting APK(s) for known non-free classes." -msgstr "" +msgstr "Verifique os APKs resultantes na busca das classes não gratuitas já conhecidas." #: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" @@ -1571,7 +1571,7 @@ msgstr "Ajuste o relógio para esse horário usando:" #: ../fdroidserver/nightly.py msgid "Set maximum releases in repo before older ones are archived" -msgstr "" +msgstr "Defina as liberações máximas no repo antes que as mais antigas sejam arquivadas" #: ../fdroidserver/build.py #, python-brace-format @@ -1661,9 +1661,9 @@ msgid "Striping mystery signature from {apkfilename}" msgstr "Assinatura misteriosa de striping de {apkfilename}" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Stripping mystery signature from {apkfilename}" -msgstr "Assinatura misteriosa de striping de {apkfilename}" +msgstr "Descarnar a assinatura misteriosa a partir do {apkfilename}" #: ../fdroidserver/lint.py #, python-format @@ -1725,7 +1725,7 @@ msgstr "Há uma colisão do keyalias - publicação parada" #: ../fdroidserver/common.py msgid "These are the apps that have been archived from the main repo." -msgstr "" +msgstr "Estas são as aplicações que foram arquivadas a partir do repositório principal." #: ../fdroidserver/import.py #, python-format @@ -1742,7 +1742,7 @@ msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" -msgstr "" +msgstr "A URL deve começar com https:// ou http://" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" @@ -1758,13 +1758,12 @@ msgid "URL {url} in Description: {error}" msgstr "Há o URL {url} na descrição: {error}" #: ../fdroidserver/lint.py -#, fuzzy msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" -msgstr "Etiqueta de licença inválida \"%s\"! Use apenas tags de https://spdx.org/license-list" +msgstr "A etiqueta da licença foi inesperada \"{}\"! Use apenas etiquetas FSF ou OSI a partir do https://spdx.org/license-list" #: ../fdroidserver/lint.py msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" -msgstr "" +msgstr "A etiqueta da licença foi inesperada \"{}\"! Use apenas as etiquetas configuradas no seu arquivo de configuração" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1792,9 +1791,9 @@ msgid "Unknown metadata format: {path}" msgstr "Formato de metadados desconhecido: {path}" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path} (use: *.yml)" -msgstr "Formato de metadados desconhecido: {path}" +msgstr "O formato dos metadados é desconhecido: {path} (use: *.yml)" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1875,14 +1874,14 @@ msgid "Unused file at %s" msgstr "Arquivo não utilizado em %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scandelete path: %s" -msgstr "Arquivo não utilizado em %s" +msgstr "Caminho scandelete não usado: %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scanignore path: %s" -msgstr "Arquivo não utilizado em %s" +msgstr "Caminho scanignore não usado: %s" #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" @@ -1922,12 +1921,12 @@ msgstr "UpdateCheckData não é uma URL válida: {url}" #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" -msgstr "" +msgstr "Enviando o {apkfilename} para o androidobservatory.org" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Uploading {apkfilename} to virustotal" -msgstr "Lendo {apkfilename} do cache" +msgstr "Enviando o {apkfilename} para o virustotal" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1966,11 +1965,11 @@ msgstr "Usando \"{path}\" para configurar s3cmd." #: ../fdroidserver/common.py msgid "Using APK Signature v2" -msgstr "" +msgstr "Usando a Assinatura APK v2" #: ../fdroidserver/common.py msgid "Using APK Signature v3" -msgstr "" +msgstr "Usando a Assinatura APK v3" #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" @@ -2010,7 +2009,7 @@ msgstr "Verificar o índice de assinatura:" #: ../fdroidserver/server.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." -msgstr "" +msgstr "A chave API do VirusTotal não pode carregar arquivos maiores que 32MB, utilize {url} para enviar para {path}." #: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" @@ -2022,7 +2021,7 @@ msgstr "Quando configurado para índices assinados, crie apenas índices não as #: ../fdroidserver/lint.py msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." -msgstr "" +msgstr "Ao cotar todo o repositório, o yamllint é desativado por padrão. Independente de qualquer coisa esta opção impõem o uso do yamllint." msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Distiguished Name' usado ao gerar as chaves" @@ -2037,7 +2036,7 @@ msgstr "Você pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou s #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "" +msgstr "Arquivo ZIP" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2063,7 +2062,7 @@ msgstr "opção ambígua: %s (%s?)" #: ../fdroidserver/common.py msgid "apksigner not found, it's required for signing!" -msgstr "" +msgstr "o apksigner não foi encontrado, ele é necessário para assinar!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2087,9 +2086,8 @@ msgid "argument \"-\" with mode %r" msgstr "argumento \"-\" com o modo %r" #: ../fdroidserver/nightly.py -#, fuzzy msgid "attempting bare SSH connection to test deploy key:" -msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" +msgstr "tentando uma conexão SSH vazia para testar a chave de implantação:" #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" @@ -2097,7 +2095,7 @@ msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" #: ../fdroidserver/common.py msgid "can not parse scrlib spec (not a string): '{}'" -msgstr "" +msgstr "não é possível analisar a especificação scrlib (não uma string): '{}'" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2106,9 +2104,9 @@ msgid "can't open '%s': %s" msgstr "não dá pra abrir '%s': %s" #: ../fdroidserver/build.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "cannot find required srclibs: \"{path}\"" -msgstr "Não é possível encontrar um appid para {path} 1!" +msgstr "não é possível encontrar os srclibs necessários: \"{path}\"" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2136,7 +2134,7 @@ msgstr "comando para executar, seja 'init' ou 'update'" #: ../fdroidserver/__main__.py msgid "commands from plugin modules:" -msgstr "" +msgstr "comandos a partir dos módulos de plugin:" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2159,15 +2157,15 @@ msgstr "copiando {apkfilename} para {path}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "could not parse '{path}'" -msgstr "" +msgstr "não foi possível analisar '{path}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (no ref specified): '{}'" -msgstr "" +msgstr "não foi possível analisar a especificação srclib (referência sem especificação): '{}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (too many '@' signs): '{}'" -msgstr "" +msgstr "não foi possível analisar a especificação srclib (excesso de sinais '@'): '{}'" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2187,7 +2185,7 @@ msgstr "logs de compilação implantados para '{path}'" #: ../fdroidserver/common.py #, python-brace-format msgid "deployed process log {path} to {dest}" -msgstr "" +msgstr "registro de processo implantado {path} para {dest}" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2197,7 +2195,7 @@ msgstr "dest = é necessário para opções como %r" #: ../fdroidserver/scanner.py msgid "executable binary, possibly code" -msgstr "" +msgstr "binário executável, possivelmente código" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2254,7 +2252,7 @@ msgstr "git svn clone falhou" #: ../fdroidserver/scanner.py msgid "gzip file archive" -msgstr "" +msgstr "arquivo gzip" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2424,7 +2422,7 @@ msgstr "argumentos posicionais" #: ../fdroidserver/common.py #, python-brace-format msgid "process log deploy {path} to {dest} failed!" -msgstr "" +msgstr "houve uma falha no registro de processo implantação {path} para {dest}!" #: ../fdroidserver/signatures.py #, python-brace-format @@ -2438,7 +2436,7 @@ msgstr "Recuse o download insegura via conexão http (use https ou especifique - #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." -msgstr "" +msgstr "o ruamel.yaml não está instalado, não é possível escrever os metadados." #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -2447,7 +2445,7 @@ msgstr "s3cmd sincroniza índices {path} para {url} e exclui" #: ../fdroidserver/scanner.py msgid "shared library" -msgstr "" +msgstr "biblioteca compartilhada" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2483,7 +2481,7 @@ msgstr "Nome 'srclibs' ausente e/ou '@'" #: ../fdroidserver/scanner.py msgid "static library" -msgstr "" +msgstr "biblioteca estática" #: ../fdroidserver/common.py #, python-brace-format @@ -2535,7 +2533,7 @@ msgstr "usando o Apache libcloud para sincronizar com {url}" #: ../fdroidserver/server.py msgid "virustotal.com is rate limiting, waiting to retry..." -msgstr "" +msgstr "o virustotal.com está limitando a taxa, esperando para tentar novamente ..." #: ../fdroidserver/publish.py #, python-brace-format @@ -2603,7 +2601,7 @@ msgstr "O {appid}: {field} deve ser um '{type}', porém é um '{fieldtype}'!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{build_flag} must be an integer, found: {value}" -msgstr "" +msgstr "{build_flag} deve ser um número inteiro, encontrado: {value}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2613,7 +2611,7 @@ msgstr "{field} não foi terminado em {name}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{file} is blank or corrupt!" -msgstr "" +msgstr "o {file} está vazio ou está corrompido!" #: ../fdroidserver/update.py #, python-brace-format @@ -2623,7 +2621,7 @@ msgstr "{name} \"{path}\" não existe! Corrija-o no config.py." #: ../fdroidserver/import.py #, python-brace-format msgid "{path} already exists, ignoring import results!" -msgstr "" +msgstr "o {path} já existe, ignorando os resultados de importação!" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2643,7 +2641,7 @@ msgstr "{path} tem um tamanho de zero!" #: ../fdroidserver/server.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" -msgstr "" +msgstr "o {path} tem mais de 200MB, upload manual: {url}" #: ../fdroidserver/mirror.py #, python-brace-format @@ -2651,9 +2649,9 @@ msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{url} does not start with \"http\"!" -msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" +msgstr "a {url} não começa com \"http\"!" #: ../fdroidserver/build.py msgid "{} build failed" From 7168d985fd48033b46263fcbf3c3a6cbd4075ac0 Mon Sep 17 00:00:00 2001 From: ssantos Date: Sat, 17 Oct 2020 07:19:33 +0200 Subject: [PATCH 0566/2775] Translated using Weblate: Portuguese (pt) by ssantos Currently translated at 100.0% (565 of 565 strings) Translated using Weblate: Portuguese (Portugal) (pt_PT) by ssantos Currently translated at 100.0% (565 of 565 strings) Translated using Weblate: Portuguese (Brazil) (pt_BR) by ssantos Currently translated at 100.0% (565 of 565 strings) Added translation using Weblate: Portuguese (pt) by ssantos Translated using Weblate: Portuguese (Portugal) (pt_PT) by ssantos Currently translated at 89.2% (504 of 565 strings) Co-authored-by: ssantos Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_PT/ Translation: F-Droid/F-Droid Server --- locale/pt/LC_MESSAGES/fdroidserver.po | 2662 ++++++++++++++++++++++ locale/pt_BR/LC_MESSAGES/fdroidserver.po | 7 +- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 227 +- 3 files changed, 2777 insertions(+), 119 deletions(-) create mode 100644 locale/pt/LC_MESSAGES/fdroidserver.po diff --git a/locale/pt/LC_MESSAGES/fdroidserver.po b/locale/pt/LC_MESSAGES/fdroidserver.po new file mode 100644 index 00000000..0e9fc895 --- /dev/null +++ b/locale/pt/LC_MESSAGES/fdroidserver.po @@ -0,0 +1,2662 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# ssantos , 2020. +msgid "" +msgstr "" +"Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" +"Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"Last-Translator: ssantos \n" +"Language-Team: Portuguese \n" +"Language: pt\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 4.3-dev\n" + +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" +"\n" +" Este é um repositório de apps a serem usados com o FDroid.\n" +" Aplicações neste repositório são binários oficiais compilados pelos\n" +" programadores da aplicação original ou são binários compilados da\n" +" fonte por f-droid.org a usar as ferramentas em https://gitlab.com/fdroid.\n" +" " + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH Public Key to be used as Deploy Key:" +msgstr "" +"\n" +"Chave pública SSH para ser usada como chave de implantar:" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" +"\n" +"Chave pública SSH a ser usada como chave de implantação:" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "" +"\n" +"{path} encoded for the DEBUG_KEYSTORE secret variable:" +msgstr "" +"\n" +"{path} codificado para a variável secreta DEBUG_KEYSTORE:" + +#: ../fdroidserver/lint.py +#, python-format +msgid "\"%s/\" has no matching metadata file!" +msgstr "\"%s/\" não tem ficheiro de metadados correspondente!" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "'{apkfilename}' já está instalado no {dev}." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains outdated {name} ({version})" +msgstr "\"{path}\" contém {name} ({version}) desatualizado" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains recent {name} ({version})" +msgstr "\"{path}\" contém {name} ({version}) recente" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "\"{path}\" exists but s3cmd is not installed!" +msgstr "\"{path}\" existe, mas s3cmd não está instalado!" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" não é um formato de ficheiro aceito (use: metadata/*.yml)" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "\"{path}\" is not an accepted format, convert to: {formats}" +msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "\"{url}\" não é uma URL válida!" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%(option)s option requires %(number)d argument" +msgid_plural "%(option)s option requires %(number)d arguments" +msgstr[0] "A opção %(option)s requer o argumento %(number)d" +msgstr[1] "A opção %(option)s requer os argumentos %(number)d" + +#: ../fdroidserver/mirror.py +#, python-format +msgid "%(prog)s [options] url" +msgstr "%(prog)s [opções] url" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%(prog)s: error: %(message)s\n" +msgstr "%(prog)s: erro: %(message)s\n" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "%d problems found" +msgstr "%d problemas encontrados" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "%prog [options]" +msgstr "%prog [opções]" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%r is not callable" +msgstr "%r não pode ser invocado" + +#: ../fdroidserver/lint.py +#, python-format +msgid "%s is not an accepted build field" +msgstr "%s não é um campo criado aceito" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%s option does not take a value" +msgstr "opção %s não leva um valor" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keypass' not found in config.py!" +msgstr "'keypass' não foi encontrada em config.py!" + +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "\"keystore\" é NONE e \"smartcardoptions\" está vazio!" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystore' not found in config.py!" +msgstr "'keystore' não encontrada em config.py!" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystorepass' not found in config.py!" +msgstr "'keystorepass' não encontrada em config.py!" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'repo_keyalias' not found in config.py!" +msgstr "'repo_keyalias' não encontrada em config.py!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "'required' is an invalid argument for positionals" +msgstr "'required' é um argumento inválido para posicionadores" + +#: ../fdroidserver/common.py +msgid "'sdk_path' not set in 'config.py'!" +msgstr "'sdk_path' não definido em 'config.py'!" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" +msgstr "'{aapt}' é muito antigo, fdroid requer build-tools-23.0.0 ou mais recente!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" +msgstr "'{aapt}' é muito antigo, fdroid requer build-tools-{version} ou mais recente!" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "'{apkfilename}' is already installed on {dev}." +msgstr "'{apkfilename}' já está instalado no {dev}." + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" +msgstr "O '{field}' em {linedesc} é obsoleto, veja os documentos para os campos actuais:" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" +msgstr "'{field}' será em ordem aleatória! Use () ou [] se a ordem for importante!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{path}' failed to execute!" +msgstr "'{path}' falhou ao executar!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" +msgstr "'{value}' não é um {field} válido em {appid}. Modelo regex: {pattern}" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "...checkupdate failed for {appid} : {error}" +msgstr "...checkupdate falhou para {appid} : {error}" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid ".__call__() not defined" +msgstr ".__call__() não definida" + +#: ../fdroidserver/metadata.py +msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." +msgstr ".fdroid.txt não é suportado! Converter para .fdroid.yml ou .fdroid.json." + +#: ../fdroidserver/lint.py +msgid "/issues is missing" +msgstr "está faltando o /issues" + +#: ../fdroidserver/mirror.py +msgid "A URL is required as an argument!" +msgstr "Uma URL é necessária como um argumento!" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Add PGP signatures using GnuPG for packages in repo" +msgstr "Adicione assinaturas PGP usando GnuPG para os pacotes no repositório" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Add a new application from its source code" +msgstr "Adicionar nova aplicação através do código fonte" + +#: ../fdroidserver/update.py +msgid "Add a repo signing key to an unsigned repo" +msgstr "Adicionar uma chave de assinatura para um repositório não assinado" + +#: ../fdroidserver/update.py +msgid "Add skeleton metadata files for APKs that are missing them" +msgstr "Adicionar ficheiros de metadados de esqueleto para APKs que estão faltando-lhes" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Adding new repo for only {name}" +msgstr "Adicionando novo repositório para apenas {name}" + +#: ../fdroidserver/init.py +msgid "Alias of the repo signing key in the keystore" +msgstr "Alias (apelido) da chave de assinatura do repositório na keystore" + +#: ../fdroidserver/import.py +msgid "Allows a different revision (or git branch) to be specified for the initial import" +msgstr "Permite que uma revisão diferente (ou árvore do git) seja especificada para a importação inicial" + +#: ../fdroidserver/mirror.py +msgid "Also mirror the full archive section" +msgstr "Também espelhar o ficheiro completo da secção" + +#: ../fdroidserver/lint.py +msgid "Also warn about formatting issues, like rewritemeta -l" +msgstr "Também avisar sobre problemas de formatação, como rewritemeta -l" + +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "Biblioteca AAR do Android" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "Ficheiro APK do Android" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "Código DEX do Android" + +#: ../fdroidserver/common.py ../fdroidserver/build.py +#, python-brace-format +msgid "Android SDK '{path}' does not have '{dirname}' installed!" +msgstr "O SDK Android '{path}' não tem '{dirname}' instalado!" + +#: ../fdroidserver/common.py +msgid "Android SDK not found!" +msgstr "SDK do Android não foi encontrado!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' does not exist!" +msgstr "O caminho do SDK Android '{path}' não existe!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' is not a directory!" +msgstr "O caminho do SDK Android '{path}' não é um diretório!" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android build-tools path '{path}' does not exist!" +msgstr "Caminho de build-tools do Android '{path}' não existe!" + +#: ../fdroidserver/update.py +msgid "AndroidManifest.xml has no date" +msgstr "AndroidManifest.xml não tem data" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "App is in '{repo}' but has a link to {url}" +msgstr "A App está em '{repo}' mas tem uma hiperligação para {url}" + +#: ../fdroidserver/lint.py +msgid "Appending .git is not necessary" +msgstr "Acrescentar .git não é necessário" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Archiving {apkfilename} with invalid signature!" +msgstr "Arquivamento {apkfilename} com assinatura inválida!" + +#: ../fdroidserver/mirror.py +msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" +msgstr "URL base para espelhar, pode incluir a chave de assinatura de índice usando a string de consulta:? Fingerprint =" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in build '{versionName}'" +msgstr "Filial '{branch} 1' usada como commit no build '{versionName} 2'" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in srclib '{srclib}'" +msgstr "Ramificação '{branch}' usado como commit em srclib '{srclib}'" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "Ligação simbólica quebrada: {path}" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Build a package from source" +msgstr "Construir pacote através da fonte" + +#: ../fdroidserver/build.py +msgid "Build all applications available" +msgstr "Compilar todos as aplicações disponíveis" + +#: ../fdroidserver/lint.py +msgid "Build generated by `fdroid import` - remove disable line once ready" +msgstr "Compilação gerada por `fdroid import` - remove a linha de desativação quando estiver pronto" + +#: ../fdroidserver/checkupdates.py +msgid "Build metadata git repo has uncommited changes!" +msgstr "Construir metadados git repo não tem mudanças comprometidas!" + +#: ../fdroidserver/build.py +msgid "Build only the latest version of each package" +msgstr "Compilar apenas a última versão de cada pacote" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" +msgstr "A compilação deve ter versionName e versionCode separados por vírgula, e não \"{value} 1\", em {linedesc} 2" + +#: ../fdroidserver/init.py +#, python-format +msgid "Built repo based in \"%s\" with this config:" +msgstr "Repo construído baseado em \"%s\" com esta configuração:" + +#: ../fdroidserver/build.py +msgid "Can't build due to {} error while scanning" +msgid_plural "Can't build due to {} errors while scanning" +msgstr[0] "Não é possível construir devido a erro {} durante a digitalização" +msgstr[1] "Não é possível construir devido a erros {} durante a digitalização" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find a packageName for {path}!" +msgstr "Não é possível encontrar um packageName para {path} 1!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find an appid for {path}!" +msgstr "Não é possível encontrar um appid para {path} 1!" + +#: ../fdroidserver/vmtools.py +#, python-brace-format +msgid "Cannot read \"{path}\"!" +msgstr "Não é possível ler \"{path}\"!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot resolve app id {appid}" +msgstr "Não é possível resolver o ID da app {appid}" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "Não é possível reescrever \"{path}\"" + +#: ../fdroidserver/rewritemeta.py +msgid "Cannot use --list and --to at the same time" +msgstr "Não é possível usar --list e --to ao mesmo tempo" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" +msgstr "Não é possível escrever \"{path}\", não é um formato aceito, use: {formats}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Categories '%s' is not valid" +msgstr "As categorias '%s' não são válidas" + +#: ../fdroidserver/lint.py +msgid "Categories are not set" +msgstr "As categorias não são definidas" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Check for updates to applications" +msgstr "Verificação de actualizações das aplicações" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" +msgstr "Verificando o arquivamento para {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" + +#: ../fdroidserver/dscanner.py +msgid "Clean after all scans have finished" +msgstr "Limpar depois que todos os escaneamentos terminarem" + +#: ../fdroidserver/dscanner.py +msgid "Clean before the scans start and rebuild the container" +msgstr "Limpar antes do escanemento começar e recompilar o container" + +#: ../fdroidserver/dscanner.py +msgid "Clean up all containers and then exit" +msgstr "Limpar todos os containers e então sair" + +#: ../fdroidserver/update.py +msgid "Clean update - don't uses caches, reprocess all APKs" +msgstr "Atualização limpa - não usa cache, reprocessa todos os APKs" + +#: ../fdroidserver/import.py +msgid "Comma separated list of categories." +msgstr "Lista de categorias separadas por vírgula." + +#: ../fdroid ../fdroidserver/__main__.py +#, c-format, python-format +msgid "Command '%s' not recognised.\n" +msgstr "Comando '%s' não reconhecido.\n" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes" +msgstr "Enviar mudanças" + +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "Argumentos conflitantes: \"--verbose\" e \"--quiet\" não podem ser especificados ao mesmo tempo." + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not find '{command}' on your system" +msgstr "Não foi possível encontrar '{command}' no seu sistema" + +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "Não foi possível encontrar o código de versão mais recente" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "Não foi possível encontrar o nome da versão mais recente" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not find {path} to remove it" +msgstr "Não foi possível localizar {path} para removê-lo" + +#: ../fdroidserver/update.py +msgid "Could not open apk file for analysis" +msgstr "Não foi possível abrir ficheiro apk para análise" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "Não foi possível analisar o tamanho \"{size}\", tipo \"{type}\" incorreto" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "Não foi possível encontrar o ID da aplicação" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/import.py +msgid "Couldn't find latest version code" +msgstr "Não foi possível encontrar o código de versão mais recente" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/import.py +msgid "Couldn't find latest version name" +msgstr "Não foi possível encontrar o nome da versão mais recente" + +#: ../fdroidserver/import.py +msgid "Couldn't find package ID" +msgstr "Não foi possível encontrar o ID do pacote" + +#: ../fdroidserver/update.py +msgid "Cowardily refusing to overwrite existing signing key setup!" +msgstr "Cobardemente recusando substituir a configuração da chave de assinatura existente!" + +#: ../fdroidserver/update.py +msgid "Create a repo signing key in a keystore" +msgstr "Criar uma chave de assinatura do repositório numa keystore" + +#: ../fdroidserver/update.py +msgid "Create skeleton metadata files that are missing" +msgstr "Criação do esqueleto de metadados dos ficheiros que estão em falta" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Created new container \"{name}\"" +msgstr "Novo contentor criado: \"{name}\"" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating \"{path}\" for configuring s3cmd." +msgstr "Criando \"{path}\" para configurar s3cmd." + +#: ../fdroidserver/publish.py +msgid "Creating log directory" +msgstr "Criando o diretório de log" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating new S3 bucket: {url}" +msgstr "Criando novo bucket S3: {url}" + +#: ../fdroidserver/publish.py +msgid "Creating output directory" +msgstr "Criando diretório de output" + +#: ../fdroidserver/index.py +msgid "Creating signed index with this key (SHA256):" +msgstr "Criando índice assinado com esta chave (SHA256):" + +#: ../fdroidserver/import.py ../fdroidserver/verify.py +#: ../fdroidserver/publish.py +msgid "Creating temporary directory" +msgstr "Criando diretório temporário" + +#: ../fdroidserver/index.py +msgid "Creating unsigned index in preparation for signing" +msgstr "Criação de índice não assinado em preparação para assinatura" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" +msgstr "CurrentVersionCode {cv} é menor que a entrada mais antiga de build {versionCode}" + +#: ../fdroidserver/nightly.py +msgid "DEBUG_KEYSTORE is not set or the value is incomplete" +msgstr "DEBUG_KEYSTORE não está definido ou o valor está incompleto" + +#: ../fdroidserver/update.py +msgid "Delete APKs and/or OBBs without metadata from the repo" +msgstr "Eliminação de APK'S e/ou OBBs que não contêm metadados do repositório" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "Apagar ficheiro, o reporte é muito grande ({size} max {limit})" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "Apagar o histórico do git-mirror, o repo é muito grande ({size} max {limit})" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Deleting unknown file: {path}" +msgstr "Apagando o ficheiro desconhecido: {path}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description '%s' is just the app's summary" +msgstr "Descrição '%s' é apenas o resumo da app" + +#: ../fdroidserver/lint.py +msgid "Description has a duplicate line" +msgstr "A descrição tem uma linha duplicada" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description has a list (%s) but it isn't bulleted (*) nor numbered (#)" +msgstr "A descrição tem a lista (%s), mas não tem marcadores (*), nem é numerada (#)" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Description of length {length} is over the {limit} char limit" +msgstr "A descrição de comprimento {length} é sobre o limite de char {limit}" + +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "Não adicionar 'disable:' às entradas de compilação geradas" + +#: ../fdroidserver/nightly.py +msgid "Do not deploy the new files to the repo" +msgstr "Não implante os novos ficheiros no repositório" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Do not include \"{path}\" in URL!" +msgstr "Não incluir \"{path}\" no URL!" + +#: ../fdroidserver/init.py +msgid "Do not prompt for Android SDK path, just fail" +msgstr "Não solicitar o caminho do Android SDK, apenas falhe" + +#: ../fdroidserver/nightly.py +msgid "Do not remove the private keys generated from the keystore" +msgstr "Não remover as chaves privadas geradas do keystore" + +#: ../fdroidserver/build.py +msgid "Don't create a source tarball, useful when testing a build" +msgstr "Não criar um tarball da fonte; útil quando testando uma compilação" + +#: ../fdroidserver/stats.py +msgid "Don't do anything logs-related" +msgstr "Não fazer nada relacionado a registros de alterações" + +#: ../fdroidserver/build.py +msgid "Don't refresh the repository, useful when testing a build with no internet connection" +msgstr "Não atualizar o repositório; útil quando testando uma compilação sem conexão com a internet" + +#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/upload.py +msgid "Don't use rsync checksums" +msgstr "Não usar as somas de verificação (checksums) do rsync" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Download complete mirrors of small repos" +msgstr "Descarregar espelhos completos de repos pequenos" + +#: ../fdroidserver/stats.py +msgid "Download logs we don't have" +msgstr "Descarregar os registos que nós não temos" + +#: ../fdroidserver/common.py +msgid "Downloading the repository already failed once, not trying again." +msgstr "O descarregamento do repositório já falhou uma vez, não tento novamente." + +#: ../fdroidserver/verify.py +#, python-brace-format +msgid "Downloading {url} failed. {error}" +msgstr "Descarregar {url} falhou. {error}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Duplicate build recipe found for versionCode {versionCode} in {linedesc}" +msgstr "Receita de compilação duplicada encontrada para versionCode {versionCode} em {linedesc}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Duplicate link in '{field}': {url}" +msgstr "Ligação duplicada em '{field}': {url}" + +#: ../fdroid +msgid "Dynamically scan APKs post build" +msgstr "Analise dinâmica dos APKs após a compilação" + +#: ../fdroidserver/mirror.py +msgid "" +"ERROR: this command should never be used to mirror f-droid.org!\n" +"A full mirror of f-droid.org requires more than 200GB." +msgstr "" +"ERRO: este comando nunca deve ser usado para espelhar f-Droid.org!\n" +"Um espelho completo de f-Droid.org requer mais de 200GB." + +#: ../fdroidserver/nightly.py +msgid "ERROR: unsupported CI type, patches welcome!" +msgstr "ERRO: tipo de CI sem suporte, patches são bem-vindos!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Empty build flag at {linedesc}" +msgstr "Sinalizador de compilação vazio em {linedesc}" + +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "A codificação está definida como '{enc}' fdroid pode ter problemas de codificação. Por favor, configure-o para 'UTF-8' para obter melhores resultados." + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"Enter the path to the Android SDK (%s) here:\n" +"> " +msgstr "" +"Digite o caminho para o SDK do Android (%s) aqui:\n" +"> " + +#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/upload.py +#, python-format +msgid "Error while attempting to publish log: %s" +msgstr "Erro ao tentar publicar o log: %s" + +#: ../fdroidserver/import.py ../fdroidserver/common.py +msgid "Error while getting repo address" +msgstr "Erro ao obter o endereço do repo" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Extract signatures from APKs" +msgstr "Extrato de assinaturas de APKs" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "Falha ao copiar {path}: {error}" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Failed fetching signatures for '{apkfilename}': {error}" +msgstr "Falha ao buscar assinaturas para '{apkfilename}': {error}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed reading {path}: {error}" +msgstr "Falha de leitura {path}: {error}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed resizing {path}: {error}" +msgstr "Falha ao redimensionar {path}: {error}" + +#: ../fdroidserver/publish.py +msgid "Failed to align application" +msgstr "Falha ao alinhar a aplicação" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Failed to create S3 bucket: {url}" +msgstr "Falha ao criar o bucket S3: {url}" + +#: ../fdroidserver/common.py +msgid "Failed to get APK manifest information" +msgstr "Falha ao obter informações de manifesto do APK" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, deleting {path}" +msgstr "Falha ao obter informações do apk, apagando {path}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, skipping {path}" +msgstr "Falha ao obter informações do apk, ignorando {path}" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Failed to install '{apkfilename}' on {dev}: {error}" +msgstr "Falha ao instalar '{apkfilename}' em {dev}: {error}" + +#: ../fdroidserver/publish.py ../fdroidserver/common.py +msgid "Failed to sign application" +msgstr "Falha ao assinar a app" + +#: ../fdroidserver/common.py +msgid "Failed to zipalign application" +msgstr "Falha no zipaligning a app" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Fetched buildserverid from VM: {buildserverid}" +msgstr "Buildserverid obtido da VM: {buildserverid}" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" +msgstr "Assinaturas obtidas para '{apkfilename}'-> '{sigdir}'" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "O ficheiro desapareceu enquanto era processado: {path}" + +#: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py +#: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "Finished" +msgstr "Terminado" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID flag" +msgstr "Os métodos de doação do Flattr pertencem no sinalizador FlattrID" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "Os métodos de doação do Flattr pertencem no campo FlattrID:" + +#: ../fdroidserver/lint.py +msgid "Forbidden HTML tags" +msgstr "Tags HTML proibidos" + +#: ../fdroidserver/build.py +msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." +msgstr "Forçar a compilação de apps desativados e continuar independentemente de problemas de escaneamento. Apenas permitido no modo de teste." + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Force halting build after {0} sec timeout!" +msgstr "Forçar suspender a construção depois de esperar {0} segundos!" + +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "Forçar a análise de apps e construções desativados." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" +msgstr "\"{path}\" gráfico encontrado sem metadados para o app \"{name}\"!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "Ficheiro de financiamento ruim \"{path}\" encontrado para \"{name}\":" + +#: ../fdroidserver/common.py +msgid "Found invalid appids in arguments" +msgstr "appids inválidos encontrados em argumentos" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Found invalid versionCodes for some apps" +msgstr "versionCodes inválidos encontrados para algumas apps" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "Vários ficheiros de blocos de assinaturas JAR foram encontrados em {path}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Found multiple metadata files for {appid}" +msgstr "Encontrados vários ficheiros de metadados para {appid}" + +#: ../fdroidserver/index.py +msgid "Found multiple signing certificates for repository." +msgstr "Vários certificados de assinatura encontrados para o repositório." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found multiple signing certificates in {path}" +msgstr "Vários certificados de assinatura encontrados em {path}" + +#: ../fdroidserver/index.py +msgid "Found no signing certificates for repository." +msgstr "Nenhum certificado de assinatura para repositório encontrado." + +#: ../fdroidserver/lint.py +#, python-format +msgid "Found non-file at %s" +msgstr "Não-ficheiro encontrado em %s" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "{apkfilename} encontrado em {url}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Generated skeleton metadata for {appid}" +msgstr "Gerado esqueleto de metadados para {appid}" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git checkout of '%s' failed" +msgstr "Git checkout de '%s' falhou" + +#: ../fdroidserver/common.py +msgid "Git clean failed" +msgstr "Git clean falhou" + +#: ../fdroidserver/common.py +msgid "Git fetch failed" +msgstr "Git fetch falhou" + +#: ../fdroidserver/common.py +msgid "Git remote set-head failed" +msgstr "Git remote set-head falhou" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git remote set-head falhou: \"%s\"" + +#: ../fdroidserver/common.py +msgid "Git reset failed" +msgstr "Git reset falhou" + +#: ../fdroidserver/common.py +msgid "Git submodule sync failed" +msgstr "Git submodule sync falhou" + +#: ../fdroidserver/common.py +msgid "Git submodule update failed" +msgstr "Git submodule update falhou" + +#: ../fdroidserver/common.py +msgid "HTTPS must be used with Subversion URLs!" +msgstr "HTTPS deve ser usado nos URLs do Subversion!" + +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "Se um espelho git ficar muito grande, permite que o arquivo seja apagado" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "Se esse envio falhar, tente enviar manualmente para {url}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "A ignorar '{field}' em metadados '{metapath}' porque é depreciado." + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "A ignorar a entrada FUNDING.yml por mais de 2048: %s" + +#: ../fdroidserver/index.py +msgid "Ignoring package without metadata: " +msgstr "Ignorando o pacote sem metadados: " + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Ignoring stale cache data for {apkfilename}" +msgstr "Ignorando dados de cache obsoletos para {apkfilename}" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Ignoring {ext} file at '{path}'" +msgstr "Ignorando o ficheiro {ext} em '{path}'" + +#: ../fdroidserver/update.py +msgid "Include APKs that are signed with disabled algorithms like MD5" +msgstr "Incluir APKs assinados com algoritmos desabilitados como MD5" + +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "Incluir os ficheiros .asc da assinatura PGP no espelho" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "Incluir os registos de construção no espelho" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "Incluir os tarballs de fontes no espelho" + +#: ../fdroidserver/common.py +msgid "Initialising submodules" +msgstr "Inicializando submódulos" + +#: ../fdroidserver/install.py +msgid "Install all signed applications available" +msgstr "Instalar todas as aplicações assinadas disponíveis" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Install built packages on devices" +msgstr "Instalação dos pacotes compilados no aparelho" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "A instalar %s…" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s…" +msgstr "Instalando %s…" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "A instalar '{apkfilename}' em {dev}…" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}…" +msgstr "Instalando '{apkfilename}' em {dev}…" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Interact with the repo HTTP server" +msgstr "Interacção com o repositório do servidor HTTP" + +#: ../fdroidserver/update.py +msgid "Invalid APK" +msgstr "APK inválido" + +#: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid VercodeOperation: {field}" +msgstr "VercodeOperation inválido: {field}" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid boolean '%s'" +msgstr "Booleano inválido '%s'" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build flag at {line} in {linedesc}" +msgstr "Sinalizador de compilação inválido em {line} em {linedesc}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build format: {value} in {name}" +msgstr "Formato de compilação inválido: {value} em {name}" + +#: ../fdroidserver/lint.py +msgid "Invalid bulleted list" +msgstr "Lista com marcadores inválida" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" +msgstr "Etiqueta de licença \"%s\" inválida! Use apenas etiquetas de https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "Hiperligação inválida - use [http://foo.bar Título do link] ou [http://foo.bar]" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid metadata in %s:%d" +msgstr "Metadados inválidos em %s:%d" + +#: ../fdroidserver/metadata.py +msgid "Invalid metadata in: " +msgstr "Metadados inválidos em: " + +#: ../fdroidserver/common.py +#, python-format +msgid "Invalid name for published file: %s" +msgstr "Nome inválido para o ficheiro publicado: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid package name {0}" +msgstr "Nome do pacote inválido {0}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid redirect to non-HTTPS: {before} -> {after} " +msgstr "Redirecionamento inválido para não-HTTPS: {before} -> {after} " + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Metadados de scrlib inválidos: '{file}' não existe" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "Metadados de srclib inválidos: não foi possível analisar \"{file}\"" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "Metadados de srclib inválidos: chave \"{key}\" desconhecida no \"{file}\"" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" +msgstr "VersionCode inválido: \"{versionCode}\" não é um inteiro!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature failed to verify: {path}" +msgstr "A assinatura JAR falhou a verificação: {path}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature verified: {path}" +msgstr "Assinatura JAR verificada: {path}" + +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "Ficheiro Java JAR" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#: ../fdroidserver/mirror.py +msgid "Java JDK not found! Install in standard location or set java_paths!" +msgstr "O Java JDK não foi encontrado! Instalar no local predefinido ou definir java_paths!" + +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "Classe Java compilada" + +#: ../fdroidserver/signindex.py +msgid "Java jarsigner not found! Install in standard location or set java_paths!" +msgstr "Java jarsigner não encontrado! Instale no local predefinido ou define java_paths!" + +#: ../fdroidserver/lint.py +msgid "Javascript in HTML src attributes" +msgstr "JavaScript em atributos HTML src" + +#: ../fdroidserver/init.py +msgid "Keystore for signing key:\t" +msgstr "Armazenamento de chaves de assinatura:\t" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o modo de verificação de atualização é '{ucm}'" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Os métodos de doação de Liberapay pertencem no campo Liberapay:" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the LiberapayID flag" +msgstr "Os métodos de doação de Liberapay pertencem na bandeira de LiberapayID" + +#: ../fdroidserver/rewritemeta.py +msgid "List files that would be reformatted" +msgstr "Listar ficheiros que devem ser reformatados" + +#: ../fdroidserver/lint.py +msgid "Locale included in f-droid.org URL" +msgstr "Locale incluído no URL do f-droid.org" + +#: ../fdroidserver/build.py +msgid "Make the build stop on exceptions" +msgstr "Fazer a compilação parar se encontrar exceções" + +#: ../fdroidserver/index.py +msgid "Malformed repository mirrors." +msgstr "Espelhos de repositório malformados." + +#: ../fdroidserver/server.py +msgid "Malformed serverwebroot line:" +msgstr "Linha de serverwebroot malformada:" + +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "Espelha todo o repositório e pacotes, todos os tipos de ficheiros." + +#: ../fdroidserver/gpgsign.py +msgid "Missing output directory" +msgstr "Falta diretório de saída" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Name '%s' is just the auto name - remove it" +msgstr "O nome '%s' é apenas o nome automático - remover" + +#: ../fdroidserver/common.py +msgid "No 'config.py' found, using defaults." +msgstr "'config.py' não encontrado, utilizando as predefinições." + +#: ../fdroidserver/common.py +msgid "No Android SDK found!" +msgstr "Android SDK não encontrado!" + +#: ../fdroidserver/import.py +msgid "No android or kivy project could be found. Specify --subdir?" +msgstr "Nenhum projeto Android ou Kivy poderia ser encontrado. Especificar --subdir?" + +#: ../fdroidserver/install.py +msgid "No attached devices found" +msgstr "Nenhum aparelho anexado encontrado" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "No commit specified for {versionName} in {linedesc}" +msgstr "Nenhum commit especificado para {versionName} em {linedesc}" + +#: ../fdroidserver/index.py +msgid "No fingerprint in URL." +msgstr "Nenhuma impressão digital no URL." + +#: ../fdroidserver/common.py +msgid "No git submodules available" +msgstr "Não há submódulos git disponíveis" + +#: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "Não foi possível encontrar nenhum projeto de gradle. Especificar --subdir?" + +#: ../fdroidserver/import.py ../fdroidserver/common.py +msgid "No information found." +msgstr "Nenhuma informação encontrada." + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is Free Software" +msgstr "Não há necessidade de especificar que o app é software livre" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is for Android" +msgstr "Não há necessidade de especificar que o app é para Android" + +#: ../fdroidserver/server.py +msgid "No option set! Edit your config.py to set at least one of these:" +msgstr "Sem opção definida! Edite seu config.py para definir pelo menos um destes:" + +#: ../fdroidserver/common.py +msgid "No packages specified" +msgstr "Nenhum pacote especificado" + +#: ../fdroidserver/install.py +#, python-format +msgid "No signed apk available for %s" +msgstr "Nenhum apk assinado disponível para %s" + +#: ../fdroidserver/install.py +msgid "No signed output directory - nothing to do" +msgstr "Nenhum diretório de saída assinado - nada a fazer" + +#: ../fdroidserver/update.py ../fdroidserver/common.py +#, python-brace-format +msgid "No signing certificates found in {path}" +msgstr "Nenhum certificado de assinatura encontrado em {path}" + +#: ../fdroidserver/common.py +#, python-format +msgid "No such package: %s" +msgstr "Nenhum pacote desses: %s" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No such versionCode {versionCode} for app {appid}" +msgstr "Nenhum versionCode {versionCode} para o app {appid}" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +msgid "No unsigned directory - nothing to do" +msgstr "Nenhum diretório não assinado - nada a fazer" + +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "Não é uma definição de tamanho válida: \"{}\"" + +#: ../fdroidserver/signindex.py +msgid "Nothing to do" +msgstr "Nada para fazer" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Nothing to do for {appid}." +msgstr "Nada a fazer para {appid}." + +#: ../fdroidserver/init.py +msgid "Now set these in config.py:" +msgstr "Agora configure estes em config.py:" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "OBB file has newer versionCode({integer}) than any APK:" +msgstr "OBB tem versionCode ({integer}) mais recente que qualquer APK:" + +#: ../fdroidserver/update.py +msgid "OBB filename must start with \"main.\" or \"patch.\":" +msgstr "O nome do ficheiro OBB deve começar com \"main.\" ou \"patch.\":" + +#: ../fdroidserver/update.py +msgid "OBB's packagename does not match a supported APK:" +msgstr "O packagename do OBB não corresponde a um APK suportado:" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Old APK signature failed to verify: {path}" +msgstr "A assinatura antiga do APK não pôde ser verificada: {path}" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Old, deprecated name for fdroid deploy" +msgstr "Nome velho e obsoleto para implantar fdroid" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Only PNG and JPEG are supported for graphics, found: {path}" +msgstr "Somente PNG e JPEG são suportados para gráficos, encontrado: {path}" + +#: ../fdroidserver/checkupdates.py +msgid "Only print differences with the Play Store" +msgstr "Apenas mostrar diferenças com a Play Store" + +#: ../fdroidserver/checkupdates.py +msgid "Only process apps with auto-updates" +msgstr "Processar apenas apps com atualizações automáticas" + +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "Os métodos de doação OpenCollective pertencem no campo OpenCollective:" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Options" +msgstr "Opções" + +#: ../fdroidserver/verify.py +msgid "Output JSON report to file named after APK." +msgstr "Saída de relatório JSON para ficheiro nomeado após APK." + +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "Saída de JSON para stdout." + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "Saída do JSON" + +#: ../fdroidserver/import.py +msgid "Overall license of the project." +msgstr "Licença geral do projeto." + +#: ../fdroidserver/dscanner.py +msgid "Override path for repo APKs (default: ./repo)" +msgstr "Substituir o caminho para os APKs do repositório (predefinição: ./repo)" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" +msgstr "Substituindo versionName em branco em {apkfilename} dos metadados: {version}" + +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "O pacote \"{appid}\" já existe" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Parsing manifest at '{path}'" +msgstr "Analisando o manifesto em '{path}'" + +#: ../fdroidserver/common.py +msgid "Password required with username" +msgstr "Palavra-passe necessária com o nome de utilizador" + +#: ../fdroidserver/import.py +msgid "Path to main Android project subdirectory, if not in root." +msgstr "Caminho para o subdiretório principal do projeto Android, se não estiver na raiz." + +msgid "Path to main android project subdirectory, if not in root." +msgstr "Caminho para o subdiretório principal do projeto Android, se não estiver na raiz." + +#: ../fdroidserver/init.py +msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)" +msgstr "Caminho até o Android SDK (algumas vezes definido em ANDROID_HOME)" + +#: ../fdroidserver/btlog.py +msgid "Path to the git repo to use as the log" +msgstr "Caminho para o repositório git para usar como log" + +#: ../fdroidserver/init.py +msgid "Path to the keystore for the repo signing key" +msgstr "Caminho até a keystore para a chave de assinatura do repositório" + +#: ../fdroidserver/dscanner.py +msgid "Prepare Drozer to run a scan" +msgstr "Preparar Drozer para executar uma verificação" + +msgid "Prepare drozer to run a scan" +msgstr "Preparar Drozer para executar uma verificação" + +#: ../fdroidserver/nightly.py +msgid "Print the secret variable to the terminal for easy copy/paste" +msgstr "Imprimir a variável secreta para o terminal para copiar/colar fácilmente" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Problem with description of {appid}: {error}" +msgstr "Problema com a descrição de {appid}: {error}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Problem with xml at '{path}'" +msgstr "Problema com xml em '{path}'" + +#: ../fdroidserver/checkupdates.py +msgid "Process auto-updates" +msgstr "Processar atualizações automáticas" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#, python-brace-format +msgid "Processing {apkfilename}" +msgstr "A processar {apkfilename}" + +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#, python-brace-format +msgid "Processing {appid}" +msgstr "A processar {appid}" + +#: ../fdroidserver/update.py +msgid "Produce human-readable XML/JSON for index files" +msgstr "Produzir XML/JSON legível por humanos para ficheiros de índice" + +#: ../fdroidserver/update.py +msgid "Produce human-readable index.xml" +msgstr "Criação human-readable index.xml" + +#: ../fdroidserver/import.py +msgid "Project URL to import from." +msgstr "URL do projeto para importar." + +#: ../fdroidserver/lint.py +msgid "Punctuation should be avoided" +msgstr "A pontuação deve ser evitada" + +#: ../fdroidserver/btlog.py +msgid "Push the log to this git remote repository" +msgstr "Submeter o registo de eventos para este repositório git remoto" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing binary transparency log to {url}" +msgstr "A submeter o registo de transparência de binário para {url}" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing to {url}" +msgstr "A submeter para {url}" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Quickly start a new repository" +msgstr "Criar rapidamente um novo repositório" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Read all the metadata files and exit" +msgstr "Ler todos os ficheiros de metadados e sair" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading '{config_file}'" +msgstr "A ler '{config_file}'" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading minSdkVersion failed: \"{apkfilename}\"" +msgstr "A leitura de minSdkVersion falhou: \"{apkfilename}\"" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" +msgstr "A leitura de packageName/versionCode/versionName falhou, APK inválido: '{apkfilename}'" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Reading {apkfilename} from cache" +msgstr "Lendo {apkfilename} do cache" + +#: ../fdroidserver/stats.py +msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." +msgstr "Recalcular estatísticas agregadas - use quando foram feitas alterações que invalidariam os dados cache antigos." + +#: ../fdroidserver/common.py +msgid "Removing specified files" +msgstr "Apagando ficheiros especificados" + +#: ../fdroidserver/update.py +msgid "Rename APK files that do not match package.name_123.apk" +msgstr "Renomear todos os ficheiros APKs que não correspondem com package.name_123.apk" + +#: ../fdroidserver/update.py +msgid "Report on build data status" +msgstr "Relatório sobre o estado dos dados de compilação" + +#: ../fdroidserver/build.py +msgid "Reset and create a brand new build server, even if the existing one appears to be ok." +msgstr "Redefinir e criar um novo servidor de compilação, mesmo que o existente parecer normal." + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Resigning {apkfilename} with provided debug.keystore" +msgstr "Renunciando {apkfilename} com debug.keystore fornecido" + +#: ../fdroidserver/update.py +msgid "Resize all the icons exceeding the max pixel size and exit" +msgstr "Redimensionar todos os ícones que excedam o tamanho máximo de pixels e sair" + +#: ../fdroidserver/common.py +msgid "Restrict output to warnings and errors" +msgstr "Restringir a saída a erros e avisos" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Rewrite all the metadata files" +msgstr "Regravar todos os ficheiros de metadados" + +#: ../fdroidserver/rewritemeta.py +msgid "Rewrite to a specific format: " +msgstr "Reescrever para um formato específico: " + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}'" +msgstr "Reescrevendo '{appid}'" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}' to '{path}'" +msgstr "Reescrevendo '{appid}' para '{path}'" + +#: ../fdroidserver/checkupdates.py +msgid "Run on git repo that has uncommitted changes" +msgstr "Executar no repo git que tem alterações não confirmadas" + +#: ../fdroidserver/lint.py +msgid "Run rewritemeta to fix formatting" +msgstr "Executar rewritemeta para corrigir a formatação" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Running first pass with MD5 checking disabled" +msgstr "Executando a primeira passagem com a verificação de MD5 desativada" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Running wget in {path}" +msgstr "Executando o wget em {path}" + +#: ../fdroidserver/dscanner.py +msgid "Scan only the latest version of each package" +msgstr "Escanear apenas a versão mais recente de cada pacote" + +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "Procure no(s) APK(s) resultante(s) por classes conhecidas não livres." + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Scan the source code of a package" +msgstr "Analisar o código fonte de um pacote" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:" +msgstr "O scanner encontrou {count} problemas em {appid}:" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:{versionCode}:" +msgstr "O scanner encontrou {count} problemas em {appid}:{versionCode}:" + +#: ../fdroidserver/build.py +msgid "Scanner found {} problem" +msgid_plural "Scanner found {} problems" +msgstr[0] "Scanner encontrou {} problema" +msgstr[1] "Scanner encontrou {} problemas" + +#: ../fdroidserver/common.py +msgid "Set clock to that time using:" +msgstr "Configurar o relógio para esse tempo usando:" + +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "Definir o máximo de lançamentos no repo antes que os mais antigos sejam arquivados" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Set open file limit to {integer}" +msgstr "Definir o limite de ficheiros abertos para {integer}" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Set up an app build for a nightly build repo" +msgstr "Configurar uma compilação de app para um repositório de compilação noturno" + +#: ../fdroidserver/build.py +msgid "Setting open file limit failed: " +msgstr "Falha ao definir o limite de ficheiros abertos: " + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Setting {0} sec timeout for this build" +msgstr "Definindo o tempo limite de {0} seg para esta compilação" + +#: ../fdroidserver/build.py +msgid "Setup an emulator, install the APK on it and perform a Drozer scan" +msgstr "Configure um emulador, instale o APK nele e execute um scan do Drozer" + +msgid "Setup an emulator, install the apk on it and perform a drozer scan" +msgstr "Configure um emulador, instale o apk nele e execute um scan do drozer" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Sign and place packages in the repo" +msgstr "Assinar e pôr os pacotes no repositório" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Sign indexes created using update --nosign" +msgstr "Assinar os índices criados com o uso de update --nosign" + +#: ../fdroidserver/build.py +msgid "Skip scanning the source code for binaries and other problems" +msgstr "Pular o escaneamento do código-fonte atrás de binários e outros problemas" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping '{apkfilename}' with invalid signature!" +msgstr "Ignorando '{apkfilename}' com uma assinatura inválida!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping index generation for {appid}" +msgstr "Ignorando a geração de índices para {appid}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping {apkfilename} with invalid signature!" +msgstr "Ignorando '{apkfilename}' com uma assinatura inválida!" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: disabled" +msgstr "Ignorando {appid}: desativado" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: no builds specified" +msgstr "Ignorando {appid}: nenhuma compilação especificada" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify a local folder to sync the repo to" +msgstr "Especifique uma pasta local para ser sincronizada com o repositório" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify an identity file to provide to SSH for rsyncing" +msgstr "Especifique um ficheiro identidade para fornecer ao SSH para usar o rsync" + +#: ../fdroidserver/build.py +msgid "Specify that we're running on the build server" +msgstr "Especificar que estamos executando no servidor de compilação" + +#: ../fdroidserver/nightly.py +msgid "Specify which debug keystore file to use." +msgstr "Especifique o ficheiro de armazenamento de chaves de depuração." + +#: ../fdroidserver/common.py +msgid "Spew out even more information than normal" +msgstr "Mostrar ainda mais informações que o normal" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Striping mystery signature from {apkfilename}" +msgstr "Esvaziar assinatura misteriosa de {apkfilename}" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "Esvaziar a assinatura misteriosa de {apkfilename}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Summary '%s' is just the app's name" +msgstr "O resumo '%s' é apenas o nome do app" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Summary of length {length} is over the {limit} char limit" +msgstr "A descrição de comprimento {length} é sobre o limite de charácteres {limit}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "System clock is older than date in {path}!" +msgstr "O relógio do sistema é mais antigo que a data em {path}!" + +#: ../fdroidserver/build.py +msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." +msgstr "Modo de teste - coloque a saída apenas no diretório tmp e sempre compile, mesmo que a saída já exista." + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "The OBB version code must come after \"{name}.\":" +msgstr "O código de versão OBB deve estar após \"{name}.\":" + +#: ../fdroidserver/btlog.py +msgid "The base URL for the repo to log (default: https://f-droid.org)" +msgstr "O URL base para o registro de mudanças do repositório (predefinição: https://f-droid.org)" + +#: ../fdroidserver/mirror.py +msgid "The directory to write the mirror to" +msgstr "O diretório para onde escrever o espelho" + +#: ../fdroidserver/nightly.py +msgid "The file to be included in the repo (path or glob)" +msgstr "O ficherio a ser incluído no repo (caminho ou glob)" + +#: ../fdroidserver/server.py +msgid "The only commands currently supported are 'init' and 'update'" +msgstr "Os únicos comandos suportados atualmente são 'init' e 'update'" + +#: ../fdroidserver/index.py +msgid "The repository's fingerprint does not match." +msgstr "A impressão digital do repositório não corresponde." + +#: ../fdroidserver/common.py +msgid "The repository's index could not be verified." +msgstr "O índice do repositório não pôde ser verificado." + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "The root dir for local_copy_dir \"{path}\" does not exist!" +msgstr "O diretório raiz para local_copy_dir \"{path}\" não existe!" + +#: ../fdroidserver/publish.py +msgid "There is a keyalias collision - publishing halted" +msgstr "Há uma colisão do keyalias - publicação parada" + +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "Estas são as aplicações que foram arquivadas do repositório principal." + +#: ../fdroidserver/import.py +#, python-format +msgid "This repo already has local metadata: %s" +msgstr "Este repositório já tem metadados locais: %s" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" +msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser definidos no config.py!" + +#: ../fdroidserver/lint.py +msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgstr "UCM é definido, mas parece que checkupdates ainda não foi executado" + +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "A URL deve começar com https:// ou http://" + +#: ../fdroidserver/lint.py +msgid "URL shorteners should not be used" +msgstr "Encurtadores de URL não devem ser usados" + +#: ../fdroidserver/metadata.py +msgid "URL title is just the URL, use brackets: [URL]" +msgstr "O título do URL é apenas o URL, use parênteses: [URL]" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "URL {url} in Description: {error}" +msgstr "Há o URL {url} na descrição: {error}" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Etiqueta de licença \"{}\" inesperada! Use somente as etiquetas aprovadas pela FSF ou OSI de https://spdx.org/license-list" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "Etiqueta de licença \"{}\" inesperada! Use somente as etiquetas de licença configuradas no seu ficheiro de configuração" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unexpected text on same line as {field} in {linedesc}" +msgstr "Texto inesperado na mesma linha como {field} em {linedesc}" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Unknown exception found!" +msgstr "Exceção desconhecida!" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Unknown file '{filename}' in build '{versionName}'" +msgstr "Ficheiro desconhecido '{filename}' na compilação '{versionName}'" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Unknown metadata format: %s" +msgstr "Formato de metadados desconhecido: %s" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path}" +msgstr "Formato de metadados desconhecido: {path}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "O formato de metadados é desconhecido: {path} (use: *.yml)" + +#: ../fdroidserver/common.py +msgid "Unknown version of aapt, might cause problems: " +msgstr "Versão desconhecida do aapt, pode causar problemas: " + +#: ../fdroidserver/lint.py +msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "Ligação des-lig-ada - use [http://foo.bar Título do link] ou [http://foo.bar]" + +#: ../fdroidserver/lint.py +msgid "Unnecessary leading space" +msgstr "Espaço desnecessário à frente" + +#: ../fdroidserver/lint.py +msgid "Unnecessary trailing space" +msgstr "Espaço desnecessário ao fim" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised app field '{fieldname}' in '{path}'" +msgstr "Campo de aplicação '{fieldname}' não reconhecido em '{path}'" + +#: ../fdroidserver/metadata.py +msgid "Unrecognised app field: " +msgstr "Campo da app não reconhecido: " + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised build flag '{build_flag}' in '{path}'" +msgstr "Bandeira de compilação '{build_flag}' não reconhecida em '{path}'" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised field '{field}' in {linedesc}" +msgstr "Campo '{field}' não reconhecido em {linedesc}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported file type \"{extension}\" for repo graphic" +msgstr "Tipo de ficheiro \"{extension}\" não suportado para o gráfico de repo" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported graphics file found: {path}" +msgstr "Ficheiro gráfico não suportado encontrado: {path}" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Unsupported metadata format, use: --to [{supported}]" +msgstr "Formato de metadados não suportado, use:--to [{supported}]" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]" +msgstr "Não terminado ]" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]]" +msgstr "Não terminado ]]" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated build in {name}" +msgstr "Compilação não terminada em {name}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated continuation in {name}" +msgstr "Continuação não terminada em {name}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused extlib at %s" +msgstr "Extlib não utilizado em %s" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused file at %s" +msgstr "Ficheiro não utilizado em %s" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "O caminho de scandelete não é usado: %s" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "O caminho de scanignore não é usado: %s" + +#: ../fdroidserver/lint.py +msgid "Update Check Name is set to the known app id - it can be removed" +msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update repo information for new packages" +msgstr "Atualizar a informação do repositório para novos pacotes" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update the binary transparency log for a URL" +msgstr "Atualizar o registo de transparência de binário para um URL" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update the stats of the repo" +msgstr "Atualizar as estatísticas do repositório" + +#: ../fdroidserver/update.py ../fdroidserver/build.py +msgid "Update the wiki" +msgstr "Atualizar a wiki" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "UpdateCheckData has invalid URL: {url}" +msgstr "UpdateCheckData tem URL inválido: {url}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must use HTTPS URL: {url}" +msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData not a valid URL: {url}" +msgstr "UpdateCheckData não é uma URL válida: {url}" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "A enviar {apkfilename} ao androidobservatory.org" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "A enviar {apkfilename} ao virustotal" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Usage" +msgstr "Utilização" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "Usage: %s\n" +msgstr "Utilização: %s\n" + +#: ../fdroidserver/lint.py +msgid "Use /HEAD instead of /master to point at a file in the default branch" +msgstr "Use /HEAD em vez de /master para apontar num ficheiro na ramificação predefinida" + +#: ../fdroidserver/update.py +msgid "Use `fdroid update -c` to create it." +msgstr "Use ' fdroid update -c ' para criá-lo." + +#: ../fdroidserver/build.py +msgid "Use build server" +msgstr "Usar servidor de compilação" + +#: ../fdroidserver/update.py +msgid "Use date from APK instead of current time for newly added APKs" +msgstr "Use da data do APK em vez do tempo atual para APKs recém-adicionados" + +msgid "Use date from apk instead of current time for newly added apks" +msgstr "Use a data do apk em vez do tempo atual para apks recém-adicionados" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using \"{path}\" for configuring s3cmd." +msgstr "Usando \"{path}\" para configurar s3cmd." + +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "A usar a assinatura APK v2" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "A usar a assinatura APK v3" + +#: ../fdroidserver/common.py +msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" +msgstr "Usando o jarsigner de Java, não recomendado para verificar APKs! Use apksigner" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Using androguard from \"{path}\"" +msgstr "Usando androguard de \"{path}\"" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Using existing keystore \"{path}\"" +msgstr "Utilizando armazenamento de chave existente \"{path}\"" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using s3cmd to sync with: {url}" +msgstr "Usando s3cmd para sincronizar com: {url}" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Valid commands are:" +msgstr "Comandos válidos:" + +#: ../fdroidserver/verify.py +msgid "Verify against locally cached copy rather than redownloading." +msgstr "Verifique a cópia em cache local em vez de redescarregando." + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Verify the integrity of downloaded packages" +msgstr "Verifique a integridade dos pacotes descarregados" + +#: ../fdroidserver/index.py +msgid "Verifying index signature:" +msgstr "Verificar o índice de assinatura:" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "A chave VirusTotal API não pode enviar ficheiros maiores que 32MB, use {url} para enviar {path}." + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Warn about possible metadata errors" +msgstr "Avisar sobre possíveis erros de metadados" + +#: ../fdroidserver/update.py +msgid "When configured for signed indexes, create only unsigned indexes at this stage" +msgstr "Quando configurado para índices assinados, crie apenas índices não assinados nesta etapa" + +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "Ao cotar todo o repositório o yamllint é desativado por predefinição. Esta opção força o yamllint independentemente." + +msgid "X.509 'Distiguished Name' used when generating keys" +msgstr "X.509 'Distiguished Name' usado ao gerar as chaves" + +#: ../fdroidserver/init.py +msgid "X.509 'Distinguished Name' used when generating keys" +msgstr "X.509 'Distiguished Name' usado na geração de chaves" + +#: ../fdroidserver/common.py +msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" +msgstr "Pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou seja:" + +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "Arquivo de ficheiros ZIP" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "adding IdentityFile to {path}" +msgstr "adicionando IdentityFile a {path}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "adding to {name}: {path}" +msgstr "adicionando a {name}: {path}" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ambiguous option: %(option)s could match %(matches)s" +msgstr "opção ambígua: %(option)s poderia corresponder %(matches)s" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "ambiguous option: %s (%s?)" +msgstr "opção ambígua: %s (%s?)" + +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "Nenhum apksigner encontrado, é necessário para assinar!" + +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +msgid "applicationId in the form APPID" +msgstr "applicationId, na forma APPID" + +#: ../fdroidserver/checkupdates.py +msgid "applicationId to check for updates" +msgstr "applicationId para verificar se há atualizações" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/dscanner.py ../fdroidserver/build.py +#: ../fdroidserver/scanner.py ../fdroidserver/install.py +msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "argument \"-\" with mode %r" +msgstr "argumento \"-\" com o modo %r" + +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "tentar a conexão nua por SSH para testar a implantação da chave:" + +#: ../fdroidserver/nightly.py +msgid "attempting bare ssh connection to test deploy key:" +msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" + +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "não é possível analisar as especificações do scrlib (não é uma cadeia): '{}'" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "can't open '%s': %s" +msgstr "não dá pra abrir '%s': %s" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "não é possível encontrar os srclibs necessários: \"{path}\"" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "cannot have multiple subparser arguments" +msgstr "não é possível ter vários argumentos de subparser" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "cannot merge actions - two groups are named %r" +msgstr "não é possível unir ações - dois grupos são denominados %r" + +#: ../fdroidserver/nightly.py +msgid "cannot publish update, did you set the deploy key?" +msgstr "não é possível publicar a atualização, definiu a chave de implantação?" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "cloning {url}" +msgstr "clonagem {url}" + +#: ../fdroidserver/server.py +msgid "command to execute, either 'init' or 'update'" +msgstr "comando para executar, seja 'init' ou 'update'" + +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "comandos dos módulos de plugin:" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "complex" +msgstr "complexo" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "conflicting option string: %s" +msgid_plural "conflicting option strings: %s" +msgstr[0] "cadeia de opções conflitante: %s" +msgstr[1] "cadeias de opções conflitantes: %s" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "copying {apkfilename} into {path}" +msgstr "copiando {apkfilename} para {path}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "não foi possível analisar '{path}'" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "não foi possível analisar a especificação srclib (referência não especificada): '{}'" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "não foi possível analisar a especificação srclib (demais símbolos '@'): '{}'" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "created {path}" +msgstr "{path} criado" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "deleting: repo/{apkfilename}" +msgstr "apagando: repo/{apkfilename}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed build logs to '{path}'" +msgstr "logs de compilação implantados para '{path}'" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "registo de processo implantado {path} a {dest}" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "dest= is required for options like %r" +msgstr "dest = é necessário para opções como %r" + +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "binário executável, possivelmente código" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "expected %s argument" +msgid_plural "expected %s arguments" +msgstr[0] "%s argumento esperado" +msgstr[1] "%s argumentos esperados" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at least one argument" +msgstr "esperado pelo menos um argumento" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at most one argument" +msgstr "esperado um argumento no máximo" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected one argument" +msgstr "esperado um argumento" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "failed deploying build logs to '{path}'" +msgstr "falha na implantação de logs de compilação para '{path}'" + +#: ../fdroid +msgid "fdroid [-h|--help|--version] []" +msgstr "fdroid [-h|--help|--version] []" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "fdroid [] [-h|--help|--version|]" +msgstr "fdroid [] [-h|--help|--version|]" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "floating-point" +msgstr "ponto flutuante" + +#: ../fdroidserver/metadata.py +msgid "force errors to be warnings, or ignore" +msgstr "forçar erros como avisos ou ignorá-los" + +#: ../fdroidserver/metadata.py +msgid "force metadata errors (default) to be warnings, or to be ignored." +msgstr "Forçar os erros de metadados (padrão) para serem avisos, ou para serem ignorados." + +#: ../fdroidserver/common.py +msgid "git svn clone failed" +msgstr "git svn clone falhou" + +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "arquivo de ficheiros gzip" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ignored explicit argument %r" +msgstr "argumento explícito %r ignorado" + +#: ../fdroidserver/index.py +msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" +msgstr "index-v1 deve ter uma assinatura, use ' fdroid signindex ' para criá-lo!" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "integer" +msgstr "inteiro" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid %(type)s value: %(value)r" +msgstr "valor inválido do tipo %(type)s: %(value)r" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid choice: %(value)r (choose from %(choices)s)" +msgstr "opção inválida: %(value)r (escolha de %(choices)s)" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid conflict_resolution value: %r" +msgstr "valor conflict_resolution inválido: %r" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" +msgstr "Opção cadeia %(option)r inválida: deve começar com o caractere %(prefix_chars)r" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" +msgstr "local_copy_dir não termina com \"fdroid\", talvez quis: \"{path}\"" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be an absolute path!" +msgstr "local_copy_dir deve ser um caminho absoluto!" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be directory, not a file!" +msgstr "local_copy_dir deve ser directory, não um ficheiro!" + +#: ../fdroidserver/index.py +#, python-format +msgid "mirror '%s' does not end with 'fdroid'!" +msgstr "espelho '%s' não termina com 'fdroid'!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "mutually exclusive arguments must be optional" +msgstr "argumentos mutuamente exclusivos devem ser opcional" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "no \"icon\" in {appid}" +msgstr "nenhum \"ícone\" em {appid}" + +#: ../fdroidserver/signatures.py +msgid "no APK supplied" +msgstr "nenhum APK fornecido" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "no such option: %s" +msgstr "não tem tal opção: %s" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "no version info found!" +msgstr "não há informações de versão encontrada!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "not allowed with argument %s" +msgstr "não é permitido com o argumento %s" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "one of the arguments %s is required" +msgstr "um dos argumentos %s é necessário" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "only accepts strings, lists, and tuples" +msgstr "apenas aceita cadeias, listas e tuplos" + +#: ../fdroidserver/install.py +#, python-format +msgid "option %s: If you really want to install all the signed apps, use --all" +msgstr "opção %s: se realmente deseja instalar todas as apps assinadas, use --all" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid %s value: %r" +msgstr "Opção %s: valor %s inválido: %r" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid choice: %r (choose from %s)" +msgstr "opção %s: escolha inválida: %r (escolha entre %s)" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s not recognized" +msgstr "opção -%s não reconhecida" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s requires argument" +msgstr "opção -%s requer um argumento" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s must not have an argument" +msgstr "opção --%s não pode ter argumento" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not a unique prefix" +msgstr "opção --%s não é prefixo único" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not recognized" +msgstr "opção --%s não reconhecida" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s requires argument" +msgstr "opção --%s necessita argumento" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "optional arguments" +msgstr "argumentos opcionais" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "overwriting existing {path}" +msgstr "sobrescrevendo {path} existente" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "positional arguments" +msgstr "argumentos posicionais" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "a implementação do registo de processo {path} a {dest} falhou!" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" +msgstr "Recusado o download via conexão HTTP insegura (use HTTPS ou especifique --no-https-check): {apkfilename}" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" +msgstr "Recusado o download via conexão http insegura (use https ou especifique --no-https-check): {apkfilename}" + +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "o ruamel.yaml não está instalado, não é possível escrever metadados." + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "s3cmd sync indexes {path} to {url} and delete" +msgstr "s3cmd sincroniza índices {path} para {url} e apaga" + +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "biblioteca compartilhada" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "show program's version number and exit" +msgstr "mostrar versão do programa e sair" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.5/optparse.py +#: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py +msgid "show this help message and exit" +msgstr "mostrar esta ajuda e sair" + +#: ../fdroidserver/signatures.py +msgid "signed APK, either a file-path or HTTPS URL." +msgstr "APK assinado, seja um caminho de ficheiro ou um URL HTTPS." + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: log content is empty" +msgstr "pular a implantação de logs completos de compilação: o conteúdo do log está vazio" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: not enabled in config" +msgstr "pular a implantação de logs de criação completos: não ativado na configuração" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "skipping source tarball: {path}" +msgstr "ignorando o tarball de origem: {path}" + +#: ../fdroidserver/lint.py +msgid "srclibs missing name and/or @" +msgstr "Nome 'srclibs' ausente e/ou '@'" + +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "biblioteca estática" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" +msgstr "o valor do data-hora fornecido ('{timestamp}') não está no formato timestamp unix" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "the following arguments are required: %s" +msgstr "os seguintes argumentos são necessários: %s" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unexpected option string: %s" +msgstr "opção de cadeia de texto inesperada: %s" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unknown parser %(parser_name)r (choices: %(choices)s)" +msgstr "O formato '%(parser_name)r' é desconhecido. (Opções Válidas: %(choices)s)" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unrecognized arguments: %s" +msgstr "argumentos não reconhecidos: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "unsafe permissions on '{config_file}' (should be 0600)!" +msgstr "permissões inseguras em '{config_file}' (deveria ser 0600)!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py +msgid "usage: " +msgstr "utilização: " + +#: ../fdroid +msgid "usage: fdroid [-h|--help|--version] []" +msgstr "utilização: fdroid [-h|--help|--version] []" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "using Apache libcloud to sync with {url}" +msgstr "usando o Apache libcloud para sincronizar com {url}" + +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "o virustotal.com está a limitar a taxa, à espera para voltar a tentar..." + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "{0} app, {1} key aliases" +msgid_plural "{0} apps, {1} key aliases" +msgstr[0] "{0} app, {1} aliases chave" +msgstr[1] "{0} apps, {1} aliases chave" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} ({appid}) has no metadata!" +msgstr "{apkfilename} ({appid}) não tem metadados!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" +msgstr "{apkfilename} tem vários ficheiros {name} que, parece explorar a Master Key!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " +msgstr "AndroidManifest.xml do {apkfilename} tem uma data má: " + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using package name instead." +msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android Package Name!" +msgstr "{appid} from {path} não é um nome de pacote Android válido!" + +#: ../fdroidserver/metadata.py ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Java Package Name!" +msgstr "{appid} do {path} não é um Nome de Pacote Java válido!" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{appid} is missing {name}" +msgstr "{appid} tem falta de {name}" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: Unknown extlib {path} in build '{versionName}'" +msgstr "{appid}: extlib {path} desconhecido na compilação '{versionName}'" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "{appid}: no builds specified, running on current source state" +msgstr "{appid}: nehnuma compilação especificada, em execução no estado de origem atual" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" +msgstr "{appid}: {field} deve ser um '{type}', mas é um '{fieldtype}!'" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" +msgstr "{appid}: {field} deve ser um '{type}', mas é um '{fieldtype}'!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "{build_flag} deve ser um inteiro, encontrado: {value}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{field} not terminated in {name}" +msgstr "{field} não foi terminado em {name}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "{file} está em branco ou corrompido!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{name} \"{path}\" does not exist! Correct it in config.py." +msgstr "{name} \"{path}\" não existe! Corrija-o no config.py." + +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "{path} já existe, a ignorar os resultados das importações!" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "{path} does not exist! Create it by running:" +msgstr "{path} não existe! Crie-o executando:" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" +msgstr "{path} tem uma má assinatura de ficheiro \"{pattern}\", um exploração Janus é possível!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} is zero size!" +msgstr "{path} tem um tamanho de zero!" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "{path} mais de 200MB, enviar manualmente: {url}" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{url} does not end with \"fdroid\", check the URL path!" +msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} não começa com \"http\"!" + +#: ../fdroidserver/build.py +msgid "{} build failed" +msgid_plural "{} builds failed" +msgstr[0] "{} compilação falhada" +msgstr[1] "{} compilações falhadas" + +#: ../fdroidserver/build.py +msgid "{} build succeeded" +msgid_plural "{} builds succeeded" +msgstr[0] "{} compilação com sucesso" +msgstr[1] "{} compilações com sucesso" diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 829f7d47..8a483606 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -4,13 +4,14 @@ # André Marcelo Alvarenga , 2020. # Hans-Christoph Steiner , 2020. # Rafael Fontenelle , 2020. +# ssantos , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-10-02 19:15+0000\n" -"Last-Translator: Wellington Terumi Uemura \n" +"PO-Revision-Date: 2020-10-03 14:48+0000\n" +"Last-Translator: ssantos \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -2036,7 +2037,7 @@ msgstr "Você pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou s #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "Arquivo ZIP" +msgstr "Arquivo de ficheiros ZIP" #: ../fdroidserver/nightly.py #, python-brace-format diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index 4e88f9bc..289817d1 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-10-01 09:00+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"Last-Translator: ssantos \n" "Language-Team: Portuguese (Portugal) \n" "Language: pt_PT\n" "MIME-Version: 1.0\n" @@ -28,6 +28,12 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Este é um repositório de apps a serem usados com o FDroid.\n" +" Aplicações neste repositório são binários oficiais compilados pelos\n" +" programadores da aplicação original ou são binários compilados da\n" +" fonte por f-droid.org a usar as ferramentas em https://gitlab.com/fdroid.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -38,13 +44,12 @@ msgstr "" "Chave pública SSH para ser usada como chave de implantar:" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" msgstr "" "\n" -"Chave pública SSH para ser usada como chave de implantar:" +"Chave pública SSH a ser usada como chave de implantação:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -61,7 +66,7 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" não tem ficheiro de metadados correspondente!" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." msgstr "'{apkfilename}' já está instalado no {dev}." @@ -81,9 +86,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe, mas s3cmd não está instalado!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" +msgstr "\"{path}\" não é um formato de ficheiro aceito (use: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -93,7 +98,7 @@ msgstr "\"{path}\" não é um formato aceito, converter para: {formats}" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" não é uma URL válida!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -147,7 +152,7 @@ msgstr "'keypass' não foi encontrada em config.py!" #: ../fdroidserver/common.py msgid "'keystore' is NONE and 'smartcardoptions' is blank!" -msgstr "" +msgstr "\"keystore\" é NONE e \"smartcardoptions\" está vazio!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" @@ -269,16 +274,15 @@ msgstr "Também avisar sobre problemas de formatação, como rewritemeta -l" #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "Biblioteca AAR do Android" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Ficheiro APK do Android" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "Android SDK não encontrado!" +msgstr "Código DEX do Android" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -343,7 +347,7 @@ msgstr "Ramificação '{branch}' usado como commit em srclib '{srclib}'" #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Ligação simbólica quebrada: {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -402,9 +406,9 @@ msgid "Cannot resolve app id {appid}" msgstr "Não é possível resolver o ID da app {appid}" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "Não é possível ler \"{path}\"!" +msgstr "Não é possível reescrever \"{path}\"" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -464,7 +468,7 @@ msgstr "Enviar mudanças" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Argumentos conflitantes: \"--verbose\" e \"--quiet\" não podem ser especificados ao mesmo tempo." #: ../fdroidserver/common.py #, python-brace-format @@ -472,12 +476,10 @@ msgid "Could not find '{command}' on your system" msgstr "Não foi possível encontrar '{command}' no seu sistema" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version code" msgstr "Não foi possível encontrar o código de versão mais recente" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version name" msgstr "Não foi possível encontrar o nome da versão mais recente" @@ -493,12 +495,11 @@ msgstr "Não foi possível abrir ficheiro apk para análise" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not parse size \"{size}\", wrong type \"{type}\"" -msgstr "" +msgstr "Não foi possível analisar o tamanho \"{size}\", tipo \"{type}\" incorreto" #: ../fdroidserver/import.py -#, fuzzy msgid "Couldn't find Application ID" -msgstr "Não foi possível encontrar o ID do pacote" +msgstr "Não foi possível encontrar o ID da aplicação" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -578,12 +579,12 @@ msgstr "Eliminação de APK'S e/ou OBBs que não contêm metadados do repositór #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Apagar ficheiro, o reporte é muito grande ({size} max {limit})" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Apagar o histórico do git-mirror, o repo é muito grande ({size} max {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -611,7 +612,7 @@ msgstr "A descrição de comprimento {length} é sobre o limite de char {limit}" #: ../fdroidserver/import.py msgid "Do not add 'disable:' to the generated build entries" -msgstr "" +msgstr "Não adicionar 'disable:' às entradas de compilação geradas" #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" @@ -698,7 +699,7 @@ msgstr "Sinalizador de compilação vazio em {linedesc}" #: ../fdroidserver/__main__.py #, python-brace-format msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." -msgstr "" +msgstr "A codificação está definida como '{enc}' fdroid pode ter problemas de codificação. Por favor, configure-o para 'UTF-8' para obter melhores resultados." #: ../fdroidserver/init.py #, python-format @@ -724,9 +725,9 @@ msgid "Extract signatures from APKs" msgstr "Extrato de assinaturas de APKs" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Failed copying {path}: {error}" -msgstr "Falha de leitura {path}: {error}" +msgstr "Falha ao copiar {path}: {error}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -792,7 +793,7 @@ msgstr "Assinaturas obtidas para '{apkfilename}'-> '{sigdir}'" #: ../fdroidserver/update.py #, python-brace-format msgid "File disappeared while processing it: {path}" -msgstr "" +msgstr "O ficheiro desapareceu enquanto era processado: {path}" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -806,9 +807,8 @@ msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Os métodos de doação do Flattr pertencem no sinalizador FlattrID" #: ../fdroidserver/lint.py -#, fuzzy msgid "Flattr donation methods belong in the FlattrID: field" -msgstr "Os métodos de doação do Flattr pertencem no sinalizador FlattrID" +msgstr "Os métodos de doação do Flattr pertencem no campo FlattrID:" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" @@ -825,7 +825,7 @@ msgstr "Forçar suspender a construção depois de esperar {0} segundos!" #: ../fdroidserver/scanner.py msgid "Force scan of disabled apps and builds." -msgstr "" +msgstr "Forçar a análise de apps e construções desativados." #: ../fdroidserver/update.py #, python-brace-format @@ -835,7 +835,7 @@ msgstr "\"{path}\" gráfico encontrado sem metadados para o app \"{name}\"!" #: ../fdroidserver/update.py #, python-brace-format msgid "Found bad funding file \"{path}\" for \"{name}\":" -msgstr "" +msgstr "Ficheiro de financiamento ruim \"{path}\" encontrado para \"{name}\":" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" @@ -847,9 +847,9 @@ msgid "Found invalid versionCodes for some apps" msgstr "versionCodes inválidos encontrados para algumas apps" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found multiple JAR Signature Block Files in {path}" -msgstr "Vários certificados de assinatura encontrados em {path}" +msgstr "Vários ficheiros de blocos de assinaturas JAR foram encontrados em {path}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -875,9 +875,9 @@ msgid "Found non-file at %s" msgstr "Não-ficheiro encontrado em %s" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "copiando {apkfilename} para {path}" +msgstr "{apkfilename} encontrado em {url}" #: ../fdroidserver/update.py #, python-brace-format @@ -902,9 +902,9 @@ msgid "Git remote set-head failed" msgstr "Git remote set-head falhou" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Git remote set-head falhou" +msgstr "Git remote set-head falhou: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -924,22 +924,22 @@ msgstr "HTTPS deve ser usado nos URLs do Subversion!" #: ../fdroidserver/server.py msgid "If a git mirror gets to big, allow the archive to be deleted" -msgstr "" +msgstr "Se um espelho git ficar muito grande, permite que o arquivo seja apagado" #: ../fdroidserver/server.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Se esse envio falhar, tente enviar manualmente para {url}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." -msgstr "" +msgstr "A ignorar '{field}' em metadados '{metapath}' porque é depreciado." #: ../fdroidserver/update.py #, python-format msgid "Ignoring FUNDING.yml entry longer than 2048: %s" -msgstr "" +msgstr "A ignorar a entrada FUNDING.yml por mais de 2048: %s" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -961,15 +961,15 @@ msgstr "Incluir APKs assinados com algoritmos desabilitados como MD5" #: ../fdroidserver/mirror.py msgid "Include the PGP signature .asc files in the mirror" -msgstr "" +msgstr "Incluir os ficheiros .asc da assinatura PGP no espelho" #: ../fdroidserver/mirror.py msgid "Include the build logs in the mirror" -msgstr "" +msgstr "Incluir os registos de construção no espelho" #: ../fdroidserver/mirror.py msgid "Include the source tarballs in the mirror" -msgstr "" +msgstr "Incluir os tarballs de fontes no espelho" #: ../fdroidserver/common.py msgid "Initialising submodules" @@ -984,9 +984,9 @@ msgid "Install built packages on devices" msgstr "Instalação dos pacotes compilados no aparelho" #: ../fdroidserver/install.py -#, fuzzy, python-format +#, python-format msgid "Installing %s..." -msgstr "Instalando %s…" +msgstr "A instalar %s…" #: ../fdroidserver/install.py #, python-format @@ -994,9 +994,9 @@ msgid "Installing %s…" msgstr "Instalando %s…" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Installing '{apkfilename}' on {dev}..." -msgstr "Instalando '{apkfilename}' em {dev}…" +msgstr "A instalar '{apkfilename}' em {dev}…" #: ../fdroidserver/install.py #, python-brace-format @@ -1069,19 +1069,19 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Redirecionamento inválido para não-HTTPS: {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Ler todos os ficheiros de metadados e sair" +msgstr "Metadados de scrlib inválidos: '{file}' não existe" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: could not parse '{file}'" -msgstr "" +msgstr "Metadados de srclib inválidos: não foi possível analisar \"{file}\"" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" -msgstr "" +msgstr "Metadados de srclib inválidos: chave \"{key}\" desconhecida no \"{file}\"" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1100,7 +1100,7 @@ msgstr "Assinatura JAR verificada: {path}" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "Ficheiro Java JAR" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1109,7 +1109,7 @@ msgstr "O Java JDK não foi encontrado! Instalar no local predefinido ou definir #: ../fdroidserver/scanner.py msgid "Java compiled class" -msgstr "" +msgstr "Classe Java compilada" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1129,9 +1129,8 @@ msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o modo de verificação de atualização é '{ucm}'" #: ../fdroidserver/lint.py -#, fuzzy msgid "Liberapay donation methods belong in the Liberapay: field" -msgstr "Os métodos de doação de Liberapay pertencem na bandeira de LiberapayID" +msgstr "Os métodos de doação de Liberapay pertencem no campo Liberapay:" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" @@ -1159,7 +1158,7 @@ msgstr "Linha de serverwebroot malformada:" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." -msgstr "" +msgstr "Espelha todo o repositório e pacotes, todos os tipos de ficheiros." #: ../fdroidserver/gpgsign.py msgid "Missing output directory" @@ -1200,9 +1199,8 @@ msgid "No git submodules available" msgstr "Não há submódulos git disponíveis" #: ../fdroidserver/import.py -#, fuzzy msgid "No gradle project could be found. Specify --subdir?" -msgstr "Nenhum projeto Android ou Kivy poderia ser encontrado. Especificar --subdir?" +msgstr "Não foi possível encontrar nenhum projeto de gradle. Especificar --subdir?" #: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." @@ -1255,7 +1253,7 @@ msgstr "Nenhum diretório não assinado - nada a fazer" #: ../fdroidserver/common.py msgid "Not a valid size definition: \"{}\"" -msgstr "" +msgstr "Não é uma definição de tamanho válida: \"{}\"" #: ../fdroidserver/signindex.py msgid "Nothing to do" @@ -1307,9 +1305,8 @@ msgid "Only process apps with auto-updates" msgstr "Processar apenas apps com atualizações automáticas" #: ../fdroidserver/lint.py -#, fuzzy msgid "OpenCollective donation methods belong in the OpenCollective: field" -msgstr "Os métodos de doação do Flattr pertencem no sinalizador FlattrID" +msgstr "Os métodos de doação OpenCollective pertencem no campo OpenCollective:" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1322,13 +1319,13 @@ msgstr "Saída de relatório JSON para ficheiro nomeado após APK." #: ../fdroidserver/scanner.py msgid "Output JSON to stdout." -msgstr "" +msgstr "Saída de JSON para stdout." #: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py #: ../fdroidserver/update.py ../fdroidserver/signindex.py #: ../fdroidserver/checkupdates.py msgid "Outputting JSON" -msgstr "" +msgstr "Saída do JSON" #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1346,7 +1343,7 @@ msgstr "Substituindo versionName em branco em {apkfilename} dos metadados: {vers #: ../fdroidserver/import.py #, python-brace-format msgid "Package \"{appid}\" already exists" -msgstr "" +msgstr "O pacote \"{appid}\" já existe" #: ../fdroidserver/common.py #, python-brace-format @@ -1545,7 +1542,7 @@ msgstr "Escanear apenas a versão mais recente de cada pacote" #: ../fdroidserver/build.py msgid "Scan the resulting APK(s) for known non-free classes." -msgstr "" +msgstr "Procure no(s) APK(s) resultante(s) por classes conhecidas não livres." #: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" @@ -1573,7 +1570,7 @@ msgstr "Configurar o relógio para esse tempo usando:" #: ../fdroidserver/nightly.py msgid "Set maximum releases in repo before older ones are archived" -msgstr "" +msgstr "Definir o máximo de lançamentos no repo antes que os mais antigos sejam arquivados" #: ../fdroidserver/build.py #, python-brace-format @@ -1663,9 +1660,9 @@ msgid "Striping mystery signature from {apkfilename}" msgstr "Esvaziar assinatura misteriosa de {apkfilename}" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Stripping mystery signature from {apkfilename}" -msgstr "Esvaziar assinatura misteriosa de {apkfilename}" +msgstr "Esvaziar a assinatura misteriosa de {apkfilename}" #: ../fdroidserver/lint.py #, python-format @@ -1727,7 +1724,7 @@ msgstr "Há uma colisão do keyalias - publicação parada" #: ../fdroidserver/common.py msgid "These are the apps that have been archived from the main repo." -msgstr "" +msgstr "Estas são as aplicações que foram arquivadas do repositório principal." #: ../fdroidserver/import.py #, python-format @@ -1744,7 +1741,7 @@ msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" -msgstr "" +msgstr "A URL deve começar com https:// ou http://" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" @@ -1760,13 +1757,12 @@ msgid "URL {url} in Description: {error}" msgstr "Há o URL {url} na descrição: {error}" #: ../fdroidserver/lint.py -#, fuzzy msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" -msgstr "Etiqueta de licença \"%s\" inválida! Use apenas etiquetas de https://spdx.org/license-list" +msgstr "Etiqueta de licença \"{}\" inesperada! Use somente as etiquetas aprovadas pela FSF ou OSI de https://spdx.org/license-list" #: ../fdroidserver/lint.py msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" -msgstr "" +msgstr "Etiqueta de licença \"{}\" inesperada! Use somente as etiquetas de licença configuradas no seu ficheiro de configuração" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1794,9 +1790,9 @@ msgid "Unknown metadata format: {path}" msgstr "Formato de metadados desconhecido: {path}" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path} (use: *.yml)" -msgstr "Formato de metadados desconhecido: {path}" +msgstr "O formato de metadados é desconhecido: {path} (use: *.yml)" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1877,14 +1873,14 @@ msgid "Unused file at %s" msgstr "Ficheiro não utilizado em %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scandelete path: %s" -msgstr "Ficheiro não utilizado em %s" +msgstr "O caminho de scandelete não é usado: %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scanignore path: %s" -msgstr "Ficheiro não utilizado em %s" +msgstr "O caminho de scanignore não é usado: %s" #: ../fdroidserver/lint.py msgid "Update Check Name is set to the known app id - it can be removed" @@ -1924,12 +1920,12 @@ msgstr "UpdateCheckData não é uma URL válida: {url}" #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" -msgstr "" +msgstr "A enviar {apkfilename} ao androidobservatory.org" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Uploading {apkfilename} to virustotal" -msgstr "Lendo {apkfilename} do cache" +msgstr "A enviar {apkfilename} ao virustotal" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1968,11 +1964,11 @@ msgstr "Usando \"{path}\" para configurar s3cmd." #: ../fdroidserver/common.py msgid "Using APK Signature v2" -msgstr "" +msgstr "A usar a assinatura APK v2" #: ../fdroidserver/common.py msgid "Using APK Signature v3" -msgstr "" +msgstr "A usar a assinatura APK v3" #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" @@ -2012,7 +2008,7 @@ msgstr "Verificar o índice de assinatura:" #: ../fdroidserver/server.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." -msgstr "" +msgstr "A chave VirusTotal API não pode enviar ficheiros maiores que 32MB, use {url} para enviar {path}." #: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" @@ -2024,7 +2020,7 @@ msgstr "Quando configurado para índices assinados, crie apenas índices não as #: ../fdroidserver/lint.py msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." -msgstr "" +msgstr "Ao cotar todo o repositório o yamllint é desativado por predefinição. Esta opção força o yamllint independentemente." msgid "X.509 'Distiguished Name' used when generating keys" msgstr "X.509 'Distiguished Name' usado ao gerar as chaves" @@ -2039,7 +2035,7 @@ msgstr "Pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou seja:" #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "" +msgstr "Arquivo de ficheiros ZIP" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2065,7 +2061,7 @@ msgstr "opção ambígua: %s (%s?)" #: ../fdroidserver/common.py msgid "apksigner not found, it's required for signing!" -msgstr "" +msgstr "Nenhum apksigner encontrado, é necessário para assinar!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2089,9 +2085,8 @@ msgid "argument \"-\" with mode %r" msgstr "argumento \"-\" com o modo %r" #: ../fdroidserver/nightly.py -#, fuzzy msgid "attempting bare SSH connection to test deploy key:" -msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" +msgstr "tentar a conexão nua por SSH para testar a implantação da chave:" #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" @@ -2099,7 +2094,7 @@ msgstr "tentativa de conexão nua por SSH para testar a implantação da chave:" #: ../fdroidserver/common.py msgid "can not parse scrlib spec (not a string): '{}'" -msgstr "" +msgstr "não é possível analisar as especificações do scrlib (não é uma cadeia): '{}'" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2108,9 +2103,9 @@ msgid "can't open '%s': %s" msgstr "não dá pra abrir '%s': %s" #: ../fdroidserver/build.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "cannot find required srclibs: \"{path}\"" -msgstr "Não é possível encontrar um appid para {path} 1!" +msgstr "não é possível encontrar os srclibs necessários: \"{path}\"" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2138,7 +2133,7 @@ msgstr "comando para executar, seja 'init' ou 'update'" #: ../fdroidserver/__main__.py msgid "commands from plugin modules:" -msgstr "" +msgstr "comandos dos módulos de plugin:" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2161,15 +2156,15 @@ msgstr "copiando {apkfilename} para {path}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "could not parse '{path}'" -msgstr "" +msgstr "não foi possível analisar '{path}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (no ref specified): '{}'" -msgstr "" +msgstr "não foi possível analisar a especificação srclib (referência não especificada): '{}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (too many '@' signs): '{}'" -msgstr "" +msgstr "não foi possível analisar a especificação srclib (demais símbolos '@'): '{}'" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2189,7 +2184,7 @@ msgstr "logs de compilação implantados para '{path}'" #: ../fdroidserver/common.py #, python-brace-format msgid "deployed process log {path} to {dest}" -msgstr "" +msgstr "registo de processo implantado {path} a {dest}" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2199,7 +2194,7 @@ msgstr "dest = é necessário para opções como %r" #: ../fdroidserver/scanner.py msgid "executable binary, possibly code" -msgstr "" +msgstr "binário executável, possivelmente código" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2256,7 +2251,7 @@ msgstr "git svn clone falhou" #: ../fdroidserver/scanner.py msgid "gzip file archive" -msgstr "" +msgstr "arquivo de ficheiros gzip" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2426,7 +2421,7 @@ msgstr "argumentos posicionais" #: ../fdroidserver/common.py #, python-brace-format msgid "process log deploy {path} to {dest} failed!" -msgstr "" +msgstr "a implementação do registo de processo {path} a {dest} falhou!" #: ../fdroidserver/signatures.py #, python-brace-format @@ -2440,7 +2435,7 @@ msgstr "Recusado o download via conexão http insegura (use https ou especifique #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." -msgstr "" +msgstr "o ruamel.yaml não está instalado, não é possível escrever metadados." #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -2449,7 +2444,7 @@ msgstr "s3cmd sincroniza índices {path} para {url} e exclui" #: ../fdroidserver/scanner.py msgid "shared library" -msgstr "" +msgstr "biblioteca compartilhada" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2468,11 +2463,11 @@ msgstr "APK assinado, seja um caminho de ficheiro ou um URL HTTPS." #: ../fdroidserver/common.py msgid "skip deploying full build logs: log content is empty" -msgstr "Pule a implantação de logs completos de compilação: o conteúdo do log está vazio." +msgstr "pular a implantação de logs completos de compilação: o conteúdo do log está vazio" #: ../fdroidserver/common.py msgid "skip deploying full build logs: not enabled in config" -msgstr "Pule a implantação de logs de criação completos: não habilitado em configuração." +msgstr "pular a implantação de logs de criação completos: não ativado na configuração" #: ../fdroidserver/update.py #, python-brace-format @@ -2485,7 +2480,7 @@ msgstr "Nome 'srclibs' ausente e/ou '@'" #: ../fdroidserver/scanner.py msgid "static library" -msgstr "" +msgstr "biblioteca estática" #: ../fdroidserver/common.py #, python-brace-format @@ -2537,7 +2532,7 @@ msgstr "usando o Apache libcloud para sincronizar com {url}" #: ../fdroidserver/server.py msgid "virustotal.com is rate limiting, waiting to retry..." -msgstr "" +msgstr "o virustotal.com está a limitar a taxa, à espera para voltar a tentar..." #: ../fdroidserver/publish.py #, python-brace-format @@ -2605,7 +2600,7 @@ msgstr "{appid}: {field} deve ser um '{type}', mas é um '{fieldtype}'!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{build_flag} must be an integer, found: {value}" -msgstr "" +msgstr "{build_flag} deve ser um inteiro, encontrado: {value}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2615,7 +2610,7 @@ msgstr "{field} não foi terminado em {name}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{file} is blank or corrupt!" -msgstr "" +msgstr "{file} está em branco ou corrompido!" #: ../fdroidserver/update.py #, python-brace-format @@ -2625,7 +2620,7 @@ msgstr "{name} \"{path}\" não existe! Corrija-o no config.py." #: ../fdroidserver/import.py #, python-brace-format msgid "{path} already exists, ignoring import results!" -msgstr "" +msgstr "{path} já existe, a ignorar os resultados das importações!" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2645,7 +2640,7 @@ msgstr "{path} tem um tamanho de zero!" #: ../fdroidserver/server.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" -msgstr "" +msgstr "{path} mais de 200MB, enviar manualmente: {url}" #: ../fdroidserver/mirror.py #, python-brace-format @@ -2653,9 +2648,9 @@ msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{url} does not start with \"http\"!" -msgstr "{url} não termina com \"fdroid\", verifique o caminho na URL!" +msgstr "{url} não começa com \"http\"!" #: ../fdroidserver/build.py msgid "{} build failed" From b1bf7d3062dc6966524b7f7efddc9ae9241b9736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sat, 17 Oct 2020 07:19:34 +0200 Subject: [PATCH 0567/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l=20(nb=5FNO)=20by=20Allan=20Nordh=C3=B8y=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 59.8% (338 of 565 strings) Co-authored-by: Allan Nordhøy Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/nb_NO/ Translation: F-Droid/F-Droid Server --- locale/nb_NO/LC_MESSAGES/fdroidserver.po | 60 ++++++++++++------------ 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index a10512c3..55778441 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.8-74-ga380b9f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-10-01 09:00+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-10-02 19:15+0000\n" +"Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" "Language: nb_NO\n" "MIME-Version: 1.0\n" @@ -92,7 +92,7 @@ msgstr "\"{path}\" er ikke et godtatt format, konverter til: {formats}" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" er ikke en gyldig nettadresse." #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -270,11 +270,11 @@ msgstr "Advar også om formateringsproblemer, som rewritemeta -l" #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "AAR-bibliotek for Android" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "APK-fil for Android" #: ../fdroidserver/scanner.py #, fuzzy @@ -467,7 +467,7 @@ msgstr "Send inn endringer" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Argumenter i konflikt: '--verbose' og '--quiet' kan ikke angis samtidig." #: ../fdroidserver/common.py #, python-brace-format @@ -497,7 +497,7 @@ msgstr "Kunne ikke åpne APK-fil for analyse" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not parse size \"{size}\", wrong type \"{type}\"" -msgstr "" +msgstr "Kunne ikke fortolke størrelse \"{size}\", feil type \"{type}\"" #: ../fdroidserver/import.py #, fuzzy @@ -582,14 +582,14 @@ msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Slett APK-er og/eller OBB-er uten metadata fra pakkebrønnen" #: ../fdroidserver/server.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Sletter arkiv, pakkebrønnen er for stor ({size} maks. {limit})" #: ../fdroidserver/server.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Sletter historikk for git-mirror, pakkebrønnen er for stor ({size} maks. {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -1124,7 +1124,7 @@ msgstr "JAR-signatur bekreftet: {path}" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "JAR-fil for Java" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1134,7 +1134,7 @@ msgstr "Fant ingen Java JDK. Installer på vanlig plass, eller sett java_paths." #: ../fdroidserver/scanner.py msgid "Java compiled class" -msgstr "" +msgstr "Java-kompilert klasse" #: ../fdroidserver/signindex.py #, fuzzy @@ -1188,7 +1188,7 @@ msgstr "Feilaktig innskrevet serverwebroot-linje:" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." -msgstr "" +msgstr "Avspeil hele pakkebrønnen og arkivet, alle filtyper." #: ../fdroidserver/gpgsign.py msgid "Missing output directory" @@ -1354,7 +1354,7 @@ msgstr "Skriv ut JSON-rapport til fil navngitt etter APK-en." #: ../fdroidserver/scanner.py msgid "Output JSON to stdout." -msgstr "" +msgstr "Send utdata-JSON til stdout." #: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py #: ../fdroidserver/update.py ../fdroidserver/signindex.py @@ -1792,7 +1792,7 @@ msgstr "UpdateCheckMode er satt, men det ser ut til at checkupdates ikke har bli #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" -msgstr "" +msgstr "Nettadressen må starte med https:// eller http://" #: ../fdroidserver/lint.py #, fuzzy @@ -2019,12 +2019,14 @@ msgid "Using \"{path}\" for configuring s3cmd." msgstr "Bruker \"{path}\" for oppsett av s3cmd." #: ../fdroidserver/common.py +#, fuzzy msgid "Using APK Signature v2" -msgstr "" +msgstr "Bruker APK Signature v2" #: ../fdroidserver/common.py +#, fuzzy msgid "Using APK Signature v3" -msgstr "" +msgstr "Bruker APK Signature v3" #: ../fdroidserver/common.py #, fuzzy @@ -2094,7 +2096,7 @@ msgstr "Du kan bruke ANDROID_HOME til å sette stien til din SDK, f.eks:" #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "" +msgstr "ZIP-filarkiv" #: ../fdroidserver/nightly.py #, fuzzy, python-brace-format @@ -2120,7 +2122,7 @@ msgstr "tvetydig valg: %s (%s?)" #: ../fdroidserver/common.py msgid "apksigner not found, it's required for signing!" -msgstr "" +msgstr "fant ikke apksigner (som kreves for signering)." #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #, fuzzy @@ -2220,7 +2222,7 @@ msgstr "kopierer {apkfilename} inn i {path}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "could not parse '{path}'" -msgstr "" +msgstr "kunne ikke tolke'{path}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (no ref specified): '{}'" @@ -2258,7 +2260,7 @@ msgstr "dest= er påkrevd for valg som %r" #: ../fdroidserver/scanner.py msgid "executable binary, possibly code" -msgstr "" +msgstr "kjørbar binærfil, muligens kode" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2513,7 +2515,7 @@ msgstr "s3cmd synkroniserer indekser {path} til {url} og sletter" #: ../fdroidserver/scanner.py msgid "shared library" -msgstr "" +msgstr "delt bibliotek" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2552,7 +2554,7 @@ msgstr "srclibs mangler navn og/eller @" #: ../fdroidserver/scanner.py msgid "static library" -msgstr "" +msgstr "statisk bibliotek" #: ../fdroidserver/common.py #, fuzzy, python-brace-format @@ -2672,7 +2674,7 @@ msgstr "{appid}: {field} må være en '{type}', men er ikke et '{fieldtype}'!" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{build_flag} must be an integer, found: {value}" -msgstr "" +msgstr "{build_flag} må være et heltall, fant: {value}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2682,7 +2684,7 @@ msgstr "{field} ikke terminert i {name}." #: ../fdroidserver/metadata.py #, python-brace-format msgid "{file} is blank or corrupt!" -msgstr "" +msgstr "{file} er tom eller skadet!" #: ../fdroidserver/update.py #, python-brace-format @@ -2692,7 +2694,7 @@ msgstr "{name} \"{path}\" finnes ikke. Rett det i config.py." #: ../fdroidserver/import.py #, python-brace-format msgid "{path} already exists, ignoring import results!" -msgstr "" +msgstr "{path} finnes allerede, ignorerer importeringsresultater." #: ../fdroidserver/nightly.py #, fuzzy, python-brace-format @@ -2710,9 +2712,9 @@ msgid "{path} is zero size!" msgstr "{path} er null størrelse." #: ../fdroidserver/server.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" -msgstr "" +msgstr "{path} er mer enn 200MB, last opp manuelt: {url}" #: ../fdroidserver/mirror.py #, fuzzy, python-brace-format From 83eb9bf36fd66592f2af3b431e4cf43de7c8597a Mon Sep 17 00:00:00 2001 From: signz signotorez Date: Sat, 17 Oct 2020 07:19:34 +0200 Subject: [PATCH 0568/2775] Translated using Weblate: Indonesian (id) by signz signotorez Currently translated at 10.6% (60 of 565 strings) Added translation using Weblate: Indonesian (id) by signz signotorez Co-authored-by: signz signotorez Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/id/ Translation: F-Droid/F-Droid Server --- locale/id/LC_MESSAGES/fdroidserver.po | 2638 +++++++++++++++++++++++++ 1 file changed, 2638 insertions(+) create mode 100644 locale/id/LC_MESSAGES/fdroidserver.po diff --git a/locale/id/LC_MESSAGES/fdroidserver.po b/locale/id/LC_MESSAGES/fdroidserver.po new file mode 100644 index 00000000..25e30b84 --- /dev/null +++ b/locale/id/LC_MESSAGES/fdroidserver.po @@ -0,0 +1,2638 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# signz signotorez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" +"Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" +"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"Last-Translator: signz signotorez \n" +"Language-Team: Indonesian \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.3-dev\n" + +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH Public Key to be used as Deploy Key:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "" +"\n" +"{path} encoded for the DEBUG_KEYSTORE secret variable:" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "\"%s/\" has no matching metadata file!" +msgstr "\"%s/\" tidak ada kesesuaian pada berkas metadata!" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "\"{apkfilename}\" sudah terpasang pada {dev}." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains outdated {name} ({version})" +msgstr "\"{path}\" berisi {name}({version}) kadaluarsa" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains recent {name} ({version})" +msgstr "\"{path}\" berisi {name}({version}) sekarang" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "\"{path}\" exists but s3cmd is not installed!" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "\"{path}\" format berkas tidak didukung (gunakan: metadata/*.yml)" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "\"{path}\" is not an accepted format, convert to: {formats}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "\"{url}\" URL tudak valid!" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%(option)s option requires %(number)d argument" +msgid_plural "%(option)s option requires %(number)d arguments" +msgstr[0] "opsi %(option)s memerlukan argumen sebanyak %(number)d" + +#: ../fdroidserver/mirror.py +#, python-format +msgid "%(prog)s [options] url" +msgstr "%(prog)s [opsi] url" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%(prog)s: error: %(message)s\n" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "%d problems found" +msgstr "%d terdapat masalah" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "%prog [options]" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%r is not callable" +msgstr "%r tidak bisa dipanggil" + +#: ../fdroidserver/lint.py +#, python-format +msgid "%s is not an accepted build field" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%s option does not take a value" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keypass' not found in config.py!" +msgstr "'keypass' tidak ditemukan dalam config.py!" + +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystore' not found in config.py!" +msgstr "'keystore' tidak ditemukan dalam config.py!" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystorepass' not found in config.py!" +msgstr "'keystorepass' tidak ditemukan dalam config.py!" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'repo_keyalias' not found in config.py!" +msgstr "'repo_keyalias' tidak ditemukan dalam config.py!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "'required' is an invalid argument for positionals" +msgstr "" + +#: ../fdroidserver/common.py +msgid "'sdk_path' not set in 'config.py'!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "'{apkfilename}' is already installed on {dev}." +msgstr "'{apkfilename}' sudah terpasang di {dev}." + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{path}' failed to execute!" +msgstr "'{path}' gagal dieksekusi!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" +msgstr "'{value}' tidak valid pada {field} dalam {appid}. Pakem regex: {pattern}" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "...checkupdate failed for {appid} : {error}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid ".__call__() not defined" +msgstr ".__call__() tidak didefinisikan" + +#: ../fdroidserver/metadata.py +msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." +msgstr ".fdroid.txt tudak didukung! Konfersi ke .fdroid.yml atau .fdroid.json." + +#: ../fdroidserver/lint.py +msgid "/issues is missing" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "A URL is required as an argument!" +msgstr "URL diperlukan sebagai argumen!" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Add PGP signatures using GnuPG for packages in repo" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Add a new application from its source code" +msgstr "Tambah aplikasi baru dari kode sumbernya" + +#: ../fdroidserver/update.py +msgid "Add a repo signing key to an unsigned repo" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Add skeleton metadata files for APKs that are missing them" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Adding new repo for only {name}" +msgstr "Menambahkan repo baru hanya untuk {name}" + +#: ../fdroidserver/init.py +msgid "Alias of the repo signing key in the keystore" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Allows a different revision (or git branch) to be specified for the initial import" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Also mirror the full archive section" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Also warn about formatting issues, like rewritemeta -l" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + +#: ../fdroidserver/common.py ../fdroidserver/build.py +#, python-brace-format +msgid "Android SDK '{path}' does not have '{dirname}' installed!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Android SDK not found!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' is not a directory!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android build-tools path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "AndroidManifest.xml has no date" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "App is in '{repo}' but has a link to {url}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Appending .git is not necessary" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Archiving {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in srclib '{srclib}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Build a package from source" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build all applications available" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Build generated by `fdroid import` - remove disable line once ready" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Build metadata git repo has uncommited changes!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build only the latest version of each package" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "Built repo based in \"%s\" with this config:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Can't build due to {} error while scanning" +msgid_plural "Can't build due to {} errors while scanning" +msgstr[0] "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find a packageName for {path}!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot find an appid for {path}!" +msgstr "" + +#: ../fdroidserver/vmtools.py +#, python-brace-format +msgid "Cannot read \"{path}\"!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot resolve app id {appid}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Cannot use --list and --to at the same time" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Categories '%s' is not valid" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Categories are not set" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Check for updates to applications" +msgstr "Periksa pembaruan pada aplikasi" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean after all scans have finished" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean before the scans start and rebuild the container" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean up all containers and then exit" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Clean update - don't uses caches, reprocess all APKs" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Comma separated list of categories." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +#, c-format, python-format +msgid "Command '%s' not recognised.\n" +msgstr "Perintah '%s' tidak dikenal.\n" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes" +msgstr "" + +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not find '{command}' on your system" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not find {path} to remove it" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Could not open apk file for analysis" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/import.py +msgid "Couldn't find latest version code" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/import.py +msgid "Couldn't find latest version name" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find package ID" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Cowardily refusing to overwrite existing signing key setup!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create a repo signing key in a keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create skeleton metadata files that are missing" +msgstr "Membuat kerangka berkas metadata yang hilang" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Created new container \"{name}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Creating log directory" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating new S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Creating output directory" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Creating signed index with this key (SHA256):" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/verify.py +#: ../fdroidserver/publish.py +msgid "Creating temporary directory" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Creating unsigned index in preparation for signing" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "DEBUG_KEYSTORE is not set or the value is incomplete" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Delete APKs and/or OBBs without metadata from the repo" +msgstr "Hapus APK dan/atau OBB tanpa metada dari repo" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Deleting unknown file: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description '%s' is just the app's summary" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Description has a duplicate line" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description has a list (%s) but it isn't bulleted (*) nor numbered (#)" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Description of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not deploy the new files to the repo" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Do not include \"{path}\" in URL!" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Do not prompt for Android SDK path, just fail" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not remove the private keys generated from the keystore" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't create a source tarball, useful when testing a build" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Don't do anything logs-related" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't refresh the repository, useful when testing a build with no internet connection" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/upload.py +msgid "Don't use rsync checksums" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Download complete mirrors of small repos" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Download logs we don't have" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Downloading the repository already failed once, not trying again." +msgstr "" + +#: ../fdroidserver/verify.py +#, python-brace-format +msgid "Downloading {url} failed. {error}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Duplicate build recipe found for versionCode {versionCode} in {linedesc}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Duplicate link in '{field}': {url}" +msgstr "" + +#: ../fdroid +msgid "Dynamically scan APKs post build" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "" +"ERROR: this command should never be used to mirror f-droid.org!\n" +"A full mirror of f-droid.org requires more than 200GB." +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "ERROR: unsupported CI type, patches welcome!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Empty build flag at {linedesc}" +msgstr "" + +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"Enter the path to the Android SDK (%s) here:\n" +"> " +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/upload.py +#, python-format +msgid "Error while attempting to publish log: %s" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py +msgid "Error while getting repo address" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Extract signatures from APKs" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Failed fetching signatures for '{apkfilename}': {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed reading {path}: {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed resizing {path}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Failed to align application" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Failed to create S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to get APK manifest information" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, deleting {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, skipping {path}" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Failed to install '{apkfilename}' on {dev}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/common.py +msgid "Failed to sign application" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to zipalign application" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Fetched buildserverid from VM: {buildserverid}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py +#: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "Finished" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID flag" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Forbidden HTML tags" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Force halting build after {0} sec timeout!" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Found invalid appids in arguments" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Found invalid versionCodes for some apps" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Found multiple metadata files for {appid}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found multiple signing certificates for repository." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found multiple signing certificates in {path}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found no signing certificates for repository." +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Found non-file at %s" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Generated skeleton metadata for {appid}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git checkout of '%s' failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git clean failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git fetch failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git remote set-head failed" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git reset failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule sync failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule update failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "HTTPS must be used with Subversion URLs!" +msgstr "" + +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Ignoring package without metadata: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Ignoring stale cache data for {apkfilename}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Ignoring {ext} file at '{path}'" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Include APKs that are signed with disabled algorithms like MD5" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Initialising submodules" +msgstr "" + +#: ../fdroidserver/install.py +msgid "Install all signed applications available" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Install built packages on devices" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s…" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}…" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Interact with the repo HTTP server" +msgstr "Interaksi dengan server repo HTTP" + +#: ../fdroidserver/update.py +msgid "Invalid APK" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid VercodeOperation: {field}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid boolean '%s'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build flag at {line} in {linedesc}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build format: {value} in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid bulleted list" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid metadata in %s:%d" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Invalid metadata in: " +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Invalid name for published file: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid package name {0}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid redirect to non-HTTPS: {before} -> {after} " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature failed to verify: {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature verified: {path}" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#: ../fdroidserver/mirror.py +msgid "Java JDK not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Java jarsigner not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Javascript in HTML src attributes" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Keystore for signing key:\t" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the LiberapayID flag" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "List files that would be reformatted" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Locale included in f-droid.org URL" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Make the build stop on exceptions" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Malformed repository mirrors." +msgstr "" + +#: ../fdroidserver/server.py +msgid "Malformed serverwebroot line:" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + +#: ../fdroidserver/gpgsign.py +msgid "Missing output directory" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Name '%s' is just the auto name - remove it" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No 'config.py' found, using defaults." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No Android SDK found!" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No android or kivy project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No attached devices found" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "No commit specified for {versionName} in {linedesc}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "No fingerprint in URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No git submodules available" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py +msgid "No information found." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is Free Software" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is for Android" +msgstr "" + +#: ../fdroidserver/server.py +msgid "No option set! Edit your config.py to set at least one of these:" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No packages specified" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "No signed apk available for %s" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No signed output directory - nothing to do" +msgstr "" + +#: ../fdroidserver/update.py ../fdroidserver/common.py +#, python-brace-format +msgid "No signing certificates found in {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "No such package: %s" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No such versionCode {versionCode} for app {appid}" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +msgid "No unsigned directory - nothing to do" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Nothing to do" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Nothing to do for {appid}." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Now set these in config.py:" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "OBB file has newer versionCode({integer}) than any APK:" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB filename must start with \"main.\" or \"patch.\":" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB's packagename does not match a supported APK:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Old APK signature failed to verify: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Old, deprecated name for fdroid deploy" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Only PNG and JPEG are supported for graphics, found: {path}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only print differences with the Play Store" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only process apps with auto-updates" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Options" +msgstr "Opsi" + +#: ../fdroidserver/verify.py +msgid "Output JSON report to file named after APK." +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Overall license of the project." +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Override path for repo APKs (default: ./repo)" +msgstr "" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" +msgstr "" + +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Parsing manifest at '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Password required with username" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Path to main Android project subdirectory, if not in root." +msgstr "" + +msgid "Path to main android project subdirectory, if not in root." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Path to the git repo to use as the log" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the keystore for the repo signing key" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Prepare Drozer to run a scan" +msgstr "" + +msgid "Prepare drozer to run a scan" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Print the secret variable to the terminal for easy copy/paste" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Problem with description of {appid}: {error}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Problem with xml at '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Process auto-updates" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#, python-brace-format +msgid "Processing {apkfilename}" +msgstr "" + +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#, python-brace-format +msgid "Processing {appid}" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable XML/JSON for index files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable index.xml" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Project URL to import from." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Punctuation should be avoided" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Push the log to this git remote repository" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing binary transparency log to {url}" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing to {url}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Quickly start a new repository" +msgstr "Mulai repositori baru secepatnya" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Read all the metadata files and exit" +msgstr "Baca semuanberkas metadata dan keluar" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading '{config_file}'" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading minSdkVersion failed: \"{apkfilename}\"" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Reading {apkfilename} from cache" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Removing specified files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Rename APK files that do not match package.name_123.apk" +msgstr "Ubah nama berkas APK yang tidak sesuai dengan package.nama_123.apk" + +#: ../fdroidserver/update.py +msgid "Report on build data status" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Reset and create a brand new build server, even if the existing one appears to be ok." +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Resigning {apkfilename} with provided debug.keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Resize all the icons exceeding the max pixel size and exit" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Restrict output to warnings and errors" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Rewrite all the metadata files" +msgstr "Tulis ulang semua berkas metadata" + +#: ../fdroidserver/rewritemeta.py +msgid "Rewrite to a specific format: " +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}'" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}' to '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Run on git repo that has uncommitted changes" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Run rewritemeta to fix formatting" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Running first pass with MD5 checking disabled" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Running wget in {path}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Scan only the latest version of each package" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Scan the source code of a package" +msgstr "Pindai sumber berkas paket" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:{versionCode}:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Scanner found {} problem" +msgid_plural "Scanner found {} problems" +msgstr[0] "" + +#: ../fdroidserver/common.py +msgid "Set clock to that time using:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Set open file limit to {integer}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Set up an app build for a nightly build repo" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setting open file limit failed: " +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Setting {0} sec timeout for this build" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setup an emulator, install the APK on it and perform a Drozer scan" +msgstr "" + +msgid "Setup an emulator, install the apk on it and perform a drozer scan" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Sign and place packages in the repo" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Sign indexes created using update --nosign" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Skip scanning the source code for binaries and other problems" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping '{apkfilename}' with invalid signature!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping index generation for {appid}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: disabled" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: no builds specified" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify a local folder to sync the repo to" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify an identity file to provide to SSH for rsyncing" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Specify that we're running on the build server" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Specify which debug keystore file to use." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Spew out even more information than normal" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Striping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Summary '%s' is just the app's name" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Summary of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "System clock is older than date in {path}!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "The OBB version code must come after \"{name}.\":" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "The base URL for the repo to log (default: https://f-droid.org)" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "The directory to write the mirror to" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "The file to be included in the repo (path or glob)" +msgstr "" + +#: ../fdroidserver/server.py +msgid "The only commands currently supported are 'init' and 'update'" +msgstr "" + +#: ../fdroidserver/index.py +msgid "The repository's fingerprint does not match." +msgstr "" + +#: ../fdroidserver/common.py +msgid "The repository's index could not be verified." +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "The root dir for local_copy_dir \"{path}\" does not exist!" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "There is a keyalias collision - publishing halted" +msgstr "" + +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + +#: ../fdroidserver/import.py +#, python-format +msgid "This repo already has local metadata: %s" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "URL shorteners should not be used" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "URL title is just the URL, use brackets: [URL]" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "URL {url} in Description: {error}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unexpected text on same line as {field} in {linedesc}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Unknown exception found!" +msgstr "Eksepsi tidak ditemukan!" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Unknown file '{filename}' in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Unknown metadata format: %s" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Unknown version of aapt, might cause problems: " +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary leading space" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary trailing space" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised app field '{fieldname}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unrecognised app field: " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised build flag '{build_flag}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised field '{field}' in {linedesc}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported file type \"{extension}\" for repo graphic" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported graphics file found: {path}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Unsupported metadata format, use: --to [{supported}]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated build in {name}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated continuation in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused extlib at %s" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused file at %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Update Check Name is set to the known app id - it can be removed" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update repo information for new packages" +msgstr "Perbarui informasi repo untuk paket yang baru" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update the binary transparency log for a URL" +msgstr "Perbarui log transparansi biner untuk URL" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update the stats of the repo" +msgstr "Perbarui status repo" + +#: ../fdroidserver/update.py ../fdroidserver/build.py +msgid "Update the wiki" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "UpdateCheckData has invalid URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must use HTTPS URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData not a valid URL: {url}" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Usage" +msgstr "Penggunaan" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "Usage: %s\n" +msgstr "Penggunaan: %s\n" + +#: ../fdroidserver/lint.py +msgid "Use /HEAD instead of /master to point at a file in the default branch" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use `fdroid update -c` to create it." +msgstr "" + +#: ../fdroidserver/build.py +msgid "Use build server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use date from APK instead of current time for newly added APKs" +msgstr "" + +msgid "Use date from apk instead of current time for newly added apks" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Using androguard from \"{path}\"" +msgstr "" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Using existing keystore \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using s3cmd to sync with: {url}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Valid commands are:" +msgstr "Perintah yang benar adalah:" + +#: ../fdroidserver/verify.py +msgid "Verify against locally cached copy rather than redownloading." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Verify the integrity of downloaded packages" +msgstr "Verifikasi integritas paket yang didownload" + +#: ../fdroidserver/index.py +msgid "Verifying index signature:" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Warn about possible metadata errors" +msgstr "Peringatkan mengenai kemungkinan error pada metadata" + +#: ../fdroidserver/update.py +msgid "When configured for signed indexes, create only unsigned indexes at this stage" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + +msgid "X.509 'Distiguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/init.py +msgid "X.509 'Distinguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/common.py +msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "adding IdentityFile to {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "adding to {name}: {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ambiguous option: %(option)s could match %(matches)s" +msgstr "opsi ambigu: %(option)s bisa sesuai dengan %(matches)s" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "ambiguous option: %s (%s?)" +msgstr "opsi ambigu: %s (%s?)" + +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +msgid "applicationId in the form APPID" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "applicationId to check for updates" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/dscanner.py ../fdroidserver/build.py +#: ../fdroidserver/scanner.py ../fdroidserver/install.py +msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "argument \"-\" with mode %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "attempting bare ssh connection to test deploy key:" +msgstr "" + +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "can't open '%s': %s" +msgstr "tidak bisa dibuka '%s': %s" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "cannot have multiple subparser arguments" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "cannot merge actions - two groups are named %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "cannot publish update, did you set the deploy key?" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "cloning {url}" +msgstr "" + +#: ../fdroidserver/server.py +msgid "command to execute, either 'init' or 'update'" +msgstr "" + +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "complex" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "conflicting option string: %s" +msgid_plural "conflicting option strings: %s" +msgstr[0] "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "copying {apkfilename} into {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "created {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "deleting: repo/{apkfilename}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed build logs to '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "dest= is required for options like %r" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "expected %s argument" +msgid_plural "expected %s arguments" +msgstr[0] "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at least one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at most one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected one argument" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "failed deploying build logs to '{path}'" +msgstr "" + +#: ../fdroid +msgid "fdroid [-h|--help|--version] []" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "fdroid [] [-h|--help|--version|]" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "floating-point" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force errors to be warnings, or ignore" +msgstr "paksa untuk mengingatkan adanya error, atau hiraukan" + +#: ../fdroidserver/metadata.py +msgid "force metadata errors (default) to be warnings, or to be ignored." +msgstr "" + +#: ../fdroidserver/common.py +msgid "git svn clone failed" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ignored explicit argument %r" +msgstr "" + +#: ../fdroidserver/index.py +msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "integer" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid %(type)s value: %(value)r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid choice: %(value)r (choose from %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid conflict_resolution value: %r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be an absolute path!" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be directory, not a file!" +msgstr "" + +#: ../fdroidserver/index.py +#, python-format +msgid "mirror '%s' does not end with 'fdroid'!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "mutually exclusive arguments must be optional" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "no \"icon\" in {appid}" +msgstr "" + +#: ../fdroidserver/signatures.py +msgid "no APK supplied" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "no such option: %s" +msgstr "tidak ada opsi: %s" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "no version info found!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "not allowed with argument %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "one of the arguments %s is required" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "only accepts strings, lists, and tuples" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "option %s: If you really want to install all the signed apps, use --all" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid %s value: %r" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid choice: %r (choose from %s)" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s not recognized" +msgstr "opsi -%s tidak dikenal" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s requires argument" +msgstr "opsi -%s memerlukan argumen" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s must not have an argument" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not a unique prefix" +msgstr "opsi --%s bukan prefiks unik" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not recognized" +msgstr "opsi --%s tidak dikenal" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s requires argument" +msgstr "opsi --%s memerlukan argumen" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "optional arguments" +msgstr "argumen opsional" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "overwriting existing {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "positional arguments" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "s3cmd sync indexes {path} to {url} and delete" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "show program's version number and exit" +msgstr "menampilkan nomor versi program dan keluar" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.5/optparse.py +#: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py +msgid "show this help message and exit" +msgstr "menampilkan bantuan ini dan keluar" + +#: ../fdroidserver/signatures.py +msgid "signed APK, either a file-path or HTTPS URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: log content is empty" +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: not enabled in config" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "skipping source tarball: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "srclibs missing name and/or @" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "the following arguments are required: %s" +msgstr "argumen berikut ini diperlukan: %s" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unexpected option string: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unknown parser %(parser_name)r (choices: %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unrecognized arguments: %s" +msgstr "argumen tidak dikenal: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "unsafe permissions on '{config_file}' (should be 0600)!" +msgstr "izin tidak aman pada '{config_file}' (seharusnya 0600)!" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py +msgid "usage: " +msgstr "penggunaan: " + +#: ../fdroid +msgid "usage: fdroid [-h|--help|--version] []" +msgstr "penggunaan: fdroid [-h|--help|--version] []" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "using Apache libcloud to sync with {url}" +msgstr "" + +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "{0} app, {1} key aliases" +msgid_plural "{0} apps, {1} key aliases" +msgstr[0] "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} ({appid}) has no metadata!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using package name instead." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android Package Name!" +msgstr "" + +#: ../fdroidserver/metadata.py ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Java Package Name!" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{appid} is missing {name}" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: Unknown extlib {path} in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "{appid}: no builds specified, running on current source state" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{field} not terminated in {name}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{name} \"{path}\" does not exist! Correct it in config.py." +msgstr "" + +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "{path} does not exist! Create it by running:" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} is zero size!" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{url} does not end with \"fdroid\", check the URL path!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "{} build failed" +msgid_plural "{} builds failed" +msgstr[0] "" + +#: ../fdroidserver/build.py +msgid "{} build succeeded" +msgid_plural "{} builds succeeded" +msgstr[0] "" From f198f16985f8ea81486c179cfb008a0ddbe0e3d2 Mon Sep 17 00:00:00 2001 From: Boris Timofeev Date: Sat, 17 Oct 2020 07:19:34 +0200 Subject: [PATCH 0569/2775] Translated using Weblate: Russian (ru) by Boris Timofeev Currently translated at 86.3% (488 of 565 strings) Co-authored-by: Boris Timofeev Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 57 +++++++++++++-------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index d5df27c7..ca66bcf8 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -5,20 +5,21 @@ # anonymous , 2020. # Andrey , 2020. # gardenapple , 2020. +# Boris Timofeev , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-07-08 21:41+0000\n" -"Last-Translator: gardenapple \n" +"PO-Revision-Date: 2020-10-05 12:34+0000\n" +"Last-Translator: Boris Timofeev \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/common.py msgid "" @@ -82,9 +83,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "путь \"{path}\" существует, но s3cmd клиент не установлен!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "формат пути \"{path}\" не принимается, преобразуйте в другой доступный: {formats}" +msgstr "\"{path}\" не поддерживаемый формат файла (используйте: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -94,7 +95,7 @@ msgstr "формат пути \"{path}\" не принимается, преоб #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" не действительный URL!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -278,9 +279,8 @@ msgid "Android APK file" msgstr "" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "Android SDK не обнаружена!" +msgstr "Android DEX код" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -345,7 +345,7 @@ msgstr "Ветка '{branch}' вошла в библиотеку '{srclib}' ка #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Неработающая символическая ссылка: {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -405,9 +405,9 @@ msgid "Cannot resolve app id {appid}" msgstr "Не удалось разобрать app id {appid}" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "Неправильно указан путь \"{path}\"!" +msgstr "Невозможно переписать \"{path}\"" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -467,7 +467,7 @@ msgstr "Сохранить изменения (commit)" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Противоречивые аргументы: '--verbose' и '--quiet' нельзя указывать одновременно." #: ../fdroidserver/common.py #, python-brace-format @@ -475,14 +475,12 @@ msgid "Could not find '{command}' on your system" msgstr "В вашей системе недоступна команда '{command}'" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version code" -msgstr "Не удалось найти внутреннюю версию приложения (versionCode)" +msgstr "Не удалось найти последнюю версию приложения (versionCode)" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version name" -msgstr "Не удалось найти публичную версию приложения (versionName)" +msgstr "Не удалось найти название последней версии" #: ../fdroidserver/update.py #, python-brace-format @@ -499,9 +497,8 @@ msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" #: ../fdroidserver/import.py -#, fuzzy msgid "Couldn't find Application ID" -msgstr "Не удалось найти package ID" +msgstr "Не удалось найти Application ID" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -727,9 +724,9 @@ msgid "Extract signatures from APKs" msgstr "Извлечь подписи из APK файлов" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Failed copying {path}: {error}" -msgstr "Не удалось распознать {path}: {error}" +msgstr "Не удалось скопировать {path}: {error}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -795,7 +792,7 @@ msgstr "Получены подписи для '{apkfilename}' -> '{sigdir}'" #: ../fdroidserver/update.py #, python-brace-format msgid "File disappeared while processing it: {path}" -msgstr "" +msgstr "Файл исчез во время обработки: {path}" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -827,8 +824,9 @@ msgid "Force halting build after {0} sec timeout!" msgstr "Принудительно останавливать сборку, если тайм-аут больше {0} секунд!" #: ../fdroidserver/scanner.py +#, fuzzy msgid "Force scan of disabled apps and builds." -msgstr "" +msgstr "Принудительное сканирование отключенных приложений и сборок." #: ../fdroidserver/update.py #, python-brace-format @@ -836,9 +834,9 @@ msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "В \"{path}\" обнаружены изображения без метаданных для приложения \"{name}\"!" #: ../fdroidserver/update.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "Found bad funding file \"{path}\" for \"{name}\":" -msgstr "" +msgstr "Обнаружен неверный файл финансирования \"{path}\" для \"{name}\":" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" @@ -880,7 +878,7 @@ msgstr "Это не похоже на файл: %s" #: ../fdroidserver/server.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "копирование {apkfilename} в {path}" +msgstr "Найдено {apkfilename} в {url}" #: ../fdroidserver/update.py #, python-brace-format @@ -907,7 +905,7 @@ msgstr "Не удалось настроить HEAD для удаленного #: ../fdroidserver/common.py #, fuzzy, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Не удалось настроить HEAD для удаленного репозитория (git remote set-head)" +msgstr "Не удалось настроить HEAD для удаленного репозитория (git remote set-head): \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -926,13 +924,14 @@ msgid "HTTPS must be used with Subversion URLs!" msgstr "URL-адреса для Subversion должны начинаться с HTTPS!" #: ../fdroidserver/server.py +#, fuzzy msgid "If a git mirror gets to big, allow the archive to be deleted" -msgstr "" +msgstr "Если git-зеркало станет большим, разрешите удалить архив." #: ../fdroidserver/server.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Если эта загрузка не удалась, попробуйте вручную загрузить в {url}." #: ../fdroidserver/metadata.py #, python-brace-format From 092f4416474b1632c8f48cf57c5c63e1f8e68d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Marcelo=20Alvarenga?= Date: Sat, 17 Oct 2020 07:19:35 +0200 Subject: [PATCH 0570/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Portu?= =?UTF-8?q?guese=20(Brazil)=20(pt=5FBR)=20by=20Andr=C3=A9=20Marcelo=20Alva?= =?UTF-8?q?renga=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (565 of 565 strings) Co-authored-by: André Marcelo Alvarenga Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translation: F-Droid/F-Droid Server --- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 8a483606..b5e3879c 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-10-03 14:48+0000\n" -"Last-Translator: ssantos \n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"Last-Translator: André Marcelo Alvarenga \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -2037,7 +2037,7 @@ msgstr "Você pode usar ANDROID_HOME para definir o caminho para o seu SDK, ou s #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "Arquivo de ficheiros ZIP" +msgstr "Arquivo ZIP" #: ../fdroidserver/nightly.py #, python-brace-format From f7ceb2b989181e904b8b02c75836654955c34da9 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Sat, 17 Oct 2020 07:19:35 +0200 Subject: [PATCH 0571/2775] Translated using Weblate: Persian (fa) by Mostafa Ahangarha Currently translated at 4.0% (23 of 565 strings) Co-authored-by: Mostafa Ahangarha Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fa/ Translation: F-Droid/F-Droid Server --- locale/fa/LC_MESSAGES/fdroidserver.po | 51 +++++++++++++-------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/locale/fa/LC_MESSAGES/fdroidserver.po b/locale/fa/LC_MESSAGES/fdroidserver.po index ef1cb43f..1e6025e3 100644 --- a/locale/fa/LC_MESSAGES/fdroidserver.po +++ b/locale/fa/LC_MESSAGES/fdroidserver.po @@ -1,22 +1,21 @@ # 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 , YEAR. -# +# Mostafa Ahangarha , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2018-12-10 16:46+0000\n" -"Last-Translator: frowzy \n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"Last-Translator: Mostafa Ahangarha \n" "Language-Team: Persian \n" "Language: fa\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 3.4-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/common.py msgid "" @@ -104,7 +103,7 @@ msgstr "" #: /usr/lib/python3.7/argparse.py #, python-format msgid "%(prog)s: error: %(message)s\n" -msgstr "" +msgstr "%(prog)s: خطا: %(message)s\n" #: ../fdroidserver/scanner.py #, python-format @@ -120,7 +119,7 @@ msgstr "کاوش کردن" #: /usr/lib/python3.7/argparse.py #, python-format msgid "%r is not callable" -msgstr "" +msgstr "‏%r قابل صدا زدن نیست" #: ../fdroidserver/lint.py #, python-format @@ -208,7 +207,7 @@ msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid ".__call__() not defined" -msgstr "" +msgstr ".__call__() تعریف نشده است" #: ../fdroidserver/metadata.py msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." @@ -228,7 +227,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "Add a new application from its source code" -msgstr "" +msgstr "برنامه جدیدی را از کد منبع‌اش اضافه می‌کند" #: ../fdroidserver/update.py msgid "Add a repo signing key to an unsigned repo" @@ -338,7 +337,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" -msgstr "" +msgstr "بسته‌ای را از کد منبع می‌سازد" #: ../fdroidserver/build.py msgid "Build all applications available" @@ -417,7 +416,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "Check for updates to applications" -msgstr "" +msgstr "به‌روزرسانی‌ها برای برنامه‌ها را بررسی می‌کند" #: ../fdroidserver/update.py #, python-brace-format @@ -447,7 +446,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" -msgstr "" +msgstr "فرمان «%s» شناسایی نشد.\n" #: ../fdroidserver/checkupdates.py msgid "Commit changes" @@ -512,7 +511,7 @@ msgstr "" #: ../fdroidserver/update.py msgid "Create skeleton metadata files that are missing" -msgstr "" +msgstr "پرونده‌های فراداده اسکلت را که موجود نیستند می‌سازد" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -561,7 +560,7 @@ msgstr "" #: ../fdroidserver/update.py msgid "Delete APKs and/or OBBs without metadata from the repo" -msgstr "" +msgstr "پرونده‌های APK و یا OBB فاقد فراداده را از مخزن پاک می‌کند" #: ../fdroidserver/server.py #, python-brace-format @@ -1754,7 +1753,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "Unknown exception found!" -msgstr "" +msgstr "خطای ناشناخته‌ای یافت شد!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname #: ../fdroidserver/lint.py @@ -1913,13 +1912,13 @@ msgstr "" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" -msgstr "" +msgstr "مصرف" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format msgid "Usage: %s\n" -msgstr "" +msgstr "مصرف: %s\n" #: ../fdroidserver/lint.py msgid "Use /HEAD instead of /master to point at a file in the default branch" @@ -1974,7 +1973,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" -msgstr "" +msgstr "فرمان‌های معتبر عبارت‌اند از:" #: ../fdroidserver/verify.py msgid "Verify against locally cached copy rather than redownloading." @@ -2354,13 +2353,13 @@ msgstr "" #: /usr/lib/python3.7/getopt.py #, python-format msgid "option -%s not recognized" -msgstr "" +msgstr "گزینه -%s شناسایی نشد" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py #, python-format msgid "option -%s requires argument" -msgstr "" +msgstr "گزینه -%s نیازمند آرگومان است" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py @@ -2378,7 +2377,7 @@ msgstr "" #: /usr/lib/python3.7/getopt.py #, python-format msgid "option --%s not recognized" -msgstr "" +msgstr "گزینه --%s شناسایی نشد" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py @@ -2389,7 +2388,7 @@ msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py msgid "optional arguments" -msgstr "" +msgstr "آرگومان‌های اختیاری" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2432,13 +2431,13 @@ msgstr "" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "show program's version number and exit" -msgstr "" +msgstr "نسخه برنامه را نمایش داده و خارج می‌شود" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.5/optparse.py #: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py msgid "show this help message and exit" -msgstr "" +msgstr "این پیام راهنما را نمایش داده و خارج می‌شود" #: ../fdroidserver/signatures.py msgid "signed APK, either a file-path or HTTPS URL." @@ -2502,11 +2501,11 @@ msgstr "" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid #: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " -msgstr "" +msgstr "مصرف: " #: ../fdroid msgid "usage: fdroid [-h|--help|--version] []" -msgstr "" +msgstr "استفاده: fdroid [-h|--help|--version] []" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format From 9db20b473498678e8bc025b6ce7f9538c594681f Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sat, 17 Oct 2020 07:19:36 +0200 Subject: [PATCH 0572/2775] Translated using Weblate: Kabyle (kab) by Kahina Messaoudi Currently translated at 9.7% (55 of 565 strings) Co-authored-by: Kahina Messaoudi Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/kab/ Translation: F-Droid/F-Droid Server --- locale/kab/LC_MESSAGES/fdroidserver.po | 77 +++++++++++++------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/locale/kab/LC_MESSAGES/fdroidserver.po b/locale/kab/LC_MESSAGES/fdroidserver.po index ca1e28e2..dad9f5f5 100644 --- a/locale/kab/LC_MESSAGES/fdroidserver.po +++ b/locale/kab/LC_MESSAGES/fdroidserver.po @@ -1,13 +1,14 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # Hans-Christoph Steiner , 2020. +# Kahina Messaoudi , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-10-01 09:00+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"Last-Translator: Kahina Messaoudi \n" "Language-Team: Kabyle \n" "Language: kab\n" "MIME-Version: 1.0\n" @@ -83,7 +84,7 @@ msgstr "" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" mačči d aseɣwen URL ameɣtu!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -107,7 +108,7 @@ msgstr "" #: ../fdroidserver/scanner.py #, python-format msgid "%d problems found" -msgstr "" +msgstr "%d n wuguren ttwafen" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -149,7 +150,7 @@ msgstr "'keystorepass' ulac-it di config.py!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'repo_keyalias' not found in config.py!" -msgstr "'repo_keyalias' ulac-it di config.py!" +msgstr "'repo_keyalias' ulac-it deg config.py!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -383,7 +384,7 @@ msgstr "" #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" -msgstr "" +msgstr "ur izmir ara ad iɣer \"{path}\"!" #: ../fdroidserver/metadata.py #, python-brace-format @@ -440,7 +441,7 @@ msgstr "" #: ../fdroidserver/import.py msgid "Comma separated list of categories." -msgstr "" +msgstr "Tabdart n taggayin i yebḍan s ticcert." #: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format @@ -449,7 +450,7 @@ msgstr "" #: ../fdroidserver/checkupdates.py msgid "Commit changes" -msgstr "" +msgstr "Azen ibeddilen" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." @@ -458,7 +459,7 @@ msgstr "" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" -msgstr "" +msgstr "D awezɣi tifin n '{command}' deg unagraw-ik.im" #: ../fdroidserver/import.py msgid "Could not find latest version code" @@ -466,7 +467,7 @@ msgstr "" #: ../fdroidserver/import.py msgid "Could not find latest version name" -msgstr "" +msgstr "Ur izmir ara ad d-yaf isem n lqem aneggaru" #: ../fdroidserver/update.py #, python-brace-format @@ -475,7 +476,7 @@ msgstr "" #: ../fdroidserver/update.py msgid "Could not open apk file for analysis" -msgstr "" +msgstr "Ur yezmir ara a d-ildi afaylu apk i tesleḍt" #: ../fdroidserver/common.py #, python-brace-format @@ -515,7 +516,7 @@ msgstr "" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" -msgstr "" +msgstr "Anagbar amaynut yettwarnan \"{name}\"" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -703,7 +704,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "Extract signatures from APKs" -msgstr "" +msgstr "Izmal-nniḍen sɣur APKs" #: ../fdroidserver/update.py #, python-brace-format @@ -727,7 +728,7 @@ msgstr "" #: ../fdroidserver/publish.py msgid "Failed to align application" -msgstr "" +msgstr "Areyyec n usnas ur yeddi ara" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -755,7 +756,7 @@ msgstr "" #: ../fdroidserver/publish.py ../fdroidserver/common.py msgid "Failed to sign application" -msgstr "" +msgstr "Azmal n usnas ur yeddi ara" #: ../fdroidserver/common.py msgid "Failed to zipalign application" @@ -793,7 +794,7 @@ msgstr "" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" -msgstr "" +msgstr "Ticraḍ HTML yettwagedlen" #: ../fdroidserver/build.py msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." @@ -872,7 +873,7 @@ msgstr "" #: ../fdroidserver/common.py msgid "Git clean failed" -msgstr "" +msgstr "Asfaḍ Git yecceḍ" #: ../fdroidserver/common.py msgid "Git fetch failed" @@ -982,7 +983,7 @@ msgstr "" #: ../fdroidserver/install.py #, python-brace-format msgid "Installing '{apkfilename}' on {dev}…" -msgstr "" +msgstr "Asebded n '{apkfilename}' deg {dev}…" #: ../fdroid ../fdroidserver/__main__.py msgid "Interact with the repo HTTP server" @@ -1014,7 +1015,7 @@ msgstr "" #: ../fdroidserver/lint.py msgid "Invalid bulleted list" -msgstr "" +msgstr "Tabdart s tneqqiḍin tarameɣtut" #: ../fdroidserver/lint.py #, python-format @@ -1081,7 +1082,7 @@ msgstr "" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "Afaylu Java JAR" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1148,7 +1149,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-format msgid "Name '%s' is just the auto name - remove it" -msgstr "" +msgstr "Isem '%s' d isem awurman kan - kkes-it" #: ../fdroidserver/common.py msgid "No 'config.py' found, using defaults." @@ -1292,7 +1293,7 @@ msgstr "" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Options" -msgstr "Iɣewwaṛen" +msgstr "Iɣewwaren" #: ../fdroidserver/verify.py msgid "Output JSON report to file named after APK." @@ -1368,7 +1369,7 @@ msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Problem with description of {appid}: {error}" -msgstr "" +msgstr "Ugur deg uglam n {appid}: {error}" #: ../fdroidserver/common.py #, python-brace-format @@ -1387,7 +1388,7 @@ msgstr "" #: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py #, python-brace-format msgid "Processing {appid}" -msgstr "" +msgstr "Asesfer n {appid}" #: ../fdroidserver/update.py msgid "Produce human-readable XML/JSON for index files" @@ -1417,7 +1418,7 @@ msgstr "" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" -msgstr "" +msgstr "Adegger ɣer {url}" #: ../fdroid ../fdroidserver/__main__.py msgid "Quickly start a new repository" @@ -1556,7 +1557,7 @@ msgstr "" #: ../fdroidserver/build.py #, python-brace-format msgid "Set open file limit to {integer}" -msgstr "" +msgstr "Sbadu talast n ufaylu yeldin ɣer {integer}" #: ../fdroid ../fdroidserver/__main__.py msgid "Set up an app build for a nightly build repo" @@ -1768,7 +1769,7 @@ msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Unknown metadata format: {path}" -msgstr "" +msgstr "Amasal n yidfersefka d arussim: {path}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1851,7 +1852,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-format msgid "Unused file at %s" -msgstr "" +msgstr "Afaylu ur nettwaseqdec ara deg %s" #: ../fdroidserver/scanner.py #, python-format @@ -1963,7 +1964,7 @@ msgstr "" #: ../fdroidserver/init.py #, python-brace-format msgid "Using existing keystore \"{path}\"" -msgstr "" +msgstr "Aseqdec n tqeffalt n uḥraz \"{path}\"" #: ../fdroidserver/server.py ../fdroidserver/upload.py #, python-brace-format @@ -1972,7 +1973,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" -msgstr "" +msgstr "Tiludna timeɣta d ti:" #: ../fdroidserver/verify.py msgid "Verify against locally cached copy rather than redownloading." @@ -1980,7 +1981,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "Verify the integrity of downloaded packages" -msgstr "" +msgstr "Senqed timmad n yikemmusen yettwasadren" #: ../fdroidserver/index.py msgid "Verifying index signature:" @@ -2021,12 +2022,12 @@ msgstr "" #: ../fdroidserver/nightly.py #, python-brace-format msgid "adding IdentityFile to {path}" -msgstr "" +msgstr "timerniwt n ufaylu n tmagit ɣer {path}" #: ../fdroidserver/update.py #, python-brace-format msgid "adding to {name}: {path}" -msgstr "" +msgstr "timerniwt ɣer {name}: {path}" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2211,7 +2212,7 @@ msgstr "" #: ../fdroid ../fdroidserver/__main__.py msgid "fdroid [] [-h|--help|--version|]" -msgstr "" +msgstr "fdroid [] [-h|--tallelt|--lqem|]" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2299,7 +2300,7 @@ msgstr "" #: ../fdroidserver/mirror.py #, python-brace-format msgid "no \"icon\" in {appid}" -msgstr "" +msgstr "ulac \"tignit\" deg {appid}" #: ../fdroidserver/signatures.py msgid "no APK supplied" @@ -2364,7 +2365,7 @@ msgstr "" #: /usr/lib/python3.7/getopt.py #, python-format msgid "option --%s must not have an argument" -msgstr "" +msgstr "aɣewwar --%s yessefk ad yesεu tiɣiret" #: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py #: /usr/lib/python3.7/getopt.py @@ -2461,7 +2462,7 @@ msgstr "" #: ../fdroidserver/scanner.py msgid "static library" -msgstr "" +msgstr "tamkerḍit n tdaddanin" #: ../fdroidserver/common.py #, python-brace-format @@ -2606,7 +2607,7 @@ msgstr "" #: ../fdroidserver/nightly.py #, python-brace-format msgid "{path} does not exist! Create it by running:" -msgstr "" +msgstr "{path} ur yelli ara! Rnu-t s uselkem:" #: ../fdroidserver/update.py #, python-brace-format From aede496fbe305e6130d7b10c878b2c19614c32c9 Mon Sep 17 00:00:00 2001 From: Coucouf Date: Sat, 17 Oct 2020 07:19:36 +0200 Subject: [PATCH 0573/2775] Translated using Weblate: French (fr) by Coucouf Currently translated at 70.0% (396 of 565 strings) Co-authored-by: Coucouf Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index b63ed756..7f36d476 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -12,13 +12,14 @@ # Yannick A. , 2020. # Renaud Perrai , 2020. # rational , 2020. +# Coucouf , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-10-01 09:00+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"Last-Translator: Coucouf \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -36,6 +37,12 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Ceci est un dépôt d’apps à utiliser avec FDroid. Les applications publiées\n" +" dans ce dépôt sont soit les binaires officiels construits par les développeurs\n" +" de ces applications, soit des binaires construits par f-droid.org à partir des\n" +" sources en utilisant les outils disponibles sur https://gitlab.com/fdroid.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -351,7 +358,7 @@ msgstr "Branche « {branch} » utilisée comme commit dans srclib « {srclib} » #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Lien symbolique cassé : {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -732,9 +739,9 @@ msgid "Extract signatures from APKs" msgstr "Extraction des signatures à partir des APKs" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Failed copying {path}: {error}" -msgstr "Erreur de lecture {path} : {error}" +msgstr "Erreur durant la copie de {path} : {error}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -800,7 +807,7 @@ msgstr "Récupération de la signature pour '{apkfilename}' -> '{sigdir}'" #: ../fdroidserver/update.py #, python-brace-format msgid "File disappeared while processing it: {path}" -msgstr "" +msgstr "Le fichier a été supprimé au cours du traitement : {path}" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -814,9 +821,8 @@ msgid "Flattr donation methods belong in the FlattrID flag" msgstr "La méthode de donnation Flattr reviens au flag FlatttrID" #: ../fdroidserver/lint.py -#, fuzzy msgid "Flattr donation methods belong in the FlattrID: field" -msgstr "La méthode de donnation Flattr reviens au flag FlatttrID" +msgstr "Les informations de dons via Flattr doivent être renseignées dans le champ FlattrID:" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" From f477fc88bd4aadd6a127f8b39596322b5c225894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20H=C3=B4?= Date: Sat, 17 Oct 2020 07:19:37 +0200 Subject: [PATCH 0574/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Frenc?= =?UTF-8?q?h=20(fr)=20by=20Alexandre=20H=C3=B4=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 70.0% (396 of 565 strings) Co-authored-by: Alexandre Hô Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 7f36d476..83469ee1 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -13,13 +13,14 @@ # Renaud Perrai , 2020. # rational , 2020. # Coucouf , 2020. +# Alexandre Hô , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" -"Last-Translator: Coucouf \n" +"Last-Translator: Alexandre Hô \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -839,7 +840,7 @@ msgstr "Arrêt forcer de la construction après {0} secondes de délai d'attente #: ../fdroidserver/scanner.py msgid "Force scan of disabled apps and builds." -msgstr "" +msgstr "Forcer le scan d'applications et versions désactivées." #: ../fdroidserver/update.py #, python-brace-format @@ -975,7 +976,7 @@ msgstr "Inclure des fichiers APK signés avec algorithmes désactivés comme MD5 #: ../fdroidserver/mirror.py msgid "Include the PGP signature .asc files in the mirror" -msgstr "" +msgstr "Inclure au miroir les fichiers .asc de signature PGP" #: ../fdroidserver/mirror.py msgid "Include the build logs in the mirror" @@ -983,7 +984,7 @@ msgstr "" #: ../fdroidserver/mirror.py msgid "Include the source tarballs in the mirror" -msgstr "" +msgstr "Inclure au miroir les tarballs de source" #: ../fdroidserver/common.py msgid "Initialising submodules" From 742b4c4f466a2f10df27351a50c485902a410dc5 Mon Sep 17 00:00:00 2001 From: Yldun Date: Sat, 17 Oct 2020 07:19:37 +0200 Subject: [PATCH 0575/2775] Translated using Weblate: French (fr) by Yldun Currently translated at 70.0% (396 of 565 strings) Co-authored-by: Yldun Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 79 +++++++++++++-------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 83469ee1..92c5395e 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -14,13 +14,14 @@ # rational , 2020. # Coucouf , 2020. # Alexandre Hô , 2020. +# Yldun , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" -"Last-Translator: Alexandre Hô \n" +"Last-Translator: Yldun \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -54,13 +55,12 @@ msgstr "" "Clé Publique SSH à utiliser comme Clé de Déploiement :" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" msgstr "" "\n" -"Clé Publique SSH à utiliser comme Clé de Déploiement :" +"Clé publique SSH à utiliser comme clé de déploiement :" #: ../fdroidserver/nightly.py #, python-brace-format @@ -77,9 +77,9 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" n'a pas de fichier de métadonnées correspondant !" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." -msgstr "'{apkfilename}' est déjà installé sur '{dev}'." +msgstr "«{apkfilename}» est déjà installé sur {dev}." #: ../fdroidserver/update.py #, python-brace-format @@ -97,9 +97,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe mais s3cmd n'est pas installé !" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" n'est pas un format autorisé, convertir en : {formats}" +msgstr "\"{path}\" n'est pas un format autorisé (utiliser : metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -109,7 +109,7 @@ msgstr "\"{path}\" n'est pas un format autorisé, convertir en : {formats}" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" n'est pas une URL valide !" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -163,7 +163,7 @@ msgstr "'keypass' non trouvé dans config.py !" #: ../fdroidserver/common.py msgid "'keystore' is NONE and 'smartcardoptions' is blank!" -msgstr "" +msgstr "'keystore' n'est pas utilisé et 'smartcardoptions' est vide !" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" @@ -285,16 +285,15 @@ msgstr "Alerter aussi à propos des problèmes de formatage, comme rewritemeta - #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "Bibliothèque Android AAR" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Fichier Android APK" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "Aucun SDK Android trouvée !" +msgstr "Code Android DEX" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -418,9 +417,9 @@ msgid "Cannot resolve app id {appid}" msgstr "Impossible de résoudre l'identifiant de l'application {appid}" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "Impossible de lire \"{path}\" !" +msgstr "Impossible d'écrire sur \"{path}\"" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -480,7 +479,7 @@ msgstr "Sauvegarder les changements (commit)" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Conflit d'arguments : '--verbose' et '--quiet' ne peuvent être choisis en même temps." #: ../fdroidserver/common.py #, python-brace-format @@ -488,12 +487,10 @@ msgid "Could not find '{command}' on your system" msgstr "Impossible de trouver « {command} » sur votre système" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version code" msgstr "Impossible de trouver la dernière version du code" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version name" msgstr "Impossible de trouver le nom de la dernière version" @@ -509,12 +506,11 @@ msgstr "Impossible d'ouvrir le fichier apk pour analyse" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not parse size \"{size}\", wrong type \"{type}\"" -msgstr "" +msgstr "Impossible de récupérer la taille \"{size}\", mauvais type \"{type}\"" #: ../fdroidserver/import.py -#, fuzzy msgid "Couldn't find Application ID" -msgstr "Impossible de trouver l'ID du paquet" +msgstr "Impossible de trouver l'ID de l'application" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -594,12 +590,12 @@ msgstr "Supprimer les APK et/ou OBB sans métadonnées dans le dépôt" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Suppression de l'archive en cours, le dépôt occupe trop de place ({size} max {limit})" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Suppression de l'historique de git-mirror, car le dépôt occupe trop de place ({size} max {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -627,7 +623,7 @@ msgstr "La longueur de la description {length} dépasser la limite du nombre de #: ../fdroidserver/import.py msgid "Do not add 'disable:' to the generated build entries" -msgstr "" +msgstr "Ne pas ajouter \"disable:\" aux entrées générées" #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" @@ -714,7 +710,7 @@ msgstr "Drapeau de construction vide à {linedesc}" #: ../fdroidserver/__main__.py #, python-brace-format msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." -msgstr "" +msgstr "L'encodage est mis sur '{enc}', FDroid peut rencontrer des problèmes d'encodage. Merci de le mettre sur 'UTF-8' pour de meilleurs résultats." #: ../fdroidserver/init.py #, python-format @@ -939,22 +935,22 @@ msgstr "HTTPS doit être utilisé avec les URL de Subversion !" #: ../fdroidserver/server.py msgid "If a git mirror gets to big, allow the archive to be deleted" -msgstr "" +msgstr "Si un miroir git prend trop de place, permet à l'archive d'être supprimé" #: ../fdroidserver/server.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Si ce téléversement échoue, tente de le téléverser manuellement vers {url}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." -msgstr "" +msgstr "Ignore '{field}' dans les métadonnées '{metapath}' parce que c'est déprécié." #: ../fdroidserver/update.py #, python-format msgid "Ignoring FUNDING.yml entry longer than 2048: %s" -msgstr "" +msgstr "Ignore l'entrée FUNDING.yml si elle excède 2048: %s" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -999,7 +995,7 @@ msgid "Install built packages on devices" msgstr "Installer les paquets compilés sur le(s) périphérique(s)" #: ../fdroidserver/install.py -#, fuzzy, python-format +#, python-format msgid "Installing %s..." msgstr "Installation de %s …" @@ -1009,7 +1005,7 @@ msgid "Installing %s…" msgstr "Installation de %s …" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Installing '{apkfilename}' on {dev}..." msgstr "Installation de '{apkfilename}' sur {dev}…" @@ -1084,19 +1080,19 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Redirection non valide vers non-HTTPS : {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Lire toutes les métadonnées et quitter" +msgstr "Métadonnée de scrlib invalide : '{file}' n'existe pas" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: could not parse '{file}'" -msgstr "" +msgstr "Métadonnée de scrlib invalide : '{file}' ne peut être analysé" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" -msgstr "" +msgstr "Métadonnée de scrlib invalide : la clé '{key}' est inconnue dans '{file}'" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1115,7 +1111,7 @@ msgstr "Signature JAR vérifiée : {path}" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "Fichier Java JAR" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1124,7 +1120,7 @@ msgstr "Java JDK introuvable ! Installez dans un emplacement standard ou défi #: ../fdroidserver/scanner.py msgid "Java compiled class" -msgstr "" +msgstr "Classe Java compilée" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1144,9 +1140,8 @@ msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ msgstr "Le dernier archivage utiliser '{commit}' ressemble a une balise, mais le Mode De Vérification Des Mise A Jour est '{ucm}'" #: ../fdroidserver/lint.py -#, fuzzy msgid "Liberapay donation methods belong in the Liberapay: field" -msgstr "La méthode de donnation Liberapay appartien dans le flag LiberapayID" +msgstr "Les méthodes de don via Liberapay font parties de Liberapay: field" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" @@ -1337,13 +1332,13 @@ msgstr "Générez un rapport JSON dans un fichier nommé d'après l'APK." #: ../fdroidserver/scanner.py msgid "Output JSON to stdout." -msgstr "" +msgstr "Sortie JSON vers stdout." #: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py #: ../fdroidserver/update.py ../fdroidserver/signindex.py #: ../fdroidserver/checkupdates.py msgid "Outputting JSON" -msgstr "" +msgstr "Sortie vers JSON" #: ../fdroidserver/import.py msgid "Overall license of the project." @@ -1361,7 +1356,7 @@ msgstr "Substitution du nom de version vide dans {apkfilename} des métadonnées #: ../fdroidserver/import.py #, python-brace-format msgid "Package \"{appid}\" already exists" -msgstr "" +msgstr "Le paquet \"{appid}\" existe déjà" #: ../fdroidserver/common.py #, python-brace-format From 11469bf9518688f01f8adc2a1794cedac5474629 Mon Sep 17 00:00:00 2001 From: WaldiS Date: Sat, 17 Oct 2020 07:19:38 +0200 Subject: [PATCH 0576/2775] Translated using Weblate: Polish (pl) by WaldiS Currently translated at 85.6% (484 of 565 strings) Co-authored-by: WaldiS Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pl/ Translation: F-Droid/F-Droid Server --- locale/pl/LC_MESSAGES/fdroidserver.po | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index ff90bdea..e831b806 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:34+0200\n" -"PO-Revision-Date: 2020-07-02 20:41+0000\n" +"PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: WaldiS \n" "Language-Team: Polish \n" "Language: pl\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: ../fdroidserver/common.py msgid "" @@ -35,13 +35,12 @@ msgstr "" "Klucz publiczny SSH do użycia jako klucz wdrażania:" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" msgstr "" "\n" -"Klucz publiczny SSH do użycia jako klucz wdrażania:" +"Klucz publiczny SSH, który ma być używany jako klucz wdrażania:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -58,9 +57,9 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" nie ma pasującego pliku metadanych!" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." -msgstr "'{apkfilename}' jest już zainstalowany na {dev}." +msgstr "\"{apkfilename}\" jest już zainstalowany na {dev}." #: ../fdroidserver/update.py #, python-brace-format @@ -78,9 +77,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" istnieje, ale s3cmd nie jest zainstalowany!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" nie jest akceptowanym formatem, zamień na: {formats}" +msgstr "„{path}” nie jest obsługiwanym formatem pliku (użyj: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -90,7 +89,7 @@ msgstr "\"{path}\" nie jest akceptowanym formatem, zamień na: {formats}" #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" nie jest prawidłowym adresem URL!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -267,16 +266,15 @@ msgstr "Ostrzeż także o problemach z formatowaniem, takich jak rewritemeta -l" #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "Biblioteka AAR systemu Android" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Plik APK systemu Android" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "Nie znaleziono pakietu SDK Androida!" +msgstr "Kod DEX Android" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format From 86932dbc218e2046c9d40a68c6ed993b6b2e2e6e Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sat, 17 Oct 2020 07:19:39 +0200 Subject: [PATCH 0577/2775] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ Translation: F-Droid/F-Droid Server --- locale/bn/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/bo/LC_MESSAGES/fdroidserver.po | 73 +++++++++++++++----- locale/cs/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/de/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- locale/es/LC_MESSAGES/fdroidserver.po | 67 ++++++++++++++----- locale/es_AR/LC_MESSAGES/fdroidserver.po | 53 +++++++++++---- locale/es_MX/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/fa/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/fr/LC_MESSAGES/fdroidserver.po | 68 ++++++++++++++----- locale/hu/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/id/LC_MESSAGES/fdroidserver.po | 53 ++++++++++----- locale/it/LC_MESSAGES/fdroidserver.po | 60 ++++++++++++----- locale/ja/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/kab/LC_MESSAGES/fdroidserver.po | 52 +++++++++++---- locale/ko/LC_MESSAGES/fdroidserver.po | 66 +++++++++++++----- locale/ml/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/nb_NO/LC_MESSAGES/fdroidserver.po | 67 +++++++++++++++---- locale/nl/LC_MESSAGES/fdroidserver.po | 53 ++++++++++----- locale/pl/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- locale/pt/LC_MESSAGES/fdroidserver.po | 78 +++++++++++++++++----- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- locale/ru/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- locale/sk/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/sq/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- locale/sv/LC_MESSAGES/fdroidserver.po | 51 ++++++++++---- locale/tr/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- locale/ug/LC_MESSAGES/fdroidserver.po | 52 +++++++++++---- locale/uk/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 55 +++++++++++---- locale/zh_Hant/LC_MESSAGES/fdroidserver.po | 74 +++++++++++++++----- 31 files changed, 1457 insertions(+), 465 deletions(-) diff --git a/locale/bn/LC_MESSAGES/fdroidserver.po b/locale/bn/LC_MESSAGES/fdroidserver.po index f809bf43..10c8b2be 100644 --- a/locale/bn/LC_MESSAGES/fdroidserver.po +++ b/locale/bn/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -370,24 +370,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -482,6 +473,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -997,6 +989,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1106,7 +1103,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1863,8 +1860,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1898,6 +1896,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2044,6 +2046,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2537,6 +2550,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2547,6 +2565,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/bo/LC_MESSAGES/fdroidserver.po b/locale/bo/LC_MESSAGES/fdroidserver.po index 7db00157..43ae3895 100644 --- a/locale/bo/LC_MESSAGES/fdroidserver.po +++ b/locale/bo/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2018-02-13 08:41+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Tibetan \n" @@ -378,24 +378,16 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "ཚགས་རྒྱབ་པའི་སྐབས་སུ་ནོར་སྐྱོན་ {} ཤོར་བས་བཟོ་སྐྲུན་བྱེད་ཐུབ་མེད།" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "{path}གྱི་ཆེད་དུ་ཐུམ་སྒྲིལ་གྱི་མིང་རྙེད་མ་སོང་།!" - -#: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "{path}!གྱི་ཆེད་དུ་ཐུམ་སྒྲིལ་གྱི་མིང་རྙེད་མ་སོང་།" - #: ../fdroidserver/vmtools.py #, fuzzy, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" #: ../fdroidserver/rewritemeta.py @@ -492,6 +484,7 @@ msgstr "དཔྱད་ཞིབ་ཀྱི་ཆེད་དུ་apk ཡི msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1012,6 +1005,11 @@ msgstr "ཁུངས་ལྡན་མིན་པའི་APK" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "ལས་ཀ་བྱེད་བཞིན་པ།{appid}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1120,8 +1118,9 @@ msgid "Keystore for signing key:\t" msgstr "མིང་རྟགས་བཀོད་པའི་ལྡེ་མིག་ཆེད་དུ་སྟོན་པའི་ལྡེ་མིག་གསོག་ཉར་ཁང་གི་ལམ།\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "ཁས་ལེན་བྱས་པའི་བེད་སྤྱོད་ཐ་མ་ '{commit}' སྦྱར་བ་འདྲ་པོ་འདུག, འོན་ཀྱང་གསར་བསྒྱུར་ཡོད་མེད་འཚོལ་བྱེད་ནི།'{ucm}'" #: ../fdroidserver/lint.py @@ -1883,8 +1882,11 @@ msgstr "%s 1 དེ་ལ་བེད་སྤྱོད་མེད་པའི msgid "Unused scanignore path: %s" msgstr "%s 1 དེ་ལ་བེད་སྤྱོད་མེད་པའི་ཡིག་ཆ།" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "མཉེན་ཆས་ཁ་བྱང་ནང་ལ་གསར་བསྒྱུར་འཚོལ་བའི་མིང་སྒྲིག་ཚར་འདུག -འདི་སུབས་ཆོག་གི་རེད།" #: ../fdroid ../fdroidserver/__main__.py @@ -1918,6 +1920,12 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "མཉེན་ཆས་ཁ་བྱང་ནང་ལ་གསར་བསྒྱུར་འཚོལ་བའི་མིང་སྒྲིག་ཚར་འདུག -འདི་སུབས་ཆོག་གི་རེད།" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2064,6 +2072,21 @@ msgstr "གསལ་ཁ་མེད་པའི་གདམ་ཀ:%s 1 (%s 2?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "མཉེས་ཆས་ཁ་བྱང་རྒྱུད་གསར་བསྒྱར་ཡོད་མིན་ལྟོས།" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "མཉེན་ཆས་ཀྱི་ངོ་བོ་དང་མཉམ་དུ་གདམ་ཀ་ཅན་གྱི་ཐོན་རིམ་ཨང་རྟགས་APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "APPID བཀོད་པའི་ནང་གི་མཉེས་ཆས་ཁ་བྱང་།" @@ -2558,6 +2581,12 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xmlལ་ཟླ་ཚེས་མིན་འདུག" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} ལ་མིང་ཡོད་མ་རེད། !དེའི་ཚབ་ལ་ཐུམ་སྒྲིལ་མིང་བེད་སྤྱོད་བྱེད།." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2568,6 +2597,11 @@ msgstr "{appid} ལ་མིང་ཡོད་མ་རེད། !དེའི msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2664,6 +2698,13 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} བཟོ་སྐྲུན་ལེགས་སྒྲུབ།" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "{path}གྱི་ཆེད་དུ་ཐུམ་སྒྲིལ་གྱི་མིང་རྙེད་མ་སོང་།!" + +#, fuzzy +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "{path}!གྱི་ཆེད་དུ་ཐུམ་སྒྲིལ་གྱི་མིང་རྙེད་མ་སོང་།" + #~ msgid "Android Build Tools path '{path}' does not exist!" #~ msgstr "ཨེན་ཀྲོཌ་བཟོ་སྐྲུན་མ་ལག་ཐབས་ལམ '{path}1' མིན་འདུག!" diff --git a/locale/cs/LC_MESSAGES/fdroidserver.po b/locale/cs/LC_MESSAGES/fdroidserver.po index 2bbe38bc..94fbddd3 100644 --- a/locale/cs/LC_MESSAGES/fdroidserver.po +++ b/locale/cs/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2019-02-01 13:33+0000\n" "Last-Translator: Michal Čihař \n" "Language-Team: Czech \n" @@ -373,24 +373,15 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -485,6 +476,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1001,6 +993,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1110,7 +1107,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1868,8 +1865,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1903,6 +1901,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2049,6 +2051,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2545,6 +2558,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2555,6 +2573,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index ab749f51..59c94768 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-02 19:15+0000\n" "Last-Translator: melusine \n" "Language-Team: German \n" @@ -387,24 +387,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Kann nicht erstellt werden, da {} Fehler beim Prüfen aufgetreten ist." msgstr[1] "Kann nicht erstellt werden, da {} Fehler beim Prüfen aufgetreten sind." -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "packageName für {path} konnte nicht gefunden werden!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "AppID für {path} konnte nicht gefunden werden!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "„{path}” konnte nicht gelesen werden!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "AppID {appid} konnte nicht aufgelöst werden" #: ../fdroidserver/rewritemeta.py @@ -501,6 +493,7 @@ msgstr "Konnte APK-Datei nicht für Analyse öffnen" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "Konnte Größe \"{size}\" nicht parsen, falscher Typ \"{type}\"" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1022,6 +1015,12 @@ msgstr "Ungültige APK" msgid "Invalid VercodeOperation: {field}" msgstr "Ungültige VercodeOperation: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "Ungültige VercodeOperation: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1130,8 +1129,9 @@ msgid "Keystore for signing key:\t" msgstr "Schlüsselspeicher für den Signierschlüssel:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Der zuletzt verwendete Commit '{commit}' sieht aus wie ein Tag, aber der Update Check Modus ist '{ucm}'" #: ../fdroidserver/lint.py @@ -1892,8 +1892,11 @@ msgstr "Nicht verwendete Datei bei %s" msgid "Unused scanignore path: %s" msgstr "Nicht verwendete Datei bei %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "Update Check Name ist auf die bekannte App-ID gesetzt - sie kann entfernt werden" #: ../fdroid ../fdroidserver/__main__.py @@ -1927,6 +1930,12 @@ msgstr "UpdateCheckData muss HTTPS-URL verwenden: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData hat eine ungültige URL: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "Update Check Name ist auf die bekannte App-ID gesetzt - sie kann entfernt werden" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2073,6 +2082,21 @@ msgstr "Mehrdeutige Option: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "App-ID, um auf Aktualisierungen zu prüfen" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "App-ID mit optionalem Versionscode in der Form APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "App-ID in der Form APPID" @@ -2567,6 +2591,12 @@ msgstr "{apkfilename} hat mehrere {name} Dateien, sieht aus wie Master Key Explo msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "Die AndroidManifest.xml der App „{apkfilename}” hat ein ungültiges Datum: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} besitzt keinen Namen! Verwende den Paketnamen stattdessen." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2577,6 +2607,12 @@ msgstr "{appid} besitzt keinen Namen! Verwende den Paketnamen stattdessen." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} von {path} ist kein gültiger Android-Paketname!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{appid} von {path} ist kein gültiger Android-Paketname!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2675,6 +2711,12 @@ msgid_plural "{} builds succeeded" msgstr[0] "Buildvorgang erfolgreich" msgstr[1] "Buildvorgänge erfolgreich" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "packageName für {path} konnte nicht gefunden werden!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "AppID für {path} konnte nicht gefunden werden!" + #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "GPG-Signaturen für Programmpakete in der Paketquelle hinzufügen" diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index c85fe5b5..44750384 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-02 19:15+0000\n" "Last-Translator: Jo \n" "Language-Team: Spanish \n" @@ -387,24 +387,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "No se puede construir debido al error {} mientras se comprobaba" msgstr[1] "No se puede construir debido a los errores {} mientras se comprobaba" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "¡No se puede encontrar un packageName para {path}!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "¡No se puede encontrar un appid para {path}!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "¡No se puede leer \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "No se puede resolver el identificador de aplicación {appid}" #: ../fdroidserver/rewritemeta.py @@ -501,6 +493,7 @@ msgstr "No se ha podido abrir el archivo apk para analizarlo" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1022,6 +1015,11 @@ msgstr "APK no válido" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1130,8 +1128,9 @@ msgid "Keystore for signing key:\t" msgstr "Depósito de claves para la clave de firma de repositorio:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "La última confirmación utilizada '{commit}' parece una etiqueta, pero Update Check Mode es '{ucm}'" #: ../fdroidserver/lint.py @@ -1891,8 +1890,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1926,6 +1926,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2072,6 +2076,21 @@ msgstr "opción ambigua: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId para buscar actualizaciones" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId con código de versión opcional en la forma APPID [: VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId en el formato APPID" @@ -2565,6 +2584,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "El AndroidManifest.xml de {apkfilename} tiene la fecha mal: " +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2575,6 +2599,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2673,6 +2702,12 @@ msgid_plural "{} builds succeeded" msgstr[0] "" msgstr[1] "" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "¡No se puede encontrar un packageName para {path}!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "¡No se puede encontrar un appid para {path}!" + #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Añadir las firmas gpg para los paquetes en el repositorio" diff --git a/locale/es_AR/LC_MESSAGES/fdroidserver.po b/locale/es_AR/LC_MESSAGES/fdroidserver.po index 3051859d..9dbbb5da 100644 --- a/locale/es_AR/LC_MESSAGES/fdroidserver.po +++ b/locale/es_AR/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-01 10:31+0000\n" "Last-Translator: riveravaldez \n" "Language-Team: Spanish (Argentina) \n" @@ -375,24 +375,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -490,6 +481,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1010,6 +1002,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1120,7 +1117,7 @@ msgstr "Ruta al almacén de claves para la llave de firmado del repositorio" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1884,8 +1881,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1919,6 +1917,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2067,6 +2069,19 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +msgid "application ID of file to operate on" +msgstr "app-id para verificar actualizaciones" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "app-id con VersionCode opcional con el formato APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #, fuzzy msgid "applicationId in the form APPID" @@ -2567,6 +2582,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2577,6 +2597,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/es_MX/LC_MESSAGES/fdroidserver.po b/locale/es_MX/LC_MESSAGES/fdroidserver.po index 06690259..bf0cc66c 100644 --- a/locale/es_MX/LC_MESSAGES/fdroidserver.po +++ b/locale/es_MX/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-04-29 12:49+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Spanish (Mexico) \n" @@ -371,24 +371,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -485,6 +476,7 @@ msgstr "No se pudo abrir el archivo apk para su análisis" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1001,6 +993,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1110,7 +1107,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1867,8 +1864,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1902,6 +1900,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2048,6 +2050,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2541,6 +2554,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2551,6 +2569,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/fa/LC_MESSAGES/fdroidserver.po b/locale/fa/LC_MESSAGES/fdroidserver.po index 1e6025e3..2927aaa3 100644 --- a/locale/fa/LC_MESSAGES/fdroidserver.po +++ b/locale/fa/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: Mostafa Ahangarha \n" "Language-Team: Persian \n" @@ -371,24 +371,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -483,6 +474,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -998,6 +990,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1107,7 +1104,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1864,8 +1861,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1899,6 +1897,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2045,6 +2047,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2538,6 +2551,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2548,6 +2566,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 92c5395e..95255e01 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: Yldun \n" "Language-Team: French \n" @@ -396,24 +396,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Build impossible à cause de l'erreur lors de l'analyse" msgstr[1] "Build impossible à cause des {} erreurs lors de l'analyse" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "Impossible de trouver un packageName pour {path} !" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "Impossible de trouver un appid pour {path} !" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Impossible de lire \"{path}\" !" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Impossible de résoudre l'identifiant de l'application {appid}" #: ../fdroidserver/rewritemeta.py @@ -508,6 +500,7 @@ msgstr "Impossible d'ouvrir le fichier apk pour analyse" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "Impossible de récupérer la taille \"{size}\", mauvais type \"{type}\"" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "Impossible de trouver l'ID de l'application" @@ -1027,6 +1020,12 @@ msgstr "APK invalide" msgid "Invalid VercodeOperation: {field}" msgstr "VercodeOperation non valide : {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "VercodeOperation non valide : {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1135,8 +1134,9 @@ msgid "Keystore for signing key:\t" msgstr "Stockage des clés signée :\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Le dernier archivage utiliser '{commit}' ressemble a une balise, mais le Mode De Vérification Des Mise A Jour est '{ucm}'" #: ../fdroidserver/lint.py @@ -1897,8 +1897,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1932,6 +1933,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2078,6 +2083,21 @@ msgstr "option ambiguë : %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId pour vérifier les mises à jour" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId avec le versionCode optionnel sous la forme APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId sous la forme de APPID" @@ -2572,6 +2592,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2582,6 +2607,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2680,6 +2710,12 @@ msgid_plural "{} builds succeeded" msgstr[0] "" msgstr[1] "" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Impossible de trouver un packageName pour {path} !" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Impossible de trouver un appid pour {path} !" + #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Ajouter des signatures GPG pour les paquets dans le dépôt" diff --git a/locale/hu/LC_MESSAGES/fdroidserver.po b/locale/hu/LC_MESSAGES/fdroidserver.po index 7b520df0..626b59a1 100644 --- a/locale/hu/LC_MESSAGES/fdroidserver.po +++ b/locale/hu/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-04-07 13:43+0000\n" "Last-Translator: Balázs Meskó \n" "Language-Team: Hungarian \n" @@ -377,24 +377,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -489,6 +480,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -1004,6 +996,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1113,7 +1110,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1870,8 +1867,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1905,6 +1903,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2051,6 +2053,17 @@ msgstr "nem egyértelmű kapcsoló: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2544,6 +2557,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2554,6 +2572,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/id/LC_MESSAGES/fdroidserver.po b/locale/id/LC_MESSAGES/fdroidserver.po index 25e30b84..5df1253e 100644 --- a/locale/id/LC_MESSAGES/fdroidserver.po +++ b/locale/id/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: signz signotorez \n" "Language-Team: Indonesian \n" @@ -368,24 +368,15 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -480,6 +471,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -995,6 +987,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1104,7 +1101,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1714,7 +1711,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py @@ -1860,8 +1857,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1895,6 +1893,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2041,6 +2043,17 @@ msgstr "opsi ambigu: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2531,6 +2544,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2541,6 +2559,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index 49c1fbdd..aa3aec38 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-01 11:26+0000\n" "Last-Translator: Massimiliano Caniparoli \n" "Language-Team: Italian \n" @@ -387,24 +387,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Impossibile costruire a causa di un errore con {} durante la scansione" msgstr[1] "Impossibile costruire a causa di errori con {} durante la scansione" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "Impossibile trovare un packageName per {path}!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "Impossibile trovare un appid per {path}!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Impossibile leggere \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Impossibile trovare l'app id {appid}" #: ../fdroidserver/rewritemeta.py @@ -501,6 +493,7 @@ msgstr "Impossibile aprire il file apk per l'analisi" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1021,6 +1014,11 @@ msgstr "APK non valido" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1130,7 +1128,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1887,8 +1885,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1922,6 +1921,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2068,6 +2071,17 @@ msgstr "opzione ambigua: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2561,6 +2575,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "L'AndroidManifest.xml di {apkfilename} ha una data non corretta: " +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2571,6 +2590,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2669,5 +2693,11 @@ msgid_plural "{} builds succeeded" msgstr[0] "" msgstr[1] "" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Impossibile trovare un packageName per {path}!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Impossibile trovare un appid per {path}!" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "Chiedi interattivamente riguardo a ciò che deve essere aggiornato." diff --git a/locale/ja/LC_MESSAGES/fdroidserver.po b/locale/ja/LC_MESSAGES/fdroidserver.po index a9fe7a47..69411cf2 100644 --- a/locale/ja/LC_MESSAGES/fdroidserver.po +++ b/locale/ja/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-224-g4b0ade7\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-09-02 16:10+0000\n" "Last-Translator: Hinaloe \n" "Language-Team: Japanese \n" @@ -368,24 +368,15 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -480,6 +471,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -995,6 +987,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1104,7 +1101,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1860,8 +1857,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1895,6 +1893,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2041,6 +2043,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2531,6 +2544,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2541,6 +2559,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/kab/LC_MESSAGES/fdroidserver.po b/locale/kab/LC_MESSAGES/fdroidserver.po index dad9f5f5..479df7d0 100644 --- a/locale/kab/LC_MESSAGES/fdroidserver.po +++ b/locale/kab/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: Kahina Messaoudi \n" "Language-Team: Kabyle \n" @@ -371,24 +371,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "ur izmir ara ad iɣer \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -483,6 +474,7 @@ msgstr "Ur yezmir ara a d-ildi afaylu apk i tesleḍt" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -998,6 +990,12 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "no \"icon\" in {appid}" +msgid "Invalid application ID {appid}" +msgstr "ulac \"tignit\" deg {appid}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1107,7 +1105,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1864,8 +1862,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1899,6 +1898,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2045,6 +2048,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2538,6 +2552,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2548,6 +2567,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/ko/LC_MESSAGES/fdroidserver.po b/locale/ko/LC_MESSAGES/fdroidserver.po index 340cdab5..d6cc6a17 100644 --- a/locale/ko/LC_MESSAGES/fdroidserver.po +++ b/locale/ko/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-135-g16dd6d28\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2019-01-19 22:57+0000\n" "Last-Translator: Seokyong Jung \n" "Language-Team: Korean \n" @@ -377,24 +377,16 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "{path}를 위한 packageName을 찾을 수 없습니다!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "{path}를 위한 appid를 찾을 수 없습니다!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "\"{path}\"를 읽을 수 없습니다!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "앱 id {appid}를 해결할 수 없습니다" #: ../fdroidserver/rewritemeta.py @@ -489,6 +481,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -1004,6 +997,12 @@ msgstr "올바르지 않은 APK" msgid "Invalid VercodeOperation: {field}" msgstr "잘못된 Vercode연산: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "잘못된 Vercode연산: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1113,7 +1112,7 @@ msgstr "서명 키를 위한 키저장소:\t" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1870,8 +1869,9 @@ msgstr "%s에서 사용되지 않은 파일" msgid "Unused scanignore path: %s" msgstr "%s에서 사용되지 않은 파일" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1905,6 +1905,10 @@ msgstr "UpdateCheckData는 HTTPS URL을 사용해야 합니다: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData는 올바른 URL이 아닙니다: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2051,6 +2055,21 @@ msgstr "모호한 옵션: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "업데이트를 확인할 applicationId" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "양식 APPID[:VERCODE]에서 선택적인 versionCode로 된 applicationId" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "양식 APPID의 applicationId" @@ -2541,6 +2560,12 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "{apkfilename}의 AndroidManifest.xml에 잘못된 날짜가 있습니다: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid}는 이름을 가지지 않습니다! 대신 패키지 이름 사용." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2551,6 +2576,11 @@ msgstr "{appid}는 이름을 가지지 않습니다! 대신 패키지 이름 사 msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2647,5 +2677,11 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} 빌드 성공됨" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "{path}를 위한 packageName을 찾을 수 없습니다!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "{path}를 위한 appid를 찾을 수 없습니다!" + #~ msgid "Add gpg signatures for packages in repo" #~ msgstr "저장소에서 패키지에 gpg 서명을 추가합니다" diff --git a/locale/ml/LC_MESSAGES/fdroidserver.po b/locale/ml/LC_MESSAGES/fdroidserver.po index 06d11bc2..33e8d4f3 100644 --- a/locale/ml/LC_MESSAGES/fdroidserver.po +++ b/locale/ml/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -370,24 +370,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -482,6 +473,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -997,6 +989,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1106,7 +1103,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1863,8 +1860,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1898,6 +1896,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2044,6 +2046,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2537,6 +2550,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2547,6 +2565,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index 55778441..6f9f99c8 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-74-ga380b9f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-02 19:15+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" @@ -384,24 +384,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Kan ikke bygge som følge av {} feil under skanning" msgstr[1] "Kan ikke bygge som følge av {} feiler under skanning" -#: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "Fant ikke packageName for {path}." - -#: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "Finner ikke AppID for {path}." - #: ../fdroidserver/vmtools.py #, fuzzy, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Kan ikke lese \"{path}\"." +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Kan ikke fortolke program-ID {appid}" #: ../fdroidserver/rewritemeta.py @@ -499,6 +490,7 @@ msgstr "Kunne ikke åpne APK-fil for analyse" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "Kunne ikke fortolke størrelse \"{size}\", feil type \"{type}\"" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1039,6 +1031,12 @@ msgstr "Ugyldig APK" msgid "Invalid VercodeOperation: {field}" msgstr "Ugyldig VercodeOperation: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "Ugyldig VercodeOperation: {field}" + #: ../fdroidserver/metadata.py #, fuzzy, python-format msgid "Invalid boolean '%s'" @@ -1152,7 +1150,7 @@ msgstr "Nøkkellager for signeringsnøkkel:\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Sist brukte innsendelse \"{commit}\" ser ut som en tagg, men oppdateringssjekkingsmodus er på \"{ucm}\"." #: ../fdroidserver/lint.py @@ -1936,9 +1934,10 @@ msgstr "Ubrukt fil i %s" msgid "Unused scanignore path: %s" msgstr "Ubrukt fil i %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py #, fuzzy -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "\"Update Check Name\" er satt til den kjente App-ID-en - den kan fjernes." #: ../fdroid ../fdroidserver/__main__.py @@ -1972,6 +1971,11 @@ msgstr "UpdateCheckData må bruke HTTPS-nettadresse: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData er ikke en gyldig nettadresse: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "\"Update Check Name\" er satt til den kjente App-ID-en - den kan fjernes." + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2124,6 +2128,21 @@ msgstr "tvetydig valg: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "fant ikke apksigner (som kreves for signering)." +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "App-ID å sjekke for oppdateringer" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "App-ID med valgfri versionCode, i formen APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #, fuzzy msgid "applicationId in the form APPID" @@ -2630,6 +2649,12 @@ msgstr "{apkfilename} har flere {name}-filer, ser ut til å være en hovednøkke msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "{apkfilename} sin AndroidManifest.xml har en feilaktig dato: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} mangler navn. Bruker pakkenavn istedenfor." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2640,6 +2665,12 @@ msgstr "{appid} mangler navn. Bruker pakkenavn istedenfor." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} fra {path} er ikke et gyldig Android-pakkenavn!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{appid} fra {path} er ikke et gyldig Android-pakkenavn!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2738,5 +2769,13 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} bygg fullført" msgstr[1] "{} bygg fullført" +#, fuzzy +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Fant ikke packageName for {path}." + +#, fuzzy +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Finner ikke AppID for {path}." + #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Legg til PGP-signaturer for pakker i pakkebrønnen ved bruk av GnuPG" diff --git a/locale/nl/LC_MESSAGES/fdroidserver.po b/locale/nl/LC_MESSAGES/fdroidserver.po index 1e2353a2..fbc7b87e 100644 --- a/locale/nl/LC_MESSAGES/fdroidserver.po +++ b/locale/nl/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-01 20:58+0000\n" "Last-Translator: Bart Groeneveld \n" "Language-Team: Dutch \n" @@ -371,24 +371,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -483,6 +474,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -998,6 +990,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1107,7 +1104,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1718,7 +1715,7 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "" #: ../fdroidserver/lint.py @@ -1864,8 +1861,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1899,6 +1897,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2045,6 +2047,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2538,6 +2551,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2548,6 +2566,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index e831b806..5437276b 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: WaldiS \n" "Language-Team: Polish \n" @@ -378,24 +378,16 @@ msgstr[0] "Nie można zbudować z powodu błędu {} podczas skanowania" msgstr[1] "Nie można zbudować z powodu błędów {} podczas skanowania" msgstr[2] "Nie można zbudować z powodu błędów {} podczas skanowania" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "Nie można znaleźć nazwy pakietu dla {path}!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "Nie można znaleźć załącznika dla {path}!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Nie można odczytać \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Nie można rozpoznać identyfikatora aplikacji {appid}" #: ../fdroidserver/rewritemeta.py @@ -492,6 +484,7 @@ msgstr "Nie można otworzyć pliku APK do analizy" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1013,6 +1006,12 @@ msgstr "Nieprawidłowy plik APK" msgid "Invalid VercodeOperation: {field}" msgstr "Nieprawidłowa VercodeOperation: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "Nieprawidłowa VercodeOperation: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1121,8 +1120,9 @@ msgid "Keystore for signing key:\t" msgstr "Magazyn kluczy do podpisywania klucza:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Ostatnio używany commit '{commit}' wygląda jak tag, ale tryb sprawdzania aktualizacji to '{ucm}'" #: ../fdroidserver/lint.py @@ -1884,8 +1884,11 @@ msgstr "Plik UNUSED, o %s" msgid "Unused scanignore path: %s" msgstr "Plik UNUSED, o %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "Aktualizacja Check Name jest ustawiona na znany identyfikator aplikacji - można go usunąć" #: ../fdroid ../fdroidserver/__main__.py @@ -1919,6 +1922,12 @@ msgstr "UpdateCheckData musi używać adresu URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData nie jest prawidłowym adresem URL: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "Aktualizacja Check Name jest ustawiona na znany identyfikator aplikacji - można go usunąć" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2065,6 +2074,21 @@ msgstr "niejednoznaczna opcja: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId, aby sprawdzić dostępność aktualizacji" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId z opcjonalnym versionCode w postaci APPID [:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId w postaci APPID" @@ -2562,6 +2586,12 @@ msgstr "{apkfilename} ma wiele {name} plików, wygląda jak exploit Master Key!" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "{apkfilename} AndroidManifest.xml ma złą datę: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} nie ma nazwy! Zamiast tego użyj nazwy pakietu." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2572,6 +2602,12 @@ msgstr "{appid} nie ma nazwy! Zamiast tego użyj nazwy pakietu." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} z {path} nie jest prawidłową nazwą pakietu Android!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{appid} z {path} nie jest prawidłową nazwą pakietu Android!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2672,5 +2708,11 @@ msgstr[0] "{} kompilacja powiodła się" msgstr[1] "{} kompilacji powiodło się" msgstr[2] "{} kompilacje powiodły się" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Nie można znaleźć nazwy pakietu dla {path}!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Nie można znaleźć załącznika dla {path}!" + #~ msgid "Interactively ask about things that need updating." #~ msgstr "Interaktywnie pytaj o rzeczy, które wymagają aktualizacji." diff --git a/locale/pt/LC_MESSAGES/fdroidserver.po b/locale/pt/LC_MESSAGES/fdroidserver.po index 0e9fc895..b7f38aab 100644 --- a/locale/pt/LC_MESSAGES/fdroidserver.po +++ b/locale/pt/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese \n" @@ -382,24 +382,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Não é possível construir devido a erro {} durante a digitalização" msgstr[1] "Não é possível construir devido a erros {} durante a digitalização" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "Não é possível encontrar um packageName para {path} 1!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "Não é possível encontrar um appid para {path} 1!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Não é possível ler \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Não é possível resolver o ID da app {appid}" #: ../fdroidserver/rewritemeta.py @@ -494,6 +486,7 @@ msgstr "Não foi possível abrir ficheiro apk para análise" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "Não foi possível analisar o tamanho \"{size}\", tipo \"{type}\" incorreto" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "Não foi possível encontrar o ID da aplicação" @@ -1013,6 +1006,12 @@ msgstr "APK inválido" msgid "Invalid VercodeOperation: {field}" msgstr "VercodeOperation inválido: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "VercodeOperation inválido: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1121,8 +1120,9 @@ msgid "Keystore for signing key:\t" msgstr "Armazenamento de chaves de assinatura:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o modo de verificação de atualização é '{ucm}'" #: ../fdroidserver/lint.py @@ -1733,7 +1733,9 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser definidos no config.py!" #: ../fdroidserver/lint.py -msgid "UCM is set but it looks like checkupdates hasn't been run yet" +#, fuzzy +#| msgid "UCM is set but it looks like checkupdates hasn't been run yet" +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" msgstr "UCM é definido, mas parece que checkupdates ainda não foi executado" #: ../fdroidserver/lint.py @@ -1879,8 +1881,11 @@ msgstr "O caminho de scandelete não é usado: %s" msgid "Unused scanignore path: %s" msgstr "O caminho de scanignore não é usado: %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" #: ../fdroid ../fdroidserver/__main__.py @@ -1914,6 +1919,12 @@ msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2060,6 +2071,21 @@ msgstr "opção ambígua: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "Nenhum apksigner encontrado, é necessário para assinar!" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId para verificar se há atualizações" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId, na forma APPID" @@ -2553,6 +2579,12 @@ msgstr "{apkfilename} tem vários ficheiros {name} que, parece explorar a Master msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml do {apkfilename} tem uma data má: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2563,6 +2595,12 @@ msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} from {path} não é um nome de pacote Android válido!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{appid} from {path} não é um nome de pacote Android válido!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2660,3 +2698,9 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} compilação com sucesso" msgstr[1] "{} compilações com sucesso" + +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Não é possível encontrar um packageName para {path} 1!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Não é possível encontrar um appid para {path} 1!" diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index b5e3879c..6035ada5 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: André Marcelo Alvarenga \n" "Language-Team: Portuguese (Brazil) \n" @@ -387,24 +387,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Não é possível criar devido a {} erro durante a digitalização" msgstr[1] "Não é possível criar devido a {} erros durante a digitalização" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "Não é possível encontrar um packageName para {path} 1!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "Não é possível encontrar um appid para {path} 1!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Impossível ler \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Impossível resolver o ID de Aplicativo '{appid}'" #: ../fdroidserver/rewritemeta.py @@ -499,6 +491,7 @@ msgstr "Impossível abrir o arquivo de APK para analisá-lo" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "Não foi possível analisar o tamanho \"{size}\", tipo incorreto \"{type}\"" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "Não foi possível encontrar o ID do aplicativo" @@ -1018,6 +1011,12 @@ msgstr "APK inválido" msgid "Invalid VercodeOperation: {field}" msgstr "Versão de Operação de Código inválido: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "Versão de Operação de Código inválido: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1126,8 +1125,9 @@ msgid "Keystore for signing key:\t" msgstr "Armazenamento de chaves de assinatura:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "O último commit usado '{commit}' parece com uma tag, mas o Update Check Mode é '{ucm}'" #: ../fdroidserver/lint.py @@ -1884,8 +1884,11 @@ msgstr "Caminho scandelete não usado: %s" msgid "Unused scanignore path: %s" msgstr "Caminho scanignore não usado: %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" #: ../fdroid ../fdroidserver/__main__.py @@ -1919,6 +1922,12 @@ msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2065,6 +2074,21 @@ msgstr "opção ambígua: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "o apksigner não foi encontrado, ele é necessário para assinar!" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId para verificar se há atualizações" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId, na forma APPID" @@ -2558,6 +2582,12 @@ msgstr "{apkfilename} tem vários arquivos {name} que, parece explorar a Master msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml do {apkfilename} tem uma data má: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2568,6 +2598,12 @@ msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "O {appid} do {path} não é um Nome de Pacote Android válido!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "O {appid} do {path} não é um Nome de Pacote Android válido!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2666,6 +2702,12 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} compilação foi bem sucedida" msgstr[1] "{} compilações foram bem sucedidas" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Não é possível encontrar um packageName para {path} 1!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Não é possível encontrar um appid para {path} 1!" + #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Adicione assinaturas gpg para os pacotes no repositório" diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index 289817d1..46991e02 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese (Portugal) \n" @@ -385,24 +385,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Não é possível construir devido a erro {} durante a digitalização" msgstr[1] "Não é possível construir devido a erros {} durante a digitalização" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "Não é possível encontrar um packageName para {path} 1!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "Não é possível encontrar um appid para {path} 1!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Não é possível ler \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Não é possível resolver o ID da app {appid}" #: ../fdroidserver/rewritemeta.py @@ -497,6 +489,7 @@ msgstr "Não foi possível abrir ficheiro apk para análise" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "Não foi possível analisar o tamanho \"{size}\", tipo \"{type}\" incorreto" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "Não foi possível encontrar o ID da aplicação" @@ -1016,6 +1009,12 @@ msgstr "APK inválido" msgid "Invalid VercodeOperation: {field}" msgstr "VercodeOperation inválido: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "VercodeOperation inválido: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1124,8 +1123,9 @@ msgid "Keystore for signing key:\t" msgstr "Armazenamento de chaves de assinatura:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o modo de verificação de atualização é '{ucm}'" #: ../fdroidserver/lint.py @@ -1882,8 +1882,11 @@ msgstr "O caminho de scandelete não é usado: %s" msgid "Unused scanignore path: %s" msgstr "O caminho de scanignore não é usado: %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" #: ../fdroid ../fdroidserver/__main__.py @@ -1917,6 +1920,12 @@ msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2063,6 +2072,21 @@ msgstr "opção ambígua: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "Nenhum apksigner encontrado, é necessário para assinar!" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId para verificar se há atualizações" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId, na forma APPID" @@ -2556,6 +2580,12 @@ msgstr "{apkfilename} tem vários ficheiros {name} que, parece explorar a Master msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml do {apkfilename} tem uma data má: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2566,6 +2596,12 @@ msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} from {path} não é um nome de pacote Android válido!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{appid} from {path} não é um nome de pacote Android válido!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2663,3 +2699,9 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} compilação com sucesso" msgstr[1] "{} compilações com sucesso" + +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Não é possível encontrar um packageName para {path} 1!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Não é possível encontrar um appid para {path} 1!" diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index ca66bcf8..bec29d58 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-05 12:34+0000\n" "Last-Translator: Boris Timofeev \n" "Language-Team: Russian \n" @@ -384,24 +384,16 @@ msgstr[0] "Запустить сборку невозможно из-за {} о msgstr[1] "Запустить сборку невозможно из-за {} ошибок во время сканирования данных" msgstr[2] "Запустить сборку невозможно из-за {} ошибок во время сканирования данных" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "По указанному пути {path} не удалось найти packageName!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "По указанному пути {path} не удалось найти appid!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Неправильно указан путь \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Не удалось разобрать app id {appid}" #: ../fdroidserver/rewritemeta.py @@ -496,6 +488,7 @@ msgstr "Не удалось открыть и проанализировать msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "Не удалось найти Application ID" @@ -1018,6 +1011,12 @@ msgstr "Непригодный файл APK" msgid "Invalid VercodeOperation: {field}" msgstr "Расхождение версий приложения в метаданных: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "Расхождение версий приложения в метаданных: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1126,8 +1125,9 @@ msgid "Keystore for signing key:\t" msgstr "Хранилище ключа для подписывания:→\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Последний наложенный коммит '{commit}' похож на метку (tag), но режим проверки обновлений (Update Check Mode) — '{ucm}'" #: ../fdroidserver/lint.py @@ -1889,8 +1889,11 @@ msgstr "Файл не ипользуется %s" msgid "Unused scanignore path: %s" msgstr "Файл не ипользуется %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "Имя приложения для проверки обновлений (Update Check Name) соответствует app id. Это поле можно удалить" #: ../fdroid ../fdroidserver/__main__.py @@ -1924,6 +1927,12 @@ msgstr "URL-адрес в UpdateCheckData должен начинаться с H msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData содержит некорректный URL-адрес: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "Имя приложения для проверки обновлений (Update Check Name) соответствует app id. Это поле можно удалить" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2070,6 +2079,21 @@ msgstr "неоднозначный выбор: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId для проверки обновлений" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId и внутренняя версия приложения (versionCode) в виде APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId в виде APPID" @@ -2567,6 +2591,12 @@ msgstr "У {apkfilename} несколько файлов {name}. Выгляди msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml приложения {apkfilename} содержит неверную дату: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "У {appid} нет имени! Будет использовано имя пакета." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2577,6 +2607,12 @@ msgstr "У {appid} нет имени! Будет использовано имя msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} из {path} не годится в качестве имени пакета Android!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{appid} из {path} не годится в качестве имени пакета Android!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2676,3 +2712,9 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} успешная сборка" msgstr[1] "{} успешные сборки" msgstr[2] "{} успешных сборок" + +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "По указанному пути {path} не удалось найти packageName!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "По указанному пути {path} не удалось найти appid!" diff --git a/locale/sk/LC_MESSAGES/fdroidserver.po b/locale/sk/LC_MESSAGES/fdroidserver.po index 06141fa4..798257b3 100644 --- a/locale/sk/LC_MESSAGES/fdroidserver.po +++ b/locale/sk/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -371,24 +371,15 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -483,6 +474,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -998,6 +990,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1107,7 +1104,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1865,8 +1862,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1900,6 +1898,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2046,6 +2048,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2542,6 +2555,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2552,6 +2570,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/sq/LC_MESSAGES/fdroidserver.po b/locale/sq/LC_MESSAGES/fdroidserver.po index 80340a99..a90be56f 100644 --- a/locale/sq/LC_MESSAGES/fdroidserver.po +++ b/locale/sq/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-04-26 19:11+0000\n" "Last-Translator: Besnik Bleta \n" "Language-Team: Albanian \n" @@ -378,24 +378,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "S’montohet dot, për shkak të {} gabimi teksa skanohej" msgstr[1] "S’montohet dot, për shkak të {} gabimeve teksa skanohej" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "S’gjendet dot një packageName për {path}!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "S’gjendet dot një appid për {path}!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "S’lexohet dot \"${path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "S’ftillohet dot ID aplikacioni {appid}" #: ../fdroidserver/rewritemeta.py @@ -492,6 +484,7 @@ msgstr "S’u hap dot kartela apk për analizim" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1013,6 +1006,12 @@ msgstr "APK e pavlefshme" msgid "Invalid VercodeOperation: {field}" msgstr "VercodeOperationi pavlefshëm: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "VercodeOperationi pavlefshëm: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1121,8 +1120,9 @@ msgid "Keystore for signing key:\t" msgstr "Depo kyçesh për kyç nënshkrimi:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Parashtrimi '{commit}' i përdorur së fundi duket si etiketë, por si Mënyrë Kontrolli Përditësimesh është '{ucm}'" #: ../fdroidserver/lint.py @@ -1883,8 +1883,11 @@ msgstr "Kartelë e papërdorur te %s" msgid "Unused scanignore path: %s" msgstr "Kartelë e papërdorur te %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" #: ../fdroid ../fdroidserver/__main__.py @@ -1918,6 +1921,12 @@ msgstr "UpdateCheckData duhet të përdorë URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData s’është URL e vlefshme: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2064,6 +2073,21 @@ msgstr "mundësi e dykuptimtë: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId për të cilin të kontrollohet për përditësime" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId me versionCode opsional në formën APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId në formën e APPID" @@ -2558,6 +2582,12 @@ msgstr "{apkfilename} ka shumë kartela {name}, duket si rreng me Kyçin e Përg msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml e {apkfilename} ka një datë të gabuar: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} s’ka emër! Në vend të tij po përdoret emër pakete." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2568,6 +2598,12 @@ msgstr "{appid} s’ka emër! Në vend të tij po përdoret emër pakete." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} prej {path} s’është Emër i vlefshëm Pakete Android!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{appid} prej {path} s’është Emër i vlefshëm Pakete Android!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2665,3 +2701,9 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} doli me sukses" msgstr[1] "{} dolën me sukses" + +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "S’gjendet dot një packageName për {path}!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "S’gjendet dot një appid për {path}!" diff --git a/locale/sv/LC_MESSAGES/fdroidserver.po b/locale/sv/LC_MESSAGES/fdroidserver.po index 70f6ba3c..e742cba5 100644 --- a/locale/sv/LC_MESSAGES/fdroidserver.po +++ b/locale/sv/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2018-10-14 14:43+0000\n" "Last-Translator: Jonatan Nyberg \n" "Language-Team: Swedish \n" @@ -371,24 +371,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -483,6 +474,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -998,6 +990,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1107,7 +1104,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1864,8 +1861,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1899,6 +1897,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2045,6 +2047,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2538,6 +2551,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2548,6 +2566,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index 79c8ebef..fe4f8c2d 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" @@ -382,24 +382,16 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Tarama sırasında {} hata nedeniyle inşa edilemiyor" msgstr[1] "Tarama sırasında {} hata nedeniyle inşa edilemiyor" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "{path} için bir packageName bulunamıyor!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "{path} için bir appid bulunamıyor!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "\"{path}\" okunamıyor!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "App id {appid} çözülemiyor" #: ../fdroidserver/rewritemeta.py @@ -494,6 +486,7 @@ msgstr "İnceleme için apk dosyası açılamadı" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "\"{size}\" boyutu ayrıştırılamadı, yanlış tür \"{type}\"" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "Uygulama kimliği bulunamadı" @@ -1013,6 +1006,12 @@ msgstr "Geçersiz APK" msgid "Invalid VercodeOperation: {field}" msgstr "Geçersiz Vercode İşlemi: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "Geçersiz Vercode İşlemi: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1121,8 +1120,9 @@ msgid "Keystore for signing key:\t" msgstr "İmzalama için anahtar deposu:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Son kullanılan işleme '{commit}' bir etiket gibi görünüyor, ama güncelleme denetleme kipi '{ucm}'" #: ../fdroidserver/lint.py @@ -1879,8 +1879,11 @@ msgstr "Kullanılmayan scandelete yolu: %s" msgid "Unused scanignore path: %s" msgstr "Kullanılmayan scanignore yolu: %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "Update Check Name bilinen app id'ye ayarlı - kaldırılabilir" #: ../fdroid ../fdroidserver/__main__.py @@ -1914,6 +1917,12 @@ msgstr "UpdateCheckData, HTTPS URL'sini kullanmalıdır: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData geçerli bir URL değil: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "Update Check Name bilinen app id'ye ayarlı - kaldırılabilir" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2060,6 +2069,21 @@ msgstr "belirsiz şeçenek: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "apksigner bulunamadı, imzalamak için gereklidir!" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "Güncellemeleri denetlemek için applicationId" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "APPID[:VERCODE] biçiminde applicationId, isteğe bağlı versionCode ile" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "APPID biçiminde applicationId" @@ -2553,6 +2577,12 @@ msgstr "{apkfilename} içinde birden çok {name} dosyası var, Master Key istisa msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "{apkfilename} içindeki AndroidManifest.xml tarihi bozuk: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} adsız! Onun yerine paket adı kullanılıyor." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2563,6 +2593,12 @@ msgstr "{appid} adsız! Onun yerine paket adı kullanılıyor." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{path}'den {appid} geçerli bir Android Paket Adı değil!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{path}'den {appid} geçerli bir Android Paket Adı değil!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2661,6 +2697,12 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} inşa başarılı" msgstr[1] "{} inşa başarılı" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "{path} için bir packageName bulunamıyor!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "{path} için bir appid bulunamıyor!" + #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Depodaki paketler için GPG imzaları ekle" diff --git a/locale/ug/LC_MESSAGES/fdroidserver.po b/locale/ug/LC_MESSAGES/fdroidserver.po index fda6cb7f..3c5fa0cd 100644 --- a/locale/ug/LC_MESSAGES/fdroidserver.po +++ b/locale/ug/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2018-06-08 03:44+0000\n" "Last-Translator: ۋولقان \n" "Language-Team: Uyghur \n" @@ -371,24 +371,15 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -483,6 +474,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "" @@ -998,6 +990,12 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "no \"icon\" in {appid}" +msgid "Invalid application ID {appid}" +msgstr "{appid} ئىچىدە \"سىنبەلگە\" تېپىلمىدى" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1107,7 +1105,7 @@ msgstr "" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1864,8 +1862,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1899,6 +1898,10 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2045,6 +2048,17 @@ msgstr "" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "" @@ -2538,6 +2552,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2548,6 +2567,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index 7ccd4ba6..1f58d2dd 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-02 19:15+0000\n" "Last-Translator: ihor_ck \n" "Language-Team: Ukrainian \n" @@ -385,24 +385,16 @@ msgstr[0] "Неможливо створити через {} помилку пі msgstr[1] "Неможливо створити через {} помилки під час сканування" msgstr[2] "Неможливо створити через {} помилок під час сканування" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "Неможливо знайти packageName за шляхом {path}!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "Не вдається знайти appid за шляхом {path}!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "Неправильно вказано шлях \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "Неможливо розв'язати id застосунку {appid}" #: ../fdroidserver/rewritemeta.py @@ -497,6 +489,7 @@ msgstr "Не вдалося відкрити файл apk для аналізу" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "Не вдалося проаналізувати розмір \"{size}\", неправильний тип \"{type}\"" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "Не вдалося знайти ID застосунку" @@ -1016,6 +1009,12 @@ msgstr "Недійсний APK" msgid "Invalid VercodeOperation: {field}" msgstr "Недійсна VercodeOperation: {field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "Недійсна VercodeOperation: {field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1124,8 +1123,9 @@ msgid "Keystore for signing key:\t" msgstr "Шлях до сховища ключів для ключа підпису сховища\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Останнє подання '{commit}' виглядає як мітка, але в режимі перевірки оновлення '{ucm}'" #: ../fdroidserver/lint.py @@ -1883,8 +1883,11 @@ msgstr "Невикористаний шлях scandelete: %s" msgid "Unused scanignore path: %s" msgstr "Невикористаний шлях scanignore: %s" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "Назву застосунку для перевірки оновлень встановлено на відомий id застосунку - його можна буде вилучити" #: ../fdroid ../fdroidserver/__main__.py @@ -1918,6 +1921,12 @@ msgstr "UpdateCheckData має використовувати URL-адресу H msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData не є дійсною URL-адресою: {url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "Назву застосунку для перевірки оновлень встановлено на відомий id застосунку - його можна буде вилучити" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2064,6 +2073,21 @@ msgstr "неоднозначний параметр: %s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "apksigner не знайдено, це потрібно для підписання!" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "applicationId для перевірки наявності оновлень" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId з необов'язковим versionCode у формі APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId у формі APPID" @@ -2560,6 +2584,12 @@ msgstr "{apkfilename} має декілька {name} файлів, схоже н msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml застосунка {apkfilename} має неправильну дату: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} не має назви! Використовуватимуться назви пакунку." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2570,6 +2600,12 @@ msgstr "{appid} не має назви! Використовуватимутьс msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} з {path} є недійсною назвою пакунка Android!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "{appid} з {path} є недійсною назвою пакунка Android!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2670,6 +2706,12 @@ msgstr[0] "{} зібрано успішно" msgstr[1] "{} зібрано успішно" msgstr[2] "{} зібрано успішно" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Неможливо знайти packageName за шляхом {path}!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Не вдається знайти appid за шляхом {path}!" + #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Додайте підписи gpg для пакетів у репозиторії" diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index 8b0e9a62..a8ce5478 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-02 19:15+0000\n" "Last-Translator: Eric \n" "Language-Team: Chinese (Simplified) \n" @@ -378,24 +378,15 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, python-brace-format -msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "" #: ../fdroidserver/rewritemeta.py @@ -490,6 +481,7 @@ msgstr "" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py msgid "Couldn't find Application ID" msgstr "找不到应用程序ID" @@ -1005,6 +997,11 @@ msgstr "" msgid "Invalid VercodeOperation: {field}" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1114,7 +1111,7 @@ msgstr "签名密钥的密钥库:\t" #: ../fdroidserver/lint.py #, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "" #: ../fdroidserver/lint.py @@ -1870,8 +1867,9 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "" #: ../fdroid ../fdroidserver/__main__.py @@ -1905,6 +1903,10 @@ msgstr "UpdateCheckData必须使用HTTPS URL:{url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2051,6 +2053,21 @@ msgstr "不明确的选项:%s(%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "检查更新的applicationId" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "带有可选 versionCode 的 app-id,格式:APPID[:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "app-id,格式:APPID" @@ -2541,6 +2558,11 @@ msgstr "" msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2551,6 +2573,11 @@ msgstr "" msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "" +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index 5daf4083..ad8fbda6 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:34+0200\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" "PO-Revision-Date: 2020-10-01 09:00+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Chinese (Traditional) \n" @@ -377,24 +377,16 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "掃描時由於 {} 出錯,無法進行編譯" -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find a packageName for {path}!" -msgstr "路徑 {path} 找不到套件名稱!" - -#: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot find an appid for {path}!" -msgstr "找不到 {path} 的 appid!" - #: ../fdroidserver/vmtools.py #, python-brace-format msgid "Cannot read \"{path}\"!" msgstr "無法讀取 \"{path}\"!" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, python-brace-format -msgid "Cannot resolve app id {appid}" +#, fuzzy, python-brace-format +#| msgid "Cannot resolve app id {appid}" +msgid "Cannot resolve application ID {appid}" msgstr "無法解析 {appid} id" #: ../fdroidserver/rewritemeta.py @@ -491,6 +483,7 @@ msgstr "無法開啟 apk 檔案作分析" msgid "Could not parse size \"{size}\", wrong type \"{type}\"" msgstr "" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py #, fuzzy msgid "Couldn't find Application ID" @@ -1012,6 +1005,12 @@ msgstr "無效的 APK" msgid "Invalid VercodeOperation: {field}" msgstr "無效的 VercodeOperation:{field}" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +#| msgid "Invalid VercodeOperation: {field}" +msgid "Invalid application ID {appid}" +msgstr "無效的 VercodeOperation:{field}" + #: ../fdroidserver/metadata.py #, python-format msgid "Invalid boolean '%s'" @@ -1120,8 +1119,9 @@ msgid "Keystore for signing key:\t" msgstr "金鑰庫的簽署金鑰:\t" #: ../fdroidserver/lint.py -#, python-brace-format -msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, fuzzy, python-brace-format +#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "最近採用的提交 '{commit}' 似乎是一個標籤,但更新的檢查模式為 '{ucm}'" #: ../fdroidserver/lint.py @@ -1881,8 +1881,11 @@ msgstr "在 %s 未使用的檔案" msgid "Unused scanignore path: %s" msgstr "在 %s 未使用的檔案" +#. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -msgid "Update Check Name is set to the known app id - it can be removed" +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID - it can be removed" msgstr "更新 Check Name 被設定成已知的應用 id - 它可以被移除" #: ../fdroid ../fdroidserver/__main__.py @@ -1916,6 +1919,12 @@ msgstr "UpdateCheckData 必須使用 HTTPS URL:{url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData 不是有效的 URL:{url}" +#: ../fdroidserver/lint.py +#, fuzzy +#| msgid "Update Check Name is set to the known app id - it can be removed" +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "更新 Check Name 被設定成已知的應用 id - 它可以被移除" + #: ../fdroidserver/server.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" @@ -2062,6 +2071,21 @@ msgstr "不明確的選項:%s (%s?)" msgid "apksigner not found, it's required for signing!" msgstr "" +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +#, fuzzy +#| msgid "applicationId to check for updates" +msgid "application ID of file to operate on" +msgstr "以 applicationId 檢查更新" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +#, fuzzy +#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "applicationId 具有任選的 versionCode 在此格式為 APPID [:VERCODE]" + #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" msgstr "applicationId 格式為 APPID" @@ -2553,6 +2577,12 @@ msgstr "{apkfilename} 有多個 {name} 檔案,看起來可能是主金鑰洩 msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "{apkfilename} AndroidManifest.xml 有一個無效的日期: " +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} does not have a name! Using package name instead." +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid}沒有名字! 使用套件名代替." + #: ../fdroidserver/update.py #, python-brace-format msgid "{appid} does not have a name! Using package name instead." @@ -2563,6 +2593,12 @@ msgstr "{appid}沒有名字! 使用套件名代替." msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "來自 {path} 的 {appid} 並不是一個有效的 android 套件名稱!" +#: ../fdroidserver/update.py +#, fuzzy, python-brace-format +#| msgid "{appid} from {path} is not a valid Android Package Name!" +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "來自 {path} 的 {appid} 並不是一個有效的 android 套件名稱!" + #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" @@ -2659,6 +2695,12 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} 編譯成功" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "路徑 {path} 找不到套件名稱!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "找不到 {path} 的 appid!" + #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "在軟體倉庫中加入套件包的 gpg 簽署" From 406a0ce8bc8033d7b30746a23051dd4d3087c315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Sat, 17 Oct 2020 07:19:39 +0200 Subject: [PATCH 0578/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Turki?= =?UTF-8?q?sh=20(tr)=20by=20O=C4=9Fuz=20Ersen=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (569 of 569 strings) Co-authored-by: Oğuz Ersen Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/tr/ Translation: F-Droid/F-Droid Server --- locale/tr/LC_MESSAGES/fdroidserver.po | 43 ++++++++++----------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index fe4f8c2d..320a615e 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"PO-Revision-Date: 2020-10-08 06:06+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" "Language: tr\n" @@ -389,10 +389,9 @@ msgstr "\"{path}\" okunamıyor!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" +#, python-brace-format msgid "Cannot resolve application ID {appid}" -msgstr "App id {appid} çözülemiyor" +msgstr "Uygulama kimliği {appid} çözümlenemiyor" #: ../fdroidserver/rewritemeta.py #, python-brace-format @@ -1007,10 +1006,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "Geçersiz Vercode İşlemi: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "Geçersiz Vercode İşlemi: {field}" +msgstr "Geçersiz uygulama kimliği {appid}" #: ../fdroidserver/metadata.py #, python-format @@ -1120,10 +1118,9 @@ msgid "Keystore for signing key:\t" msgstr "İmzalama için anahtar deposu:\t" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, python-brace-format msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" -msgstr "Son kullanılan işleme '{commit}' bir etiket gibi görünüyor, ama güncelleme denetleme kipi '{ucm}'" +msgstr "Son kullanılan işleme '{commit}' bir etiket gibi görünüyor, ama UpdateCheckMode '{ucm}'" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the Liberapay: field" @@ -1881,10 +1878,8 @@ msgstr "Kullanılmayan scanignore yolu: %s" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Update Check Name bilinen app id'ye ayarlı - kaldırılabilir" +msgstr "UpdateCheckName bilinen uygulama kimliğine ayarlı - kaldırılabilir" #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" @@ -1918,10 +1913,8 @@ msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData geçerli bir URL değil: {url}" #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" -msgstr "Update Check Name bilinen app id'ye ayarlı - kaldırılabilir" +msgstr "UpdateCheckName bilinen uygulama kimliğine ayarlı - kaldırılabilir" #: ../fdroidserver/server.py #, python-brace-format @@ -2071,18 +2064,14 @@ msgstr "apksigner bulunamadı, imzalamak için gereklidir!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py -#, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" -msgstr "Güncellemeleri denetlemek için applicationId" +msgstr "üzerinde işlem yapılacak dosyanın uygulama kimliği" #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py -#, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" -msgstr "APPID[:VERCODE] biçiminde applicationId, isteğe bağlı versionCode ile" +msgstr "UYGULAMA_KİMLİĞİ[:SÜRÜM_KODU] biçiminde isteğe bağlı versionCode ile uygulama kimliği" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2578,10 +2567,9 @@ msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "{apkfilename} içindeki AndroidManifest.xml tarihi bozuk: " #: ../fdroidserver/update.py -#, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." +#, python-brace-format msgid "{appid} does not have a name! Using application ID instead." -msgstr "{appid} adsız! Onun yerine paket adı kullanılıyor." +msgstr "{appid} bir ada sahip değil! Bunun yerine uygulama kimliği kullanılıyor." #: ../fdroidserver/update.py #, python-brace-format @@ -2594,10 +2582,9 @@ msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{path}'den {appid} geçerli bir Android Paket Adı değil!" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" +#, python-brace-format msgid "{appid} from {path} is not a valid Android application ID!" -msgstr "{path}'den {appid} geçerli bir Android Paket Adı değil!" +msgstr "{path}'den {appid} geçerli bir Android uygulama kimliği değil!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format From 46e0ef09c1381ba50d187037f81ec1d0391a7ab1 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 17 Oct 2020 07:19:39 +0200 Subject: [PATCH 0579/2775] Translated using Weblate: Chinese (Simplified) (zh_Hans) by Eric Currently translated at 33.7% (192 of 569 strings) Co-authored-by: Eric Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hans/ Translation: F-Droid/F-Droid Server --- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index a8ce5478..e7e797b9 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-02 19:15+0000\n" +"PO-Revision-Date: 2020-10-08 06:06+0000\n" "Last-Translator: Eric \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" @@ -2055,18 +2055,14 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py -#, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" -msgstr "检查更新的applicationId" +msgstr "要操作的文件的应用程序ID" #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py -#, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" -msgstr "带有可选 versionCode 的 app-id,格式:APPID[:VERCODE]" +msgstr "带APPID[:VERCODE]格式可选的versionCode的应用程序 ID" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" From 790c385f9a5669e8b7c49ccde6ac19f69098c1ec Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Sat, 17 Oct 2020 07:19:40 +0200 Subject: [PATCH 0580/2775] Translated using Weblate: Ukrainian (uk) by ihor_ck Currently translated at 100.0% (569 of 569 strings) Co-authored-by: ihor_ck Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/uk/ Translation: F-Droid/F-Droid Server --- locale/uk/LC_MESSAGES/fdroidserver.po | 39 +++++++++------------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index 1f58d2dd..166df0ab 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-02 19:15+0000\n" +"PO-Revision-Date: 2020-10-08 06:06+0000\n" "Last-Translator: ihor_ck \n" "Language-Team: Ukrainian \n" "Language: uk\n" @@ -392,8 +392,7 @@ msgstr "Неправильно вказано шлях \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" +#, python-brace-format msgid "Cannot resolve application ID {appid}" msgstr "Неможливо розв'язати id застосунку {appid}" @@ -1010,10 +1009,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "Недійсна VercodeOperation: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "Недійсна VercodeOperation: {field}" +msgstr "Недійсний ID застосунку {appid}" #: ../fdroidserver/metadata.py #, python-format @@ -1123,8 +1121,7 @@ msgid "Keystore for signing key:\t" msgstr "Шлях до сховища ключів для ключа підпису сховища\t" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, python-brace-format msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Останнє подання '{commit}' виглядає як мітка, але в режимі перевірки оновлення '{ucm}'" @@ -1885,10 +1882,8 @@ msgstr "Невикористаний шлях scanignore: %s" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Назву застосунку для перевірки оновлень встановлено на відомий id застосунку - його можна буде вилучити" +msgstr "Назву застосунку для перевірки оновлень встановлено на відомий ID застосунку — його можна буде вилучити" #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" @@ -1922,10 +1917,8 @@ msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData не є дійсною URL-адресою: {url}" #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" -msgstr "Назву застосунку для перевірки оновлень встановлено на відомий id застосунку - його можна буде вилучити" +msgstr "Назву застосунку для перевірки оновлень встановлено на відомий ID застосунку — його можна буде вилучити" #: ../fdroidserver/server.py #, python-brace-format @@ -2075,18 +2068,14 @@ msgstr "apksigner не знайдено, це потрібно для підпи #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py -#, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" -msgstr "applicationId для перевірки наявності оновлень" +msgstr "application ID файлу застосунку для роботи на" #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py -#, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" -msgstr "applicationId з необов'язковим versionCode у формі APPID[:VERCODE]" +msgstr "ID застосунку з необов'язковим versionCode у формі APPID[:VERCODE]" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2585,10 +2574,9 @@ msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml застосунка {apkfilename} має неправильну дату: " #: ../fdroidserver/update.py -#, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." +#, python-brace-format msgid "{appid} does not have a name! Using application ID instead." -msgstr "{appid} не має назви! Використовуватимуться назви пакунку." +msgstr "{appid} не має назви! Застосовуватиметься ID застосунку." #: ../fdroidserver/update.py #, python-brace-format @@ -2601,10 +2589,9 @@ msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} з {path} є недійсною назвою пакунка Android!" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" +#, python-brace-format msgid "{appid} from {path} is not a valid Android application ID!" -msgstr "{appid} з {path} є недійсною назвою пакунка Android!" +msgstr "{appid} з {path} є недійсним ID застосунку Android!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format From 47ad13e6e5920f3197efc4b896f622c6dd40cc70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sat, 17 Oct 2020 07:19:40 +0200 Subject: [PATCH 0581/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l=20(nb=5FNO)=20by=20Allan=20Nordh=C3=B8y=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 60.1% (342 of 569 strings) Translated using Weblate: Norwegian Bokmål (nb_NO) by Allan Nordhøy Currently translated at 60.1% (342 of 569 strings) Co-authored-by: Allan Nordhøy Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/nb_NO/ Translation: F-Droid/F-Droid Server --- locale/nb_NO/LC_MESSAGES/fdroidserver.po | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index 6f9f99c8..6fe4f914 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.8-74-ga380b9f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-02 19:15+0000\n" +"PO-Revision-Date: 2020-10-14 09:28+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" "Language: nb_NO\n" @@ -80,9 +80,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" finnes, men s3cmd er ikke installert!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" er ikke et godtatt format, konverter til: {formats}" +msgstr "\"{path}\" er ikke et støttet filformat. (bruk: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -887,9 +887,9 @@ msgid "Found non-file at %s" msgstr "Fant ikke-fil i %s" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "kopierer {apkfilename} inn i {path}" +msgstr "Fant {apkfilename} i {url}" #: ../fdroidserver/update.py #, python-brace-format @@ -917,7 +917,7 @@ msgstr "Git set-head annensteds hen mislyktes" #: ../fdroidserver/common.py #, fuzzy, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Git set-head annensteds hen mislyktes" +msgstr "Git set-head annensteds hen mislyktes: «%s»" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -1032,10 +1032,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "Ugyldig VercodeOperation: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "Ugyldig VercodeOperation: {field}" +msgstr "Ugyldig program-ID {appid}" #: ../fdroidserver/metadata.py #, fuzzy, python-format @@ -1091,9 +1090,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Ugyldig videresending til ikke-HTTPS: {before} → {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Les alle metadatafilene og avslutt" +msgstr "Ugyldig scrlib-metadata: «{file}» finnes ikke" #: ../fdroidserver/metadata.py #, python-brace-format From eb21b17959f05ea55ca66c64432d3ba901285d2d Mon Sep 17 00:00:00 2001 From: Renaud Perrai Date: Sat, 17 Oct 2020 07:19:40 +0200 Subject: [PATCH 0582/2775] Translated using Weblate: French (fr) by Renaud Perrai Currently translated at 70.8% (403 of 569 strings) Translated using Weblate: French (fr) by Renaud Perrai Currently translated at 69.5% (396 of 569 strings) Co-authored-by: Renaud Perrai Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/fr/ Translation: F-Droid/F-Droid Server --- locale/fr/LC_MESSAGES/fdroidserver.po | 58 +++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 95255e01..4d0b179c 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -15,13 +15,14 @@ # Coucouf , 2020. # Alexandre Hô , 2020. # Yldun , 2020. +# Renaud Perrai , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-06 08:26+0000\n" -"Last-Translator: Yldun \n" +"PO-Revision-Date: 2020-10-08 15:24+0000\n" +"Last-Translator: Renaud Perrai \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -40,9 +41,9 @@ msgid "" " " msgstr "" "\n" -" Ceci est un dépôt d’apps à utiliser avec FDroid. Les applications publiées\n" -" dans ce dépôt sont soit les binaires officiels construits par les développeurs\n" -" de ces applications, soit des binaires construits par f-droid.org à partir des\n" +" Ceci est un dépôt d’applications à utiliser avec FDroid. Les applications publiées\n" +" dans ce dépôt sont soit celles compilées par les développeurs\n" +" de ces applications, soit celles compilées par f-droid.org à partir des\n" " sources en utilisant les outils disponibles sur https://gitlab.com/fdroid.\n" " " @@ -353,7 +354,7 @@ msgstr "Branche « {branch} » utilisée comme commit dans le build « {versionN #: ../fdroidserver/lint.py #, python-brace-format msgid "Branch '{branch}' used as commit in srclib '{srclib}'" -msgstr "Branche « {branch} » utilisée comme commit dans srclib « {srclib} »" +msgstr "La branche « {branch} » est utilisée comme commit dans srclib « {srclib} »" #: ../fdroidserver/update.py #, python-brace-format @@ -420,7 +421,7 @@ msgstr "Impossible d'utiliser --list et --to en même temps" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" -msgstr "Impossible d'écrire « {path} », format non accepté. Merci d'utiliser : {formats}" +msgstr "Impossible d'écrire \"{path}\", le format n'est pas accepté. Merci d'utiliser : {formats}" #: ../fdroidserver/lint.py #, python-format @@ -476,7 +477,7 @@ msgstr "Conflit d'arguments : '--verbose' et '--quiet' ne peuvent être choisis #: ../fdroidserver/common.py #, python-brace-format msgid "Could not find '{command}' on your system" -msgstr "Impossible de trouver « {command} » sur votre système" +msgstr "Impossible de trouver '{command}' sur votre système" #: ../fdroidserver/import.py msgid "Could not find latest version code" @@ -489,7 +490,7 @@ msgstr "Impossible de trouver le nom de la dernière version" #: ../fdroidserver/update.py #, python-brace-format msgid "Could not find {path} to remove it" -msgstr "Chemin {path} non trouvé pour suppression" +msgstr "Chemin {path} introuvable pour sa suppression" #: ../fdroidserver/update.py msgid "Could not open apk file for analysis" @@ -879,9 +880,9 @@ msgid "Found non-file at %s" msgstr "Aucun fichier trouvée a %s" #: ../fdroidserver/server.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "Traitement de {apkfilename}" +msgstr "{apkfilename} trouvé à {url}" #: ../fdroidserver/update.py #, python-brace-format @@ -906,9 +907,9 @@ msgid "Git remote set-head failed" msgstr "Set-head distant du Git à échouer" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Set-head distant du Git à échouer" +msgstr "Impossible de définir la branche par défaut du Git distant : \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -943,7 +944,7 @@ msgstr "Ignore '{field}' dans les métadonnées '{metapath}' parce que c'est dé #: ../fdroidserver/update.py #, python-format msgid "Ignoring FUNDING.yml entry longer than 2048: %s" -msgstr "Ignore l'entrée FUNDING.yml si elle excède 2048: %s" +msgstr "Ignorer l'entrée FUNDING.yml supérieure à 2048 : %s" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -1021,10 +1022,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "VercodeOperation non valide : {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "VercodeOperation non valide : {field}" +msgstr "ID de l'application invalide {appid}" #: ../fdroidserver/metadata.py #, python-format @@ -1141,7 +1141,7 @@ msgstr "Le dernier archivage utiliser '{commit}' ressemble a une balise, mais le #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the Liberapay: field" -msgstr "Les méthodes de don via Liberapay font parties de Liberapay: field" +msgstr "Les méthodes de don via Liberapay font partie de Liberapay : field" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" @@ -1169,7 +1169,7 @@ msgstr "serverwebroot malformer en ligne :" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." -msgstr "" +msgstr "Cloner entièrement le repo et les archives, tous les fichiers." #: ../fdroidserver/gpgsign.py msgid "Missing output directory" @@ -1265,7 +1265,7 @@ msgstr "Aucun dossier signée - rien n'est a faire" #: ../fdroidserver/common.py msgid "Not a valid size definition: \"{}\"" -msgstr "" +msgstr "Définition de la taille invalide : \"{}\"" #: ../fdroidserver/signindex.py msgid "Nothing to do" @@ -2139,9 +2139,9 @@ msgid "can't open '%s': %s" msgstr "Impossible d'ouvrir %s : %s" #: ../fdroidserver/build.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "cannot find required srclibs: \"{path}\"" -msgstr "Impossible de trouver un appid pour {path} !" +msgstr "Impossible de trouver srclibs : \"{path}\"" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2686,29 +2686,29 @@ msgstr "" #: ../fdroidserver/server.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" -msgstr "" +msgstr "{path} supérieur à 200MB, envoi manuel : {url}" #: ../fdroidserver/mirror.py #, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" -msgstr "" +msgstr "{url} ne fini pas par \"fdroid\", vérifiez l'URL !" #: ../fdroidserver/common.py #, python-brace-format msgid "{url} does not start with \"http\"!" -msgstr "" +msgstr "{url} ne commence pas par \"http\" !" #: ../fdroidserver/build.py msgid "{} build failed" msgid_plural "{} builds failed" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "{} compilation échouée" +msgstr[1] "{} compilations échouées" #: ../fdroidserver/build.py msgid "{} build succeeded" msgid_plural "{} builds succeeded" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "{} compilation réussie" +msgstr[1] "{} compilations réussies" #~ msgid "Cannot find a packageName for {path}!" #~ msgstr "Impossible de trouver un packageName pour {path} !" From 4a8db4e283e499aa534be8197243339c21654dd5 Mon Sep 17 00:00:00 2001 From: ssantos Date: Sat, 17 Oct 2020 07:19:41 +0200 Subject: [PATCH 0583/2775] Translated using Weblate: Portuguese (pt) by ssantos Currently translated at 100.0% (569 of 569 strings) Translated using Weblate: Portuguese (Portugal) (pt_PT) by ssantos Currently translated at 100.0% (569 of 569 strings) Co-authored-by: ssantos Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_PT/ Translation: F-Droid/F-Droid Server --- locale/pt/LC_MESSAGES/fdroidserver.po | 47 ++++++++---------------- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 43 ++++++++-------------- 2 files changed, 31 insertions(+), 59 deletions(-) diff --git a/locale/pt/LC_MESSAGES/fdroidserver.po b/locale/pt/LC_MESSAGES/fdroidserver.po index b7f38aab..ebab6be0 100644 --- a/locale/pt/LC_MESSAGES/fdroidserver.po +++ b/locale/pt/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"PO-Revision-Date: 2020-10-14 09:28+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -389,8 +389,7 @@ msgstr "Não é possível ler \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" +#, python-brace-format msgid "Cannot resolve application ID {appid}" msgstr "Não é possível resolver o ID da app {appid}" @@ -947,7 +946,7 @@ msgstr "Ignorando o ficheiro {ext} em '{path}'" #: ../fdroidserver/update.py msgid "Include APKs that are signed with disabled algorithms like MD5" -msgstr "Incluir APKs assinados com algoritmos desabilitados como MD5" +msgstr "Incluir APKs assinados com algoritmos desativados como MD5" #: ../fdroidserver/mirror.py msgid "Include the PGP signature .asc files in the mirror" @@ -1007,10 +1006,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "VercodeOperation inválido: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "VercodeOperation inválido: {field}" +msgstr "ID da aplicação {appid} inválido" #: ../fdroidserver/metadata.py #, python-format @@ -1120,10 +1118,9 @@ msgid "Keystore for signing key:\t" msgstr "Armazenamento de chaves de assinatura:\t" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, python-brace-format msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" -msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o modo de verificação de atualização é '{ucm}'" +msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o UpdateCheckMode (modo de verificação de atualização) é '{ucm}'" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the Liberapay: field" @@ -1733,10 +1730,8 @@ msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in con msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser definidos no config.py!" #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "UCM is set but it looks like checkupdates hasn't been run yet" msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UCM é definido, mas parece que checkupdates ainda não foi executado" +msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" @@ -1883,10 +1878,8 @@ msgstr "O caminho de scanignore não é usado: %s" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" +msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comum da aplicação - pode ser removido" #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" @@ -1920,10 +1913,8 @@ msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" -msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" +msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comun da aplicação - pode ser removido" #: ../fdroidserver/server.py #, python-brace-format @@ -2073,18 +2064,14 @@ msgstr "Nenhum apksigner encontrado, é necessário para assinar!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py -#, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" -msgstr "applicationId para verificar se há atualizações" +msgstr "ID de aplicação do ficheiro para operar" #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py -#, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" -msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" +msgstr "applicationID com versionCode opcional na forma APPID[:VERCODE]" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2580,10 +2567,9 @@ msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml do {apkfilename} tem uma data má: " #: ../fdroidserver/update.py -#, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." +#, python-brace-format msgid "{appid} does not have a name! Using application ID instead." -msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." +msgstr "{appid} não tem um nome! A usar o ID da aplicação em vez disso." #: ../fdroidserver/update.py #, python-brace-format @@ -2596,10 +2582,9 @@ msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} from {path} não é um nome de pacote Android válido!" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" +#, python-brace-format msgid "{appid} from {path} is not a valid Android application ID!" -msgstr "{appid} from {path} não é um nome de pacote Android válido!" +msgstr "{appid} de {path} não é um ID de aplicação Android válido!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index 46991e02..426e2673 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"PO-Revision-Date: 2020-10-14 09:28+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese (Portugal) \n" "Language: pt_PT\n" @@ -392,10 +392,9 @@ msgstr "Não é possível ler \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" +#, python-brace-format msgid "Cannot resolve application ID {appid}" -msgstr "Não é possível resolver o ID da app {appid}" +msgstr "Não é possível resolver o ID da applicação {appid}" #: ../fdroidserver/rewritemeta.py #, python-brace-format @@ -1010,10 +1009,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "VercodeOperation inválido: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "VercodeOperation inválido: {field}" +msgstr "ID da aplicação {appid} inválido" #: ../fdroidserver/metadata.py #, python-format @@ -1123,10 +1121,9 @@ msgid "Keystore for signing key:\t" msgstr "Armazenamento de chaves de assinatura:\t" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" +#, python-brace-format msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" -msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o modo de verificação de atualização é '{ucm}'" +msgstr "O último commit usado '{commit}' parece-se com uma tag, mas o UpdateCheckMode (modo de verificação de atualização) é '{ucm}'" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the Liberapay: field" @@ -1884,10 +1881,8 @@ msgstr "O caminho de scanignore não é usado: %s" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" +msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comum da aplicação - pode ser removido" #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" @@ -1921,10 +1916,8 @@ msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" #: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" -msgstr "O nome da verificação de atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" +msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comun da aplicação - pode ser removido" #: ../fdroidserver/server.py #, python-brace-format @@ -2074,18 +2067,14 @@ msgstr "Nenhum apksigner encontrado, é necessário para assinar!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py -#, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" -msgstr "applicationId para verificar se há atualizações" +msgstr "ID de aplicação do ficheiro para operar" #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py -#, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" -msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" +msgstr "applicationID com versionCode opcional na forma APPID[:VERCODE]" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2581,10 +2570,9 @@ msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml do {apkfilename} tem uma data má: " #: ../fdroidserver/update.py -#, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." +#, python-brace-format msgid "{appid} does not have a name! Using application ID instead." -msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." +msgstr "{appid} não tem um nome! A usar o ID da aplicação em vez disso." #: ../fdroidserver/update.py #, python-brace-format @@ -2597,10 +2585,9 @@ msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} from {path} não é um nome de pacote Android válido!" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" +#, python-brace-format msgid "{appid} from {path} is not a valid Android application ID!" -msgstr "{appid} from {path} não é um nome de pacote Android válido!" +msgstr "{appid} de {path} não é um ID de aplicação Android válido!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format From 60ca80ff4efdcf1141bc0f2efaf9386212aec6bb Mon Sep 17 00:00:00 2001 From: random r Date: Sat, 17 Oct 2020 07:19:41 +0200 Subject: [PATCH 0584/2775] Translated using Weblate: Italian (it) by random r Currently translated at 34.6% (197 of 569 strings) Co-authored-by: random r Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/it/ Translation: F-Droid/F-Droid Server --- locale/it/LC_MESSAGES/fdroidserver.po | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index aa3aec38..e8920b7f 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-01 11:26+0000\n" -"Last-Translator: Massimiliano Caniparoli \n" +"PO-Revision-Date: 2020-10-14 09:28+0000\n" +"Last-Translator: random r \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" @@ -282,9 +282,8 @@ msgid "Android APK file" msgstr "" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "Android SDK non trovato!" +msgstr "Codice DEX Android" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -400,9 +399,9 @@ msgid "Cannot resolve application ID {appid}" msgstr "Impossibile trovare l'app id {appid}" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "Impossibile leggere \"{path}\"!" +msgstr "Impossibile riscrivere \"{path}\"" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -992,9 +991,9 @@ msgid "Installing %s…" msgstr "" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Installing '{apkfilename}' on {dev}..." -msgstr "Impossibile installare '{apkfilename}' su {dev}: {error}" +msgstr "Installazione di '{apkfilename}' su {dev}..." #: ../fdroidserver/install.py #, python-brace-format @@ -1072,9 +1071,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Leggi tutti i file di metadata ed esci" +msgstr "Metadati scrlib non validi: '{file}' non esiste" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1663,9 +1662,9 @@ msgid "Striping mystery signature from {apkfilename}" msgstr "" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Stripping mystery signature from {apkfilename}" -msgstr "Impossibile recuperare le firme per '{apkfilename}': {error}" +msgstr "Riduzione della firma misteriosa da {apkfilename}" #: ../fdroidserver/lint.py #, python-format @@ -2122,9 +2121,9 @@ msgid "can't open '%s': %s" msgstr "impossibile aprire \"%s\": %s" #: ../fdroidserver/build.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "cannot find required srclibs: \"{path}\"" -msgstr "Impossibile trovare un appid per {path}!" +msgstr "impossibile trovare srclibs richiesto: \"{path}\"" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py From 4e0b0f63e92a7b1534c4cd7b9e28c8bdd9788524 Mon Sep 17 00:00:00 2001 From: WaldiS Date: Sat, 17 Oct 2020 07:19:42 +0200 Subject: [PATCH 0585/2775] Translated using Weblate: Polish (pl) by WaldiS Currently translated at 84.5% (481 of 569 strings) Co-authored-by: WaldiS Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pl/ Translation: F-Droid/F-Droid Server --- locale/pl/LC_MESSAGES/fdroidserver.po | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index 5437276b..7c62a94d 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-06 08:26+0000\n" +"PO-Revision-Date: 2020-10-14 09:28+0000\n" "Last-Translator: WaldiS \n" "Language-Team: Polish \n" "Language: pl\n" @@ -339,7 +339,7 @@ msgstr "Gałąź '{branch}' używana jako commit w srclib '{srclib}'" #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Uszkodzone dowiązanie symboliczne: {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -385,15 +385,14 @@ msgstr "Nie można odczytać \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" +#, python-brace-format msgid "Cannot resolve application ID {appid}" msgstr "Nie można rozpoznać identyfikatora aplikacji {appid}" #: ../fdroidserver/rewritemeta.py #, fuzzy, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "Nie można odczytać \"{path}\"!" +msgstr "Nie można odczytać \"{path}\"" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" From 45959775b3f93c7b354e08570d123616b5a1f395 Mon Sep 17 00:00:00 2001 From: marzzzello Date: Sat, 17 Oct 2020 07:19:42 +0200 Subject: [PATCH 0586/2775] Translated using Weblate: German (de) by marzzzello Currently translated at 86.2% (491 of 569 strings) Co-authored-by: marzzzello Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/de/ Translation: F-Droid/F-Droid Server --- locale/de/LC_MESSAGES/fdroidserver.po | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index 59c94768..17b98cb9 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -3,13 +3,14 @@ # Oliver , 2020. # Fynn Godau , 2020. # melusine , 2020. +# marzzzello , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-02 19:15+0000\n" -"Last-Translator: melusine \n" +"PO-Revision-Date: 2020-10-15 17:12+0000\n" +"Last-Translator: marzzzello \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" @@ -153,7 +154,7 @@ msgstr "„keypass” nicht in config.py vorhanden!" #: ../fdroidserver/common.py msgid "'keystore' is NONE and 'smartcardoptions' is blank!" -msgstr "" +msgstr "'keystore' ist NONE und 'smartcardoptions' ist leer!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" @@ -582,7 +583,7 @@ msgstr "Archiv löschen, Repo ist zu groß ({size} max {limit})" #: ../fdroidserver/server.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Git-Mirror-Verlauf löschen, Repository ist zu groß ({size} max {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -697,7 +698,7 @@ msgstr "Build-Flag bei {linedesc} leeren" #: ../fdroidserver/__main__.py #, python-brace-format msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." -msgstr "" +msgstr "Die Kodierung ist auf '{enc}' gesetzt. Dies könnte zu Kodierungsproblemen führen. Bitte setze sie auf ''UTF-8'' für beste Ergebnisse." #: ../fdroidserver/init.py #, python-format @@ -791,7 +792,7 @@ msgstr "Signaturen für {apkfilename} -> {sigdir} abgerufen" #: ../fdroidserver/update.py #, python-brace-format msgid "File disappeared while processing it: {path}" -msgstr "" +msgstr "Datei verschwand während der Verarbeitung: {path}" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -824,7 +825,7 @@ msgstr "Erzwingt das Anhalten des Builds nach {0} Sek. Zeitüberschreitung!" #: ../fdroidserver/scanner.py msgid "Force scan of disabled apps and builds." -msgstr "" +msgstr "Scannen von deaktivierten Anwendungen und Builds erzwingen." #: ../fdroidserver/update.py #, python-brace-format @@ -832,9 +833,9 @@ msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" msgstr "Grafik \"{path}\" ohne Metadaten für App \"{name}\" gefunden!" #: ../fdroidserver/update.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "Found bad funding file \"{path}\" for \"{name}\":" -msgstr "" +msgstr "Schlechte Finanzierungsdatei \"{path}\" für \"{name}\" gefunden:" #: ../fdroidserver/common.py msgid "Found invalid appids in arguments" @@ -922,8 +923,9 @@ msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS muss bei Subversion-URLs verwendet werden!" #: ../fdroidserver/server.py +#, fuzzy msgid "If a git mirror gets to big, allow the archive to be deleted" -msgstr "" +msgstr "Wenn ein Git-Mirror zu groß wird, kann das Archiv gelöscht werden" #: ../fdroidserver/server.py #, fuzzy, python-brace-format @@ -933,12 +935,12 @@ msgstr "Wenn dieser Upload fehlschlägt, versuchen Sie ihn manuell auf {url} hoc #: ../fdroidserver/metadata.py #, python-brace-format msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." -msgstr "" +msgstr "'{field}' in '{metapath}' Metadaten wird ignoriert, da es veraltet ist." #: ../fdroidserver/update.py #, python-format msgid "Ignoring FUNDING.yml entry longer than 2048: %s" -msgstr "" +msgstr "Ignoriere FUNDING.yml Einträge länger als 2048: %s" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " From f7f65e26c3fb91ec52468acc95e2dca5783bf602 Mon Sep 17 00:00:00 2001 From: IvanDan Date: Sat, 17 Oct 2020 07:19:42 +0200 Subject: [PATCH 0587/2775] Translated using Weblate: Italian (it) by IvanDan Currently translated at 34.9% (199 of 569 strings) Co-authored-by: IvanDan Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/it/ Translation: F-Droid/F-Droid Server --- locale/it/LC_MESSAGES/fdroidserver.po | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index e8920b7f..9851dc7c 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-01 12:22+0200\n" -"PO-Revision-Date: 2020-10-14 09:28+0000\n" -"Last-Translator: random r \n" +"PO-Revision-Date: 2020-10-15 17:12+0000\n" +"Last-Translator: IvanDan \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" @@ -393,10 +393,9 @@ msgstr "Impossibile leggere \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" +#, python-brace-format msgid "Cannot resolve application ID {appid}" -msgstr "Impossibile trovare l'app id {appid}" +msgstr "Impossibile trovare l’ID dell’applicazione {appid}" #: ../fdroidserver/rewritemeta.py #, python-brace-format @@ -461,7 +460,7 @@ msgstr "Cambiamenti del commit" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Argomenti in conflitto: '--verbose' e '--quiet' non possono essere specificati contemporaneamente." #: ../fdroidserver/common.py #, python-brace-format From 73a6a9c046d840fd0b581c991dd866fd6bea8bdf Mon Sep 17 00:00:00 2001 From: Hakim Oubouali Date: Sat, 17 Oct 2020 07:19:43 +0200 Subject: [PATCH 0588/2775] Added translation using Weblate: Central Atlas Tamazight (tzm) by Hakim Oubouali Co-authored-by: Hakim Oubouali --- locale/tzm/LC_MESSAGES/fdroidserver.po | 2668 ++++++++++++++++++++++++ 1 file changed, 2668 insertions(+) create mode 100644 locale/tzm/LC_MESSAGES/fdroidserver.po diff --git a/locale/tzm/LC_MESSAGES/fdroidserver.po b/locale/tzm/LC_MESSAGES/fdroidserver.po new file mode 100644 index 00000000..d40cb39b --- /dev/null +++ b/locale/tzm/LC_MESSAGES/fdroidserver.po @@ -0,0 +1,2668 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# Hakim Oubouali , 2020. +msgid "" +msgstr "" +"Project-Id-Version: fdroidserver 1.1-681-gc19e8952\n" +"Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" +"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: tzm\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 >= 2 && (n < 11 || n > 99);\n" + +#: ../fdroidserver/common.py +msgid "" +"\n" +" This is a repository of apps to be used with FDroid. Applications in this\n" +" repository are either official binaries built by the original application\n" +" developers, or are binaries built from source by f-droid.org using the\n" +" tools on https://gitlab.com/fdroid.\n" +" " +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH Public Key to be used as Deploy Key:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "" +"\n" +"SSH public key to be used as deploy key:" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "" +"\n" +"{path} encoded for the DEBUG_KEYSTORE secret variable:" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "\"%s/\" has no matching metadata file!" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains outdated {name} ({version})" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains recent {name} ({version})" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "\"{path}\" exists but s3cmd is not installed!" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "\"{path}\" is not an accepted format, convert to: {formats}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%(option)s option requires %(number)d argument" +msgid_plural "%(option)s option requires %(number)d arguments" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/mirror.py +#, python-format +msgid "%(prog)s [options] url" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%(prog)s: error: %(message)s\n" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "%d problems found" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "%prog [options]" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "%r is not callable" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "%s is not an accepted build field" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "%s option does not take a value" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keypass' not found in config.py!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystore' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'keystorepass' not found in config.py!" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "'repo_keyalias' not found in config.py!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "'required' is an invalid argument for positionals" +msgstr "" + +#: ../fdroidserver/common.py +msgid "'sdk_path' not set in 'config.py'!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "'{apkfilename}' is already installed on {dev}." +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{field}' in {linedesc} is obsolete, see docs for current fields:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{field}' will be in random order! Use () or [] brackets if order is important!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{path}' failed to execute!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "...checkupdate failed for {appid} : {error}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid ".__call__() not defined" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid ".fdroid.txt is not supported! Convert to .fdroid.yml or .fdroid.json." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "/issues is missing" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "A URL is required as an argument!" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Add PGP signatures using GnuPG for packages in repo" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Add a new application from its source code" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Add a repo signing key to an unsigned repo" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Add skeleton metadata files for APKs that are missing them" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Adding new repo for only {name}" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Alias of the repo signing key in the keystore" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Allows a different revision (or git branch) to be specified for the initial import" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Also mirror the full archive section" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Also warn about formatting issues, like rewritemeta -l" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "" + +#: ../fdroidserver/common.py ../fdroidserver/build.py +#, python-brace-format +msgid "Android SDK '{path}' does not have '{dirname}' installed!" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Android SDK not found!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' is not a directory!" +msgstr "" + +#. Translators: "build-tools" is the file name of a package from +#. Google, it is part of the Android SDK. So it probably shouldn't be +#. translated or transliterated. +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android build-tools path '{path}' does not exist!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "AndroidManifest.xml has no date" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "App is in '{repo}' but has a link to {url}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Appending .git is not necessary" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Archiving {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in srclib '{srclib}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Build a package from source" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build all applications available" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Build generated by `fdroid import` - remove disable line once ready" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Build metadata git repo has uncommited changes!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Build only the latest version of each package" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Build should have comma-separated versionName and versionCode, not \"{value}\", in {linedesc}" +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "Built repo based in \"%s\" with this config:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Can't build due to {} error while scanning" +msgid_plural "Can't build due to {} errors while scanning" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/vmtools.py +#, python-brace-format +msgid "Cannot read \"{path}\"!" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot resolve application ID {appid}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Cannot use --list and --to at the same time" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Cannot write \"{path}\", not an accepted format, use: {formats}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Categories '%s' is not valid" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Categories are not set" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Check for updates to applications" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean after all scans have finished" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean before the scans start and rebuild the container" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Clean up all containers and then exit" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Clean update - don't uses caches, reprocess all APKs" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Comma separated list of categories." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +#, c-format, python-format +msgid "Command '%s' not recognised.\n" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes" +msgstr "" + +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not find '{command}' on your system" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version code" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Could not find latest version name" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not find {path} to remove it" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Could not open apk file for analysis" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/import.py +msgid "Couldn't find Application ID" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/import.py +msgid "Couldn't find latest version code" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/import.py +msgid "Couldn't find latest version name" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Couldn't find package ID" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Cowardily refusing to overwrite existing signing key setup!" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create a repo signing key in a keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Create skeleton metadata files that are missing" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Created new container \"{name}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Creating log directory" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Creating new S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Creating output directory" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Creating signed index with this key (SHA256):" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/verify.py +#: ../fdroidserver/publish.py +msgid "Creating temporary directory" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Creating unsigned index in preparation for signing" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "DEBUG_KEYSTORE is not set or the value is incomplete" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Delete APKs and/or OBBs without metadata from the repo" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Deleting unknown file: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description '%s' is just the app's summary" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Description has a duplicate line" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description has a list (%s) but it isn't bulleted (*) nor numbered (#)" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Description of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not deploy the new files to the repo" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Do not include \"{path}\" in URL!" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Do not prompt for Android SDK path, just fail" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Do not remove the private keys generated from the keystore" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't create a source tarball, useful when testing a build" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Don't do anything logs-related" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Don't refresh the repository, useful when testing a build with no internet connection" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/upload.py +msgid "Don't use rsync checksums" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Download complete mirrors of small repos" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Download logs we don't have" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Downloading the repository already failed once, not trying again." +msgstr "" + +#: ../fdroidserver/verify.py +#, python-brace-format +msgid "Downloading {url} failed. {error}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Duplicate build recipe found for versionCode {versionCode} in {linedesc}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Duplicate link in '{field}': {url}" +msgstr "" + +#: ../fdroid +msgid "Dynamically scan APKs post build" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "" +"ERROR: this command should never be used to mirror f-droid.org!\n" +"A full mirror of f-droid.org requires more than 200GB." +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "ERROR: unsupported CI type, patches welcome!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Empty build flag at {linedesc}" +msgstr "" + +#: ../fdroidserver/__main__.py +#, python-brace-format +msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." +msgstr "" + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"Enter the path to the Android SDK (%s) here:\n" +"> " +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/upload.py +#, python-format +msgid "Error while attempting to publish log: %s" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py +msgid "Error while getting repo address" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Extract signatures from APKs" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Failed fetching signatures for '{apkfilename}': {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed reading {path}: {error}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed resizing {path}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "Failed to align application" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Failed to create S3 bucket: {url}" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to get APK manifest information" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, deleting {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get apk information, skipping {path}" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Failed to install '{apkfilename}' on {dev}: {error}" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/common.py +msgid "Failed to sign application" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Failed to zipalign application" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Fetched buildserverid from VM: {buildserverid}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py +#: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "Finished" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID flag" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Flattr donation methods belong in the FlattrID: field" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Forbidden HTML tags" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode." +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Force halting build after {0} sec timeout!" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Force scan of disabled apps and builds." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found \"{path}\" graphic without metadata for app \"{name}\"!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Found invalid appids in arguments" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Found invalid versionCodes for some apps" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Found multiple metadata files for {appid}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found multiple signing certificates for repository." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found multiple signing certificates in {path}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Found no signing certificates for repository." +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Found non-file at %s" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Generated skeleton metadata for {appid}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git checkout of '%s' failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git clean failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git fetch failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git remote set-head failed" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git reset failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule sync failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Git submodule update failed" +msgstr "" + +#: ../fdroidserver/common.py +msgid "HTTPS must be used with Subversion URLs!" +msgstr "" + +#: ../fdroidserver/server.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Ignoring package without metadata: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Ignoring stale cache data for {apkfilename}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Ignoring {ext} file at '{path}'" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Include APKs that are signed with disabled algorithms like MD5" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Initialising submodules" +msgstr "" + +#: ../fdroidserver/install.py +msgid "Install all signed applications available" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Install built packages on devices" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s…" +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}…" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Interact with the repo HTTP server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Invalid APK" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid VercodeOperation: {field}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid boolean '%s'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build flag at {line} in {linedesc}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid build format: {value} in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid bulleted list" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Invalid license tag \"%s\"! Use only tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Invalid link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Invalid metadata in %s:%d" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Invalid metadata in: " +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "Invalid name for published file: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid package name {0}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid redirect to non-HTTPS: {before} -> {after} " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid versionCode: \"{versionCode}\" is not an integer!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature failed to verify: {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature verified: {path}" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#: ../fdroidserver/mirror.py +msgid "Java JDK not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Java compiled class" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Java jarsigner not found! Install in standard location or set java_paths!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Javascript in HTML src attributes" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Keystore for signing key:\t" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the LiberapayID flag" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "List files that would be reformatted" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Locale included in f-droid.org URL" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Make the build stop on exceptions" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Malformed repository mirrors." +msgstr "" + +#: ../fdroidserver/server.py +msgid "Malformed serverwebroot line:" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "" + +#: ../fdroidserver/gpgsign.py +msgid "Missing output directory" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Name '%s' is just the auto name - remove it" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No 'config.py' found, using defaults." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No Android SDK found!" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No android or kivy project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No attached devices found" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "No commit specified for {versionName} in {linedesc}" +msgstr "" + +#: ../fdroidserver/index.py +msgid "No fingerprint in URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "No git submodules available" +msgstr "" + +#: ../fdroidserver/import.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "" + +#: ../fdroidserver/import.py ../fdroidserver/common.py +msgid "No information found." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is Free Software" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "No need to specify that the app is for Android" +msgstr "" + +#: ../fdroidserver/server.py +msgid "No option set! Edit your config.py to set at least one of these:" +msgstr "" + +#: ../fdroidserver/common.py +msgid "No packages specified" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "No signed apk available for %s" +msgstr "" + +#: ../fdroidserver/install.py +msgid "No signed output directory - nothing to do" +msgstr "" + +#: ../fdroidserver/update.py ../fdroidserver/common.py +#, python-brace-format +msgid "No signing certificates found in {path}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-format +msgid "No such package: %s" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No such versionCode {versionCode} for app {appid}" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +msgid "No unsigned directory - nothing to do" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Not a valid size definition: \"{}\"" +msgstr "" + +#: ../fdroidserver/signindex.py +msgid "Nothing to do" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Nothing to do for {appid}." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Now set these in config.py:" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "OBB file has newer versionCode({integer}) than any APK:" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB filename must start with \"main.\" or \"patch.\":" +msgstr "" + +#: ../fdroidserver/update.py +msgid "OBB's packagename does not match a supported APK:" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Old APK signature failed to verify: {path}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Old, deprecated name for fdroid deploy" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Only PNG and JPEG are supported for graphics, found: {path}" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only print differences with the Play Store" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Only process apps with auto-updates" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Options" +msgstr "" + +#: ../fdroidserver/verify.py +msgid "Output JSON report to file named after APK." +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "" + +#: ../fdroidserver/gpgsign.py ../fdroidserver/publish.py +#: ../fdroidserver/update.py ../fdroidserver/signindex.py +#: ../fdroidserver/checkupdates.py +msgid "Outputting JSON" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Overall license of the project." +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Override path for repo APKs (default: ./repo)" +msgstr "" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" +msgstr "" + +#: ../fdroidserver/import.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Parsing manifest at '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Password required with username" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Path to main Android project subdirectory, if not in root." +msgstr "" + +msgid "Path to main android project subdirectory, if not in root." +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Path to the git repo to use as the log" +msgstr "" + +#: ../fdroidserver/init.py +msgid "Path to the keystore for the repo signing key" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Prepare Drozer to run a scan" +msgstr "" + +msgid "Prepare drozer to run a scan" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Print the secret variable to the terminal for easy copy/paste" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Problem with description of {appid}: {error}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Problem with xml at '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Process auto-updates" +msgstr "" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#, python-brace-format +msgid "Processing {apkfilename}" +msgstr "" + +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#, python-brace-format +msgid "Processing {appid}" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable XML/JSON for index files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Produce human-readable index.xml" +msgstr "" + +#: ../fdroidserver/import.py +msgid "Project URL to import from." +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Punctuation should be avoided" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "Push the log to this git remote repository" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing binary transparency log to {url}" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Pushing to {url}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Quickly start a new repository" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Read all the metadata files and exit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading '{config_file}'" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading minSdkVersion failed: \"{apkfilename}\"" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#. https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Reading {apkfilename} from cache" +msgstr "" + +#: ../fdroidserver/stats.py +msgid "Recalculate aggregate stats - use when changes have been made that would invalidate old cached data." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Removing specified files" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Rename APK files that do not match package.name_123.apk" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Report on build data status" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Reset and create a brand new build server, even if the existing one appears to be ok." +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Resigning {apkfilename} with provided debug.keystore" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Resize all the icons exceeding the max pixel size and exit" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Restrict output to warnings and errors" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Rewrite all the metadata files" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +msgid "Rewrite to a specific format: " +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}'" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}' to '{path}'" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "Run on git repo that has uncommitted changes" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Run rewritemeta to fix formatting" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Running first pass with MD5 checking disabled" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Running wget in {path}" +msgstr "" + +#: ../fdroidserver/dscanner.py +msgid "Scan only the latest version of each package" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Scan the source code of a package" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:{versionCode}:" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Scanner found {} problem" +msgid_plural "Scanner found {} problems" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/common.py +msgid "Set clock to that time using:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Set maximum releases in repo before older ones are archived" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Set open file limit to {integer}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Set up an app build for a nightly build repo" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setting open file limit failed: " +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Setting {0} sec timeout for this build" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Setup an emulator, install the APK on it and perform a Drozer scan" +msgstr "" + +msgid "Setup an emulator, install the apk on it and perform a drozer scan" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Sign and place packages in the repo" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Sign indexes created using update --nosign" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Skip scanning the source code for binaries and other problems" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping '{apkfilename}' with invalid signature!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping index generation for {appid}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping {apkfilename} with invalid signature!" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: disabled" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: no builds specified" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify a local folder to sync the repo to" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "Specify an identity file to provide to SSH for rsyncing" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Specify that we're running on the build server" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "Specify which debug keystore file to use." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Spew out even more information than normal" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Striping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Stripping mystery signature from {apkfilename}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Summary '%s' is just the app's name" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Summary of length {length} is over the {limit} char limit" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "System clock is older than date in {path}!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "The OBB version code must come after \"{name}.\":" +msgstr "" + +#: ../fdroidserver/btlog.py +msgid "The base URL for the repo to log (default: https://f-droid.org)" +msgstr "" + +#: ../fdroidserver/mirror.py +msgid "The directory to write the mirror to" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "The file to be included in the repo (path or glob)" +msgstr "" + +#: ../fdroidserver/server.py +msgid "The only commands currently supported are 'init' and 'update'" +msgstr "" + +#: ../fdroidserver/index.py +msgid "The repository's fingerprint does not match." +msgstr "" + +#: ../fdroidserver/common.py +msgid "The repository's index could not be verified." +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "The root dir for local_copy_dir \"{path}\" does not exist!" +msgstr "" + +#: ../fdroidserver/publish.py +msgid "There is a keyalias collision - publishing halted" +msgstr "" + +#: ../fdroidserver/common.py +msgid "These are the apps that have been archived from the main repo." +msgstr "" + +#: ../fdroidserver/import.py +#, python-format +msgid "This repo already has local metadata: %s" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "URL shorteners should not be used" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "URL title is just the URL, use brackets: [URL]" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "URL {url} in Description: {error}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unexpected text on same line as {field} in {linedesc}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Unknown exception found!" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Unknown file '{filename}' in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Unknown metadata format: %s" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Unknown version of aapt, might cause problems: " +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unlinkified link - use [http://foo.bar Link title] or [http://foo.bar]" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary leading space" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Unnecessary trailing space" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised app field '{fieldname}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unrecognised app field: " +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised build flag '{build_flag}' in '{path}'" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised field '{field}' in {linedesc}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported file type \"{extension}\" for repo graphic" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported graphics file found: {path}" +msgstr "" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Unsupported metadata format, use: --to [{supported}]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "Unterminated ]]" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated build in {name}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unterminated continuation in {name}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused extlib at %s" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused file at %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update repo information for new packages" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update the binary transparency log for a URL" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Update the stats of the repo" +msgstr "" + +#: ../fdroidserver/update.py ../fdroidserver/build.py +msgid "Update the wiki" +msgstr "" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "UpdateCheckData has invalid URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must use HTTPS URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData not a valid URL: {url}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "Usage" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "Usage: %s\n" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "Use /HEAD instead of /master to point at a file in the default branch" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use `fdroid update -c` to create it." +msgstr "" + +#: ../fdroidserver/build.py +msgid "Use build server" +msgstr "" + +#: ../fdroidserver/update.py +msgid "Use date from APK instead of current time for newly added APKs" +msgstr "" + +msgid "Use date from apk instead of current time for newly added apks" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using \"{path}\" for configuring s3cmd." +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "" + +#: ../fdroidserver/common.py +msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Using androguard from \"{path}\"" +msgstr "" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Using existing keystore \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "Using s3cmd to sync with: {url}" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Valid commands are:" +msgstr "" + +#: ../fdroidserver/verify.py +msgid "Verify against locally cached copy rather than redownloading." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Verify the integrity of downloaded packages" +msgstr "" + +#: ../fdroidserver/index.py +msgid "Verifying index signature:" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "Warn about possible metadata errors" +msgstr "" + +#: ../fdroidserver/update.py +msgid "When configured for signed indexes, create only unsigned indexes at this stage" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "When linting the entire repository yamllint is disabled by default. This option forces yamllint regardless." +msgstr "" + +msgid "X.509 'Distiguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/init.py +msgid "X.509 'Distinguished Name' used when generating keys" +msgstr "" + +#: ../fdroidserver/common.py +msgid "You can use ANDROID_HOME to set the path to your SDK, i.e.:" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "ZIP file archive" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "adding IdentityFile to {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "adding to {name}: {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ambiguous option: %(option)s could match %(matches)s" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "ambiguous option: %s (%s?)" +msgstr "" + +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +#: ../fdroidserver/checkupdates.py +msgid "application ID of file to operate on" +msgstr "" + +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/build.py ../fdroidserver/scanner.py +#: ../fdroidserver/install.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + +#: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py +msgid "applicationId in the form APPID" +msgstr "" + +#: ../fdroidserver/checkupdates.py +msgid "applicationId to check for updates" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/verify.py ../fdroidserver/publish.py +#: ../fdroidserver/dscanner.py ../fdroidserver/build.py +#: ../fdroidserver/scanner.py ../fdroidserver/install.py +msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "argument \"-\" with mode %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "attempting bare SSH connection to test deploy key:" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "attempting bare ssh connection to test deploy key:" +msgstr "" + +#: ../fdroidserver/common.py +msgid "can not parse scrlib spec (not a string): '{}'" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "can't open '%s': %s" +msgstr "" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "cannot have multiple subparser arguments" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "cannot merge actions - two groups are named %r" +msgstr "" + +#: ../fdroidserver/nightly.py +msgid "cannot publish update, did you set the deploy key?" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "cloning {url}" +msgstr "" + +#: ../fdroidserver/server.py +msgid "command to execute, either 'init' or 'update'" +msgstr "" + +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "complex" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "conflicting option string: %s" +msgid_plural "conflicting option strings: %s" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "copying {apkfilename} into {path}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (too many '@' signs): '{}'" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "created {path}" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "deleting: repo/{apkfilename}" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed build logs to '{path}'" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "dest= is required for options like %r" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "expected %s argument" +msgid_plural "expected %s arguments" +msgstr[0] "" +msgstr[1] "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at least one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected at most one argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "expected one argument" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "failed deploying build logs to '{path}'" +msgstr "" + +#: ../fdroid +msgid "fdroid [-h|--help|--version] []" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "fdroid [] [-h|--help|--version|]" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "floating-point" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force errors to be warnings, or ignore" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "force metadata errors (default) to be warnings, or to be ignored." +msgstr "" + +#: ../fdroidserver/common.py +msgid "git svn clone failed" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "ignored explicit argument %r" +msgstr "" + +#: ../fdroidserver/index.py +msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "integer" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid %(type)s value: %(value)r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid choice: %(value)r (choose from %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid conflict_resolution value: %r" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be an absolute path!" +msgstr "" + +#: ../fdroidserver/server.py +msgid "local_copy_dir must be directory, not a file!" +msgstr "" + +#: ../fdroidserver/index.py +#, python-format +msgid "mirror '%s' does not end with 'fdroid'!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "mutually exclusive arguments must be optional" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "no \"icon\" in {appid}" +msgstr "" + +#: ../fdroidserver/signatures.py +msgid "no APK supplied" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "no such option: %s" +msgstr "" + +#: ../fdroid ../fdroidserver/__main__.py +msgid "no version info found!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "not allowed with argument %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "one of the arguments %s is required" +msgstr "" + +#: ../fdroidserver/index.py ../fdroidserver/common.py +msgid "only accepts strings, lists, and tuples" +msgstr "" + +#: ../fdroidserver/install.py +#, python-format +msgid "option %s: If you really want to install all the signed apps, use --all" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid %s value: %r" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +#, python-format +msgid "option %s: invalid choice: %r (choose from %s)" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s not recognized" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option -%s requires argument" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s must not have an argument" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not a unique prefix" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s not recognized" +msgstr "" + +#: /usr/lib/python3.5/getopt.py /usr/lib/python3.6/getopt.py +#: /usr/lib/python3.7/getopt.py +#, python-format +msgid "option --%s requires argument" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "optional arguments" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "overwriting existing {path}" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +msgid "positional arguments" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" +msgstr "" + +#: ../fdroidserver/metadata.py +msgid "ruamel.yaml not installed, can not write metadata." +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "s3cmd sync indexes {path} to {url} and delete" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "" + +#: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/optparse.py +msgid "show program's version number and exit" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.5/optparse.py +#: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py +#: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py +msgid "show this help message and exit" +msgstr "" + +#: ../fdroidserver/signatures.py +msgid "signed APK, either a file-path or HTTPS URL." +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: log content is empty" +msgstr "" + +#: ../fdroidserver/common.py +msgid "skip deploying full build logs: not enabled in config" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "skipping source tarball: {path}" +msgstr "" + +#: ../fdroidserver/lint.py +msgid "srclibs missing name and/or @" +msgstr "" + +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "supplied timestamp value '{timestamp}' is not a unix timestamp" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "the following arguments are required: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unexpected option string: %s" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unknown parser %(parser_name)r (choices: %(choices)s)" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py +#: /usr/lib/python3.7/argparse.py +#, python-format +msgid "unrecognized arguments: %s" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "unsafe permissions on '{config_file}' (should be 0600)!" +msgstr "" + +#: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid +#: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py +msgid "usage: " +msgstr "" + +#: ../fdroid +msgid "usage: fdroid [-h|--help|--version] []" +msgstr "" + +#: ../fdroidserver/server.py ../fdroidserver/upload.py +#, python-brace-format +msgid "using Apache libcloud to sync with {url}" +msgstr "" + +#: ../fdroidserver/server.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "" + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "{0} app, {1} key aliases" +msgid_plural "{0} apps, {1} key aliases" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} ({appid}) has no metadata!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using package name instead." +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android Package Name!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Android application ID!" +msgstr "" + +#: ../fdroidserver/metadata.py ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} from {path} is not a valid Java Package Name!" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{appid} is missing {name}" +msgstr "" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: Unknown extlib {path} in build '{versionName}'" +msgstr "" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "{appid}: no builds specified, running on current source state" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" +msgstr "" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be an integer, found: {value}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{field} not terminated in {name}" +msgstr "" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{name} \"{path}\" does not exist! Correct it in config.py." +msgstr "" + +#: ../fdroidserver/import.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "{path} does not exist! Create it by running:" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" +msgstr "" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} is zero size!" +msgstr "" + +#: ../fdroidserver/server.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{url} does not end with \"fdroid\", check the URL path!" +msgstr "" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "" + +#: ../fdroidserver/build.py +msgid "{} build failed" +msgid_plural "{} builds failed" +msgstr[0] "" +msgstr[1] "" + +#: ../fdroidserver/build.py +msgid "{} build succeeded" +msgid_plural "{} builds succeeded" +msgstr[0] "" +msgstr[1] "" From 8daf273843b05998521083d0a8a55e792580f895 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 21 Oct 2020 10:16:17 +0200 Subject: [PATCH 0589/2775] server: purge `fdroid server init` command, it is totally unneeded The existing rsync command used to deploy via SSH will create all the dirs that `fdroid server init` does. --- fdroidserver/server.py | 71 ++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 48 deletions(-) diff --git a/fdroidserver/server.py b/fdroidserver/server.py index d406da1d..9ae21d5f 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/server.py @@ -21,8 +21,6 @@ import glob import hashlib import json import os -import paramiko -import pwd import re import subprocess import time @@ -715,8 +713,8 @@ def main(): config = common.read_config(options) - if options.command != 'init' and options.command != 'update': - logging.critical(_("The only commands currently supported are 'init' and 'update'")) + if options.command != 'update': + logging.critical(_("The only command currently supported is 'update'")) sys.exit(1) if config.get('nonstandardwebroot') is True: @@ -792,52 +790,29 @@ def main(): if config['per_app_repos']: repo_sections += common.get_per_app_repos() - if options.command == 'init': - ssh = paramiko.SSHClient() - ssh.load_system_host_keys() - for serverwebroot in config.get('serverwebroot', []): - sshstr, remotepath = serverwebroot.rstrip('/').split(':') - if sshstr.find('@') >= 0: - username, hostname = sshstr.split('@') + for repo_section in repo_sections: + if local_copy_dir is not None: + if config['sync_from_local_copy_dir']: + sync_from_localcopy(repo_section, local_copy_dir) else: - username = pwd.getpwuid(os.getuid())[0] # get effective uid - hostname = sshstr - ssh.connect(hostname, username=username) - sftp = ssh.open_sftp() - if os.path.basename(remotepath) \ - not in sftp.listdir(os.path.dirname(remotepath)): - sftp.mkdir(remotepath, mode=0o755) - for repo_section in repo_sections: - repo_path = os.path.join(remotepath, repo_section) - if os.path.basename(repo_path) \ - not in sftp.listdir(remotepath): - sftp.mkdir(repo_path, mode=0o755) - sftp.close() - ssh.close() - elif options.command == 'update': - for repo_section in repo_sections: - if local_copy_dir is not None: - if config['sync_from_local_copy_dir']: - sync_from_localcopy(repo_section, local_copy_dir) - else: - update_localcopy(repo_section, local_copy_dir) - for serverwebroot in config.get('serverwebroot', []): - update_serverwebroot(serverwebroot, repo_section) - if config.get('servergitmirrors', []): - # update_servergitmirrors will take care of multiple mirrors so don't need a foreach - servergitmirrors = config.get('servergitmirrors', []) - update_servergitmirrors(servergitmirrors, repo_section) - if config.get('awsbucket'): - update_awsbucket(repo_section) - if config.get('androidobservatory'): - upload_to_android_observatory(repo_section) - if config.get('virustotal_apikey'): - upload_to_virustotal(repo_section, config.get('virustotal_apikey')) + update_localcopy(repo_section, local_copy_dir) + for serverwebroot in config.get('serverwebroot', []): + update_serverwebroot(serverwebroot, repo_section) + if config.get('servergitmirrors', []): + # update_servergitmirrors will take care of multiple mirrors so don't need a foreach + servergitmirrors = config.get('servergitmirrors', []) + update_servergitmirrors(servergitmirrors, repo_section) + if config.get('awsbucket'): + update_awsbucket(repo_section) + if config.get('androidobservatory'): + upload_to_android_observatory(repo_section) + if config.get('virustotal_apikey'): + upload_to_virustotal(repo_section, config.get('virustotal_apikey')) - binary_transparency_remote = config.get('binary_transparency_remote') - if binary_transparency_remote: - push_binary_transparency(BINARY_TRANSPARENCY_DIR, - binary_transparency_remote) + binary_transparency_remote = config.get('binary_transparency_remote') + if binary_transparency_remote: + push_binary_transparency(BINARY_TRANSPARENCY_DIR, + binary_transparency_remote) if config.get('wiki_server') and config.get('wiki_path'): update_wiki() From 17f6a778ba510c86a22abd5e2219cffd029890a3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 21 Oct 2020 09:52:58 +0200 Subject: [PATCH 0590/2775] deploy: move server.py to deploy.py and remove aliases closes #832 --- MANIFEST.in | 2 +- examples/config.py | 4 +- fdroidserver/__init__.py | 2 +- fdroidserver/__main__.py | 9 +-- fdroidserver/btlog.py | 4 +- fdroidserver/{server.py => deploy.py} | 13 +--- fdroidserver/nightly.py | 2 +- locale/POTFILES.in | 2 +- locale/fdroidserver.pot | 70 +++++++++++----------- tests/{server.TestCase => deploy.TestCase} | 50 ++++++++-------- tests/main.TestCase | 3 +- tests/run-tests | 20 +++---- 12 files changed, 85 insertions(+), 96 deletions(-) rename fdroidserver/{server.py => deploy.py} (98%) rename tests/{server.TestCase => deploy.TestCase} (83%) diff --git a/MANIFEST.in b/MANIFEST.in index ce591656..b3dcf59b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -537,6 +537,7 @@ include tests/check-fdroid-apk include tests/common.TestCase include tests/complete-ci-tests include tests/config.py +include tests/deploy.TestCase include tests/description-parsing.py include tests/dummy-keystore.jks include tests/dump_internal_metadata_format.py @@ -667,7 +668,6 @@ include tests/repo/urzip-*.apk include tests/repo/v1.v2.sig_1020.apk include tests/run-tests include tests/scanner.TestCase -include tests/server.TestCase include tests/signatures.TestCase include tests/signindex/guardianproject.jar include tests/signindex/guardianproject-v1.jar diff --git a/examples/config.py b/examples/config.py index f074fb15..c9c1cbc1 100644 --- a/examples/config.py +++ b/examples/config.py @@ -222,9 +222,9 @@ The repository of older versions of applications from the main demo repository. # If you are running the repo signing process on a completely offline machine, # which provides the best security, then you can specify a folder to sync the -# repo to when running `fdroid server update`. This is most likely going to +# repo to when running `fdroid deploy`. This is most likely going to # be a USB thumb drive, SD Card, or some other kind of removable media. Make -# sure it is mounted before running `fdroid server update`. Using the +# sure it is mounted before running `fdroid deploy`. Using the # standard folder called 'fdroid' as the specified folder is recommended, like # with serverwebroot. # diff --git a/fdroidserver/__init__.py b/fdroidserver/__init__.py index 3a395ea2..1e1cd42f 100644 --- a/fdroidserver/__init__.py +++ b/fdroidserver/__init__.py @@ -48,7 +48,7 @@ process_apk # NOQA: B101 process_apks # NOQA: B101 scan_apk # NOQA: B101 scan_repo_files # NOQA: B101 -from fdroidserver.server import (update_awsbucket, +from fdroidserver.deploy import (update_awsbucket, update_servergitmirrors, update_serverwebroot) # NOQA: E402 update_awsbucket # NOQA: B101 diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index 4d0c4785..d90a4316 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -48,7 +48,6 @@ COMMANDS = OrderedDict([ ("lint", _("Warn about possible metadata errors")), ("scanner", _("Scan the source code of a package")), ("stats", _("Update the stats of the repo")), - ("server", _("Old, deprecated name for fdroid deploy")), ("signindex", _("Sign indexes created using update --nosign")), ("btlog", _("Update the binary transparency log for a URL")), ("signatures", _("Extract signatures from APKs")), @@ -137,6 +136,9 @@ def main(): if command in ('-h', '--help'): print_help(available_plugins=available_plugins) sys.exit(0) + elif command == 'server': + print(_("""ERROR: The "server" subcommand has been removed, use "deploy"!""")) + sys.exit(1) elif command == '--version': output = _('no version info found!') cmddir = os.path.realpath(os.path.dirname(os.path.dirname(__file__))) @@ -187,11 +189,6 @@ def main(): "can not be specified at the same time.")) sys.exit(1) - # temporary workaround until server.py becomes deploy.py - if command == 'deploy': - command = 'server' - sys.argv.insert(2, 'update') - # Trick optparse into displaying the right usage when --help is used. sys.argv[0] += ' ' + command diff --git a/fdroidserver/btlog.py b/fdroidserver/btlog.py index 08993aec..f1e83c90 100755 --- a/fdroidserver/btlog.py +++ b/fdroidserver/btlog.py @@ -42,7 +42,7 @@ from argparse import ArgumentParser from . import _ from . import common -from . import server +from . import deploy from .exception import FDroidException @@ -219,7 +219,7 @@ def main(): os.chdir(tempdirbase) make_binary_transparency_log(repodirs, options.git_repo, options.url, 'fdroid btlog') if options.git_remote: - server.push_binary_transparency(options.git_repo, options.git_remote) + deploy.push_binary_transparency(options.git_repo, options.git_remote) shutil.rmtree(tempdirbase, ignore_errors=True) diff --git a/fdroidserver/server.py b/fdroidserver/deploy.py similarity index 98% rename from fdroidserver/server.py rename to fdroidserver/deploy.py index 9ae21d5f..724487d5 100644 --- a/fdroidserver/server.py +++ b/fdroidserver/deploy.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# server.py - part of the FDroid server tools +# deploy.py - part of the FDroid server tools # Copyright (C) 2010-15, Ciaran Gultnieks, ciaran@ciarang.com # # This program is free software: you can redistribute it and/or modify @@ -41,7 +41,7 @@ start_timestamp = time.gmtime() BINARY_TRANSPARENCY_DIR = 'binary_transparency' -AUTO_S3CFG = '.fdroid-server-update-s3cfg' +AUTO_S3CFG = '.fdroid-deploy-s3cfg' USER_S3CFG = 's3cfg' REMOTE_HOSTNAME_REGEX = re.compile(r'\W*\w+\W+(\w+).*') @@ -344,7 +344,7 @@ def update_servergitmirrors(servergitmirrors, repo_section): from clint.textui import progress if config.get('local_copy_dir') \ and not config.get('sync_from_local_copy_dir'): - logging.debug('Offline machine, skipping git mirror generation until `fdroid server update`') + logging.debug(_('Offline machine, skipping git mirror generation until `fdroid deploy`')) return # right now we support only 'repo' git-mirroring @@ -697,10 +697,8 @@ def update_wiki(): def main(): global config, options - # Parse command line... parser = ArgumentParser() common.setup_global_opts(parser) - parser.add_argument("command", help=_("command to execute, either 'init' or 'update'")) parser.add_argument("-i", "--identity-file", default=None, help=_("Specify an identity file to provide to SSH for rsyncing")) parser.add_argument("--local-copy-dir", default=None, @@ -710,13 +708,8 @@ def main(): parser.add_argument("--no-keep-git-mirror-archive", action="store_true", default=False, help=_("If a git mirror gets to big, allow the archive to be deleted")) options = parser.parse_args() - config = common.read_config(options) - if options.command != 'update': - logging.critical(_("The only command currently supported is 'update'")) - sys.exit(1) - if config.get('nonstandardwebroot') is True: standardwebroot = False else: diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 671c217a..63e7d131 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -301,7 +301,7 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, if not options.no_deploy: try: - cmd = ['fdroid', 'server', 'update', '--verbose', '--no-keep-git-mirror-archive'] + cmd = ['fdroid', 'deploy', '--verbose', '--no-keep-git-mirror-archive'] subprocess.check_call(cmd, cwd=repo_basedir) except subprocess.CalledProcessError: logging.error(_('cannot publish update, did you set the deploy key?') diff --git a/locale/POTFILES.in b/locale/POTFILES.in index 7d31bec0..07ad4fcc 100644 --- a/locale/POTFILES.in +++ b/locale/POTFILES.in @@ -3,6 +3,7 @@ fdroidserver/btlog.py fdroidserver/build.py fdroidserver/checkupdates.py fdroidserver/common.py +fdroidserver/deploy.py fdroidserver/import.py fdroidserver/init.py fdroidserver/install.py @@ -11,7 +12,6 @@ fdroidserver/metadata.py fdroidserver/publish.py fdroidserver/rewritemeta.py fdroidserver/scanner.py -fdroidserver/server.py fdroidserver/stats.py fdroidserver/update.py fdroidserver/verify.py diff --git a/locale/fdroidserver.pot b/locale/fdroidserver.pot index cb5017a6..31ab5fc6 100644 --- a/locale/fdroidserver.pot +++ b/locale/fdroidserver.pot @@ -66,7 +66,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -505,12 +505,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -519,7 +519,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -554,12 +554,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -621,7 +621,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -684,7 +684,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -722,7 +722,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -848,7 +848,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -896,11 +896,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1131,7 +1131,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1193,7 +1193,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1407,12 +1407,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1506,7 +1506,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1613,11 +1613,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1680,7 +1680,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1692,7 +1692,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1710,7 +1710,7 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" @@ -1901,12 +1901,12 @@ msgstr "" msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1941,7 +1941,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1968,7 +1968,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1989,7 +1989,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2122,7 +2122,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2287,16 +2287,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2432,7 +2432,7 @@ msgstr "" msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2520,12 +2520,12 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" @@ -2642,7 +2642,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/tests/server.TestCase b/tests/deploy.TestCase similarity index 83% rename from tests/server.TestCase rename to tests/deploy.TestCase index 4236d6e5..2ce5e500 100755 --- a/tests/server.TestCase +++ b/tests/deploy.TestCase @@ -15,29 +15,29 @@ if localmodule not in sys.path: sys.path.insert(0, localmodule) import fdroidserver.common -import fdroidserver.server +import fdroidserver.deploy from testcommon import TmpCwd -class ServerTest(unittest.TestCase): - '''fdroidserver/server.py''' +class DeployTest(unittest.TestCase): + '''fdroidserver/deploy.py''' def setUp(self): logging.basicConfig(level=logging.DEBUG) self.basedir = os.path.join(localmodule, 'tests') - fdroidserver.server.options = mock.Mock() - fdroidserver.server.config = {} + fdroidserver.deploy.options = mock.Mock() + fdroidserver.deploy.config = {} def test_update_serverwebroot_make_cur_version_link(self): # setup parameters for this test run - fdroidserver.server.options.no_chcksum = True - fdroidserver.server.options.identity_file = None - fdroidserver.server.options.verbose = False - fdroidserver.server.options.quiet = True - fdroidserver.server.options.identity_file = None - fdroidserver.server.config['make_current_version_link'] = True + fdroidserver.deploy.options.no_chcksum = True + fdroidserver.deploy.options.identity_file = None + fdroidserver.deploy.options.verbose = False + fdroidserver.deploy.options.quiet = True + fdroidserver.deploy.options.identity_file = None + fdroidserver.deploy.config['make_current_version_link'] = True serverwebroot = "example.com:/var/www/fdroid" repo_section = 'repo' @@ -86,19 +86,19 @@ class ServerTest(unittest.TestCase): os.symlink('repo/com.example.sym.apk.asc', 'Sym.apk.asc') os.symlink('repo/com.example.sym.apk.sig', 'Sym.apk.sig') with mock.patch('subprocess.call', side_effect=update_server_webroot_call): - fdroidserver.server.update_serverwebroot(serverwebroot, + fdroidserver.deploy.update_serverwebroot(serverwebroot, repo_section) self.assertEqual(call_iteration, 3, 'expected 3 invocations of subprocess.call') def test_update_serverwebroot_with_id_file(self): # setup parameters for this test run - fdroidserver.server.options.no_chcksum = False - fdroidserver.server.options.verbose = True - fdroidserver.server.options.quiet = False - fdroidserver.server.options.identity_file = None - fdroidserver.server.config['identity_file'] = './id_rsa' - fdroidserver.server.config['make_current_version_link'] = False + fdroidserver.deploy.options.no_chcksum = False + fdroidserver.deploy.options.verbose = True + fdroidserver.deploy.options.quiet = False + fdroidserver.deploy.options.identity_file = None + fdroidserver.deploy.config['identity_file'] = './id_rsa' + fdroidserver.deploy.config['make_current_version_link'] = False serverwebroot = "example.com:/var/www/fdroid" repo_section = 'archive' @@ -115,7 +115,7 @@ class ServerTest(unittest.TestCase): '--verbose', '-e', 'ssh -oBatchMode=yes -oIdentitiesOnly=yes -i ' - + fdroidserver.server.config['identity_file'], + + fdroidserver.deploy.config['identity_file'], '--exclude', 'archive/index.xml', '--exclude', 'archive/index.jar', '--exclude', 'archive/index-v1.jar', @@ -129,7 +129,7 @@ class ServerTest(unittest.TestCase): '--verbose', '-e', 'ssh -oBatchMode=yes -oIdentitiesOnly=yes -i ' - + fdroidserver.server.config['identity_file'], + + fdroidserver.deploy.config['identity_file'], 'archive', serverwebroot]) else: @@ -138,15 +138,15 @@ class ServerTest(unittest.TestCase): return 0 with mock.patch('subprocess.call', side_effect=update_server_webroot_call): - fdroidserver.server.update_serverwebroot(serverwebroot, + fdroidserver.deploy.update_serverwebroot(serverwebroot, repo_section) self.assertEqual(call_iteration, 2, 'expected 2 invocations of subprocess.call') @unittest.skipIf(not os.getenv('VIRUSTOTAL_API_KEY'), 'VIRUSTOTAL_API_KEY is not set') def test_upload_to_virustotal(self): - fdroidserver.server.options.verbose = True + fdroidserver.deploy.options.verbose = True virustotal_apikey = os.getenv('VIRUSTOTAL_API_KEY') - fdroidserver.server.upload_to_virustotal('repo', virustotal_apikey) + fdroidserver.deploy.upload_to_virustotal('repo', virustotal_apikey) def test_remote_hostname_regex(self): for remote_url, name in ( @@ -158,7 +158,7 @@ class ServerTest(unittest.TestCase): ): self.assertEqual( name, - fdroidserver.server.REMOTE_HOSTNAME_REGEX.sub(r'\1', remote_url) + fdroidserver.deploy.REMOTE_HOSTNAME_REGEX.sub(r'\1', remote_url) ) @@ -171,5 +171,5 @@ if __name__ == "__main__": (fdroidserver.common.options, args) = parser.parse_args(['--verbose']) newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(ServerTest)) + newSuite.addTest(unittest.makeSuite(DeployTest)) unittest.main(failfast=False) diff --git a/tests/main.TestCase b/tests/main.TestCase index e05efd95..11e4410b 100755 --- a/tests/main.TestCase +++ b/tests/main.TestCase @@ -42,7 +42,6 @@ class MainTest(unittest.TestCase): 'lint', 'scanner', 'stats', - 'server', 'signindex', 'btlog', 'signatures', @@ -63,7 +62,7 @@ class MainTest(unittest.TestCase): def test_call_deploy(self): co = mock.Mock() with mock.patch('sys.argv', ['', 'deploy', '-h']): - with mock.patch('fdroidserver.server.main', co): + with mock.patch('fdroidserver.deploy.main', co): with mock.patch('sys.exit') as exit_mock: fdroidserver.__main__.main() # note: this is sloppy, if `deploy` changes diff --git a/tests/run-tests b/tests/run-tests index 66b00ed7..ea878c83 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -691,7 +691,7 @@ $fdroid lint $fdroid readmeta $fdroid rewritemeta fake $fdroid deploy -$fdroid server update +$fdroid deploy $fdroid scanner # run these to get their output, but the are not setup, so don't fail @@ -725,26 +725,26 @@ cd $REPOROOT $fdroid init $fdroid update --create-metadata --verbose $fdroid readmeta -$fdroid server update --local-copy-dir=/tmp/fdroid +$fdroid deploy --local-copy-dir=/tmp/fdroid $fdroid deploy --local-copy-dir=/tmp/fdroid --verbose # now test the errors work set +e -$fdroid server update --local-copy-dir=thisisnotanabsolutepath +$fdroid deploy --local-copy-dir=thisisnotanabsolutepath if [ $? -eq 0 ]; then echo "This should have failed because thisisnotanabsolutepath is not an absolute path!" exit 1 else echo "testing absolute path checker passed" fi -$fdroid server update --local-copy-dir=/tmp/IReallyDoubtThisPathExistsasdfasdf +$fdroid deploy --local-copy-dir=/tmp/IReallyDoubtThisPathExistsasdfasdf if [ $? -eq 0 ]; then echo "This should have failed because the path does not end with 'fdroid'!" exit 1 else echo "testing dirname exists checker passed" fi -$fdroid server update --local-copy-dir=/tmp/IReallyDoubtThisPathExistsasdfasdf/fdroid +$fdroid deploy --local-copy-dir=/tmp/IReallyDoubtThisPathExistsasdfasdf/fdroid if [ $? -eq 0 ]; then echo "This should have failed because the dirname path does not exist!" exit 1 @@ -766,12 +766,12 @@ $fdroid readmeta grep -F '> config.py $fdroid update --verbose if have_git_2_3; then - $fdroid server update --verbose + $fdroid deploy --verbose test -e repo/index.xml test -e repo/index.jar test -e repo/index-v1.jar @@ -1204,7 +1204,7 @@ if have_git_2_3; then cd binary_transparency [ `git rev-list --count HEAD` == "1" ] cd .. - $fdroid server update --verbose + $fdroid deploy --verbose grep -F '> config.py @@ -1213,7 +1213,7 @@ if have_git_2_3; then echo "servergitmirrors = '$SERVER_GIT_MIRROR'" >> config.py echo "local_copy_dir = '$LOCAL_COPY_DIR'" >> config.py echo "binary_transparency_remote = '$BINARY_TRANSPARENCY_REMOTE'" >> config.py - $fdroid server update --verbose + $fdroid deploy --verbose cd $BINARY_TRANSPARENCY_REMOTE [ `git rev-list --count HEAD` == "1" ] cd $SERVER_GIT_MIRROR From 3e35b2dd27c0a3b22783474a08d18825e5ccbdb2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 21 Oct 2020 18:05:32 +0200 Subject: [PATCH 0591/2775] make -C locale update --- locale/bn/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/bo/LC_MESSAGES/fdroidserver.po | 122 ++++++++++--------- locale/cs/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/de/LC_MESSAGES/fdroidserver.po | 130 +++++++++++---------- locale/es/LC_MESSAGES/fdroidserver.po | 123 ++++++++++--------- locale/es_AR/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/es_MX/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/fa/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/fdroidserver.pot | 39 +++++-- locale/fr/LC_MESSAGES/fdroidserver.po | 123 ++++++++++--------- locale/hu/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/id/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/it/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/ja/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/kab/LC_MESSAGES/fdroidserver.po | 108 +++++++++-------- locale/ko/LC_MESSAGES/fdroidserver.po | 118 ++++++++++--------- locale/ml/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/nb_NO/LC_MESSAGES/fdroidserver.po | 119 ++++++++++--------- locale/nl/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/pl/LC_MESSAGES/fdroidserver.po | 117 ++++++++++--------- locale/pt/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 130 +++++++++++---------- locale/pt_PT/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/ru/LC_MESSAGES/fdroidserver.po | 118 ++++++++++--------- locale/sk/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/sq/LC_MESSAGES/fdroidserver.po | 118 ++++++++++--------- locale/sv/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/tr/LC_MESSAGES/fdroidserver.po | 119 +++++++++++-------- locale/tzm/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/ug/LC_MESSAGES/fdroidserver.po | 108 +++++++++-------- locale/uk/LC_MESSAGES/fdroidserver.po | 119 +++++++++++-------- locale/zh_Hans/LC_MESSAGES/fdroidserver.po | 107 ++++++++++------- locale/zh_Hant/LC_MESSAGES/fdroidserver.po | 130 +++++++++++---------- 33 files changed, 2071 insertions(+), 1589 deletions(-) diff --git a/locale/bn/LC_MESSAGES/fdroidserver.po b/locale/bn/LC_MESSAGES/fdroidserver.po index 10c8b2be..4e58c37d 100644 --- a/locale/bn/LC_MESSAGES/fdroidserver.po +++ b/locale/bn/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -65,7 +65,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -504,12 +504,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -518,7 +518,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -553,12 +553,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -620,7 +620,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -656,6 +656,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -683,7 +687,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -721,7 +725,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -847,7 +851,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -895,11 +899,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1130,7 +1134,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1192,7 +1196,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1260,6 +1264,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1406,12 +1414,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1505,7 +1513,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1612,11 +1620,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1679,7 +1687,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1691,7 +1699,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1709,14 +1717,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1860,11 +1864,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1896,16 +1895,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1940,7 +1948,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1967,7 +1975,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1988,7 +1996,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2121,7 +2129,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2286,16 +2294,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2427,11 +2435,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2519,15 +2532,19 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2641,7 +2658,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/bo/LC_MESSAGES/fdroidserver.po b/locale/bo/LC_MESSAGES/fdroidserver.po index 43ae3895..a6c83c2a 100644 --- a/locale/bo/LC_MESSAGES/fdroidserver.po +++ b/locale/bo/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2018-02-13 08:41+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Tibetan \n" @@ -73,7 +73,7 @@ msgstr "\"{path}\"དུས་ཚོད་ཡོལ་ཟིན་པའི་{n msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" ཉེ་ཆར་{name} ({version})རྣམས་ཚུད་ཡོད།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -386,7 +386,6 @@ msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" @@ -516,12 +515,12 @@ msgstr "ལྡེ་མིག་གསོག་ཉར་ཁག་གི་ནང msgid "Create skeleton metadata files that are missing" msgstr "བོར་བརླག་ཏུ་སོང་བའི་ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་ཡང་སྐྱར་བཟོས།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "དྲྭ་སྣོད་གསར་པ་བཟོས་\"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -530,7 +529,7 @@ msgstr "" msgid "Creating log directory" msgstr "ཉིན་ཐོ་ཕྱོགས་དེབ་བཟོ་བཞིན་པ།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "S3 སྣོད་གསར་པ་བཟོ་བཞིན་པ།:{url}" @@ -565,12 +564,12 @@ msgstr "DEBUG_KEYSTORE སྒྲིག་བཀོད་བྱེད་མིན msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "APKs དང/ཡང་ནOBBs གཉིས་ལ་རེ་པོ་ནས་འགྲེལ་ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་མེད་པ་རྣམས་སུབས།" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -632,7 +631,7 @@ msgstr "ཐོ་གཞུང་དང་འབྲེལ་བ་ཡོད་པ msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "མཛོད་ཁང་སྐྱར་སོས་མ་བྱེད། དྲྭ་རྒྱ་མེད་པའི་སྐབས་ལ་ཐོན་སྐྱེད་ཚོད་ལྟ་བྱེད་པར་ཕན་ཐོགས་ཡོང་།" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "rsync ཡིག་ཚགས་བརྟག་དཔྱད་ཀྱི་གསོག་ཉར་ཁང་འདི་བེད་སྤྱོད་མ་བྱེད།" @@ -668,6 +667,10 @@ msgstr "'{field}'ནང་གི་ངོ་བཤུས་སྦྲེལ་མ msgid "Dynamically scan APKs post build" msgstr "APKs ཐོན་སྐྱེད་རྗེས་ཀྱི་ཞིབ་ཚགས་པོའི་འཚག་རྒྱབ།" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -697,7 +700,7 @@ msgstr "" "ཨེན་ཀྲོཌ་SDKགྱི་ལམ་འདིར་ཡོད་པས་ནང་འཛུལ་བྱེད། (%s) :\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, fuzzy, python-format msgid "Error while attempting to publish log: %s" @@ -735,7 +738,7 @@ msgstr "ཆེ་ཆུང་སྐྱར་སྒྲིག་ཐུབ་མ་ msgid "Failed to align application" msgstr "མཉེན་ཆས་ཡོད་རྣམས་ཕྱོགས་སྒྲིག་བྱེད་ཐུབ་མ་སོང་།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "S3 དྲྭ་སྣོད་བཟོས་ཐུབ་མ་སོང་། :{url}" @@ -863,7 +866,7 @@ msgstr "མཛོད་ཁང་ཆེད་དུ་མིང་རྟགས་ msgid "Found non-file at %s" msgstr "འདི་ལ་%s 1 ཡིག་ཆ་མིན་པ་རྙེད་སོང་།" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "{path} ནང་ལ་ {apkfilename}ཤུས་བཞིན་པ།" @@ -911,11 +914,11 @@ msgstr "གིཊ་ཡན་ལག་རྒྱ་ཁྱོན་གསར་བ msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1119,7 +1122,6 @@ msgstr "མིང་རྟགས་བཀོད་པའི་ལྡེ་མི #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "ཁས་ལེན་བྱས་པའི་བེད་སྤྱོད་ཐ་མ་ '{commit}' སྦྱར་བ་འདྲ་པོ་འདུག, འོན་ཀྱང་གསར་བསྒྱུར་ཡོད་མེད་འཚོལ་བྱེད་ནི།'{ucm}'" @@ -1149,7 +1151,7 @@ msgstr "དམིགས་བསལ་གྱི་གནས་སྐབས་ལ msgid "Malformed repository mirrors." msgstr "བཟོ་ལྟ་མེད་པའི་མཛོད་ཁང་ཤེལ་སྒོ་རྣམས།." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "བཟོ་ལྟ་ཤོར་བའི་ serverwebroot line:" @@ -1212,7 +1214,7 @@ msgstr "མཉེས་ཆས་འདི་རིན་མེད་མཉེན msgid "No need to specify that the app is for Android" msgstr "མཉེན་ཆས་འདི་ཨེན་ཀྲོཌ་ཆེད་དུ་ཡིན་པ་དམིགས་སྟོན་བྱེད་དགོས་དོན་མེད།" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "གདམ་ཀ་མེད་པ་སྒྲིག།! ཁྱེད་རང་གི་config.py འདིའི་ནང་ནས་མ་མཐའ་ཡིན་ཡང་གང་རུང་ཞིག་རྩོམ་སྒྲིག་བྱེད་:" @@ -1281,6 +1283,10 @@ msgstr "OBB ཡིག་ཆའི་མིང་ངེས་པར་དུ་\" msgid "OBB's packagename does not match a supported APK:" msgstr "OBB's ཐུམ་སྒྲིལ་མིང་འདིས་APK རྒྱབ་སྐྱོར་ཡོད་པ་དང་མཐུན་གྱི་མིན་འདུག:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1428,12 +1434,12 @@ msgstr "ཡི་གེའི་བར་རྟགས་རིགས་ངེས msgid "Push the log to this git remote repository" msgstr "ཐོ་གཞུད་འདི་གིཊ་ཐག་རིང་གི་མཛོད་ཁང་ནང་འབུད་རྒྱག་གཏོང་།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "{url}ཆེད་དུ་ཨང་གྲངས་ཀྱི་ཐོ་གཞུང་གསར་བསྒྱུར།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "{url}ཕྱོགས་ལ་འབུད་རྒྱབ་རྒྱོབ།" @@ -1527,7 +1533,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "བཀོད་སྒྲིག་འདི་ག་རང་ལ་སྐྱར་བྲིས་བྱེད།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "MD5 ཚོད་ལྟ་བེད་སྤྱོད་མེད་པ་དང་མཉམ་དུ་ཐེངས་དང་པོ་འཁོར་སྐྱོད་བྱེད་བཞིན་པ།" @@ -1633,11 +1639,11 @@ msgstr "མཆོང་བཞིན་པ་ {appid}: བེད་མེད།" msgid "Skipping {appid}: no builds specified" msgstr "མཆོང་བཞིན་པ་ {appid}: བཟོ་སྐྲུན་དམིགས་སྟོན་མིན་འདུག" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "བསྟི་གནས་ཀྱི་ཡིག་ཁུག་གཅིག་ཁ་ཕྱེས་ནས་རེ་པོ་འདི་ལ་མཉམ་བསྲེས།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "rsync གྱི་ཆེད་དུ་SSH འདི་ངོ་ཐག་ཆོད་པའི་ཡིག་ཆ་ཞིག་དམིགས་སུ་བཀར་ནས་སྟེར།" @@ -1700,7 +1706,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "(path or glob)རེ་པོ་ནང་ཚུད་པའི་ཡིག་ཆ།" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "ལག་བསྟར་བྱེད་རྒྱུར་བཀའ་གཏོང། ཡང་ན་'init'འམ་ཡང་ན་ 'གསར་བསྒྱུར།'" @@ -1712,7 +1718,7 @@ msgstr "མཛོད་ཁང་གི་མཛུབ་མཐིལ་དང་ msgid "The repository's index could not be verified." msgstr "མཛོད་ཁང་གི་ཕྱོགས་སྟོན་ར་སྤྲོད་ཐུབ་མ་སོང་།." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "dir གྱི་རྩ་བ་ for local_copy_dir \"{path}\" མིན་འདུག!" @@ -1730,14 +1736,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "རེ་པོ་འདི་ལ་སྔོན་ཚོད་ནས་ས་གནས་ཀྱི་རྒྱབ་ལྗོངས་ཡིག་ཆ་འདུག: %s 1" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "awsbucket, awssecretkey དང་། awsaccesskeyid བེད་སྤྱོད་བྱེད་པའི་ཆེད་དུ་ config.py ནང་དུ་ངེས་པར་དུ་སྒྲིག་དགོས།!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckModeསྒྲིག་བཀོད་བྱས་ཟིན་ཡང་གསར་བསྒྱུར་འཚོལ་བ་དེ་འགོ་འཛུགས་མིན་འདུག" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1882,13 +1884,6 @@ msgstr "%s 1 དེ་ལ་བེད་སྤྱོད་མེད་པའི msgid "Unused scanignore path: %s" msgstr "%s 1 དེ་ལ་བེད་སྤྱོད་མེད་པའི་ཡིག་ཆ།" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "མཉེན་ཆས་ཁ་བྱང་ནང་ལ་གསར་བསྒྱུར་འཚོལ་བའི་མིང་སྒྲིག་ཚར་འདུག -འདི་སུབས་ཆོག་གི་རེད།" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "ཐུམ་སྒྲིལ་གསར་པའི་ཆེད་དུ་རེ་པོ་གནས་ཚུལ་གསར་བསྒྱུར་བྱེད།" @@ -1920,18 +1915,27 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckModeསྒྲིག་བཀོད་བྱས་ཟིན་ཡང་གསར་བསྒྱུར་འཚོལ་བ་དེ་འགོ་འཛུགས་མིན་འདུག" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "མཉེན་ཆས་ཁ་བྱང་ནང་ལ་གསར་བསྒྱུར་འཚོལ་བའི་མིང་སྒྲིག་ཚར་འདུག -འདི་སུབས་ཆོག་གི་རེད།" + #: ../fdroidserver/lint.py #, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "མཉེན་ཆས་ཁ་བྱང་ནང་ལ་གསར་བསྒྱུར་འཚོལ་བའི་མིང་སྒྲིག་ཚར་འདུག -འདི་སུབས་ཆོག་གི་རེད།" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "སྦས་ཁུང་ནས་ {apkfilename}ཀློག་བཞིན་པ།" @@ -1966,7 +1970,7 @@ msgstr "APK རང་གི་ཚེས་གྲངས་དེ་བེད་ msgid "Use date from apk instead of current time for newly added apks" msgstr "apk རང་གི་ཚེས་གྲངས་དེ་བེད་སྤྱོད་བྱས་པ་ལས་ཁ་སྣོན་བྱས་པའི་apk གསར་པའི་དུས་ཚོས་བེད་སྤྱོད་མ་བྱེད།" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1993,7 +1997,7 @@ msgstr "སྐྱར་བྲིས་ཡོད་།{path}" msgid "Using existing keystore \"{path}\"" msgstr "སྐྱར་བྲིས་ཡོད་།{path}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "s3cmd བེད་སྤྱོད་བྱས་ནས་: {url}1དང་མཉམ་དུ་sync" @@ -2014,7 +2018,7 @@ msgstr "ཕབ་ལེན་བྱས་པའི་ཐུམ་སྒྲིལ msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2075,7 +2079,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "མཉེས་ཆས་ཁ་བྱང་རྒྱུད་གསར་བསྒྱར་ཡོད་མིན་ལྟོས།" @@ -2083,7 +2086,6 @@ msgstr "མཉེས་ཆས་ཁ་བྱང་རྒྱུད་གསར་ #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "མཉེན་ཆས་ཀྱི་ངོ་བོ་དང་མཉམ་དུ་གདམ་ཀ་ཅན་གྱི་ཐོན་རིམ་ཨང་རྟགས་APPID[:VERCODE]" @@ -2152,7 +2154,7 @@ msgstr "པར་སྐྲུན་གསར་བསྒྱུར་བྱེད msgid "cloning {url}" msgstr "འདྲ་བཟོས་{url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "ལག་བསྟར་བྱེད་རྒྱུར་བཀའ་གཏོང། ཡང་ན་'init'འམ་ཡང་ན་ 'གསར་བསྒྱུར།'" @@ -2318,16 +2320,16 @@ msgstr "ཁུངས་ལྡན་མིན་པའི་རྙོག་ཕྲ msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "ཁུངས་ལྡན་མིན་པའི་ཚིག་སྒྲུབ་གདམ་ཀ། %(option)r: ཁྱད་ཆོས་དང་མཉམ་དུ་འགོ་བཙུགས། %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir \"fdroid\"གིས་མཇུག་སྐྱོང་མིན་འདུག་ : \"{path}1\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir ནི་ངེས་པར་དུ་མཐའ་མའི་འགྲོ་ལམ་དེ་ཆགས་ཡོད།!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir ངེས་པར་ཕྱོགས་དེབ་ཡིན་དགོས། ཡིག་ཆ་མ་རེད།!" @@ -2459,11 +2461,16 @@ msgstr "བདེ་ཆགས་མེད་པའི་HTTPMམཐུད་ཀ msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "བེད་ཆགས་མེད་པའི་དྲྭ་རྒྱའི་ཁ་བྱང་http ནས་ཕབ་ལེན་བཀག། (use https or specify --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sync ཕྱོགས་སྟོན།{path}1 དེ་ནས {url} དང་སུབས།" @@ -2551,15 +2558,19 @@ msgstr "བེད་སྤྱོད།: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "བེད་སྤྱོད་: ཨེཕ་རོཌ་[-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "Apache libcloud བེད་སྤྱོད་བྱས་པའི་ཐོག་ {url}1དང་མཉམ་དུ་ཟླ་སྒྲིལ་གཏོང་།" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2583,7 +2594,6 @@ msgstr "AndroidManifest.xmlལ་ཟླ་ཚེས་མིན་འདུག" #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "{appid} ལ་མིང་ཡོད་མ་རེད། !དེའི་ཚབ་ལ་ཐུམ་སྒྲིལ་མིང་བེད་སྤྱོད་བྱེད།." @@ -2673,7 +2683,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "{path} ལ་ཆེ་ཆུང་མེད།!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" @@ -2698,6 +2708,9 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} བཟོ་སྐྲུན་ལེགས་སྒྲུབ།" +#~ msgid "Android Build Tools path '{path}' does not exist!" +#~ msgstr "ཨེན་ཀྲོཌ་བཟོ་སྐྲུན་མ་ལག་ཐབས་ལམ '{path}1' མིན་འདུག!" + #~ msgid "Cannot find a packageName for {path}!" #~ msgstr "{path}གྱི་ཆེད་དུ་ཐུམ་སྒྲིལ་གྱི་མིང་རྙེད་མ་སོང་།!" @@ -2705,9 +2718,6 @@ msgstr[0] "{} བཟོ་སྐྲུན་ལེགས་སྒྲུབ།" #~ msgid "Cannot find an appid for {path}!" #~ msgstr "{path}!གྱི་ཆེད་དུ་ཐུམ་སྒྲིལ་གྱི་མིང་རྙེད་མ་སོང་།" -#~ msgid "Android Build Tools path '{path}' does not exist!" -#~ msgstr "ཨེན་ཀྲོཌ་བཟོ་སྐྲུན་མ་ལག་ཐབས་ལམ '{path}1' མིན་འདུག!" - #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "གསར་བསྒྱུར་གཙང་བཟོ།-ཡིག་ཆ་གསོག་ཉར་བེད་སྤྱོ་མ་བྱེད། apks ཚང་མ་སྐྱར་སྤྱོད་བྱེད།" diff --git a/locale/cs/LC_MESSAGES/fdroidserver.po b/locale/cs/LC_MESSAGES/fdroidserver.po index 94fbddd3..78a8aeab 100644 --- a/locale/cs/LC_MESSAGES/fdroidserver.po +++ b/locale/cs/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2019-02-01 13:33+0000\n" "Last-Translator: Michal Čihař \n" "Language-Team: Czech \n" @@ -66,7 +66,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -508,12 +508,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -522,7 +522,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -557,12 +557,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -624,7 +624,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -660,6 +660,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -687,7 +691,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -725,7 +729,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -851,7 +855,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -899,11 +903,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1134,7 +1138,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1196,7 +1200,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1264,6 +1268,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1410,12 +1418,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1509,7 +1517,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1617,11 +1625,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1684,7 +1692,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1696,7 +1704,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1714,14 +1722,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1865,11 +1869,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1901,16 +1900,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1945,7 +1953,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1972,7 +1980,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1993,7 +2001,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2126,7 +2134,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2293,16 +2301,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2434,11 +2442,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2526,15 +2539,19 @@ msgstr "použití: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2649,7 +2666,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index 17b98cb9..d036f86c 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-15 17:12+0000\n" "Last-Translator: marzzzello \n" "Language-Team: German \n" @@ -82,7 +82,7 @@ msgstr "{name} ({version}) in „{path}” veraltet" msgid "\"{path}\" contains recent {name} ({version})" msgstr "{name} ({version}) in \"{path}\" ist aktuell" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "„{path}” vorhanden, aber S3cmd ist nicht installiert!" @@ -396,7 +396,6 @@ msgstr "„{path}” konnte nicht gelesen werden!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "AppID {appid} konnte nicht aufgelöst werden" @@ -526,12 +525,12 @@ msgstr "Repository-Signierschlüssel in einem Schlüsselspeicher erstellen" msgid "Create skeleton metadata files that are missing" msgstr "Gerüst für fehlende Metadaten-Dateien erstellen" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Neuer Container „{name}” wurde erstellt" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "„{path}” für die Konfiguration von S3cmd wird erstellt." @@ -540,7 +539,7 @@ msgstr "„{path}” für die Konfiguration von S3cmd wird erstellt." msgid "Creating log directory" msgstr "Erstelle Log Verzeichnis" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Neuer S3-Bucket wird erstellt: {url}" @@ -575,12 +574,12 @@ msgstr "DEBUG_KEYSTORE ist nicht festgelegt oder der Wert ist unvollständig" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "APKs und/oder OBBs ohne Metadaten aus dem Repository löschen" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "Archiv löschen, Repo ist zu groß ({size} max {limit})" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "Git-Mirror-Verlauf löschen, Repository ist zu groß ({size} max {limit})" @@ -642,7 +641,7 @@ msgstr "Mache auf Logs bezogen nichts" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Keine Aktualisierung des Repositorys. Nützlich, wenn ein Build ohne Internetverbindung getestet wird" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Keine rsync-Prüfsummen verwenden" @@ -678,6 +677,10 @@ msgstr "Link in „{field}” duplizieren: {url}" msgid "Dynamically scan APKs post build" msgstr "APKs nach Erstellung dynamisch durchsuchen" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -709,7 +712,7 @@ msgstr "" "Geben Sie hier den Pfad zum Android-SDK (%s) ein:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -747,7 +750,7 @@ msgstr "Größenanpassung von {path} fehlgeschlagen: {error}" msgid "Failed to align application" msgstr "Anwendung konnte nicht angepasst werden" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "S3-Bucket konnte nicht erstellt werden: {url}" @@ -874,7 +877,7 @@ msgstr "Es wurden keine Signaturzertifikate für das Repository gefunden." msgid "Found non-file at %s" msgstr "Eine Nicht-Datei gefunden bei %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "Kopiere {apkfilename} nach {path}" @@ -922,12 +925,12 @@ msgstr "Git submodule update fehlgeschlagen" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS muss bei Subversion-URLs verwendet werden!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "Wenn ein Git-Mirror zu groß wird, kann das Archiv gelöscht werden" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "Wenn dieser Upload fehlschlägt, versuchen Sie ihn manuell auf {url} hochzuladen." @@ -1019,7 +1022,6 @@ msgstr "Ungültige VercodeOperation: {field}" #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" msgid "Invalid application ID {appid}" msgstr "Ungültige VercodeOperation: {field}" @@ -1132,7 +1134,6 @@ msgstr "Schlüsselspeicher für den Signierschlüssel:\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Der zuletzt verwendete Commit '{commit}' sieht aus wie ein Tag, aber der Update Check Modus ist '{ucm}'" @@ -1161,7 +1162,7 @@ msgstr "Erstellung bei Fehlern anhalten" msgid "Malformed repository mirrors." msgstr "Fehlerhafte Repository Mirrors." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Fehlerhafte serverwebroot Zeile:" @@ -1224,7 +1225,7 @@ msgstr "Sie müssen nicht angeben, dass die App freie Software ist" msgid "No need to specify that the app is for Android" msgstr "Sie müssen nicht angeben, dass die App für Android ist" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Keine Option gesetzt! Bearbeiten Sie Ihre config.py, um mindestens eine davon zu setzen:" @@ -1292,6 +1293,10 @@ msgstr "Der OBB Dateiname muss mit \"main.\" oder \"patch.\" beginnen:" msgid "OBB's packagename does not match a supported APK:" msgstr "Der OBB-Packetname stimmt mit keinem unterstützten APK überein:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1439,12 +1444,12 @@ msgstr "Interpunktion sollte vermieden werden" msgid "Push the log to this git remote repository" msgstr "Anmeldung an diesem Git-Repository durchführen" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Binäres Transparenz-Log nach {url} pushen" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Pushen auf {url}" @@ -1538,7 +1543,7 @@ msgstr "Auf Git Repo, das nicht committete Änderungen hat, laufen lassen" msgid "Run rewritemeta to fix formatting" msgstr "Metadaten neu schreiben, um Formatierungen zu korrigieren" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Erster Durchlauf mit MD5-Prüfung abgeschaltet" @@ -1645,11 +1650,11 @@ msgstr "Überspringen von {appid}: deaktiviert" msgid "Skipping {appid}: no builds specified" msgstr "Überspringe {appid}: keine Builds angegeben" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Einen lokalen Ordner bestimmen, in dem das Repository synchronisiert wird" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Eine Identitätsdatei bestimmen, die bei Re-Synchronisation an SSH übergeben wird" @@ -1712,7 +1717,7 @@ msgstr "Das Verzeichnis, in das der Mirror geschrieben werden soll" msgid "The file to be included in the repo (path or glob)" msgstr "Die in das Repo aufzunehmende Datei (Pfad oder Glob)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Derzeit werden nur die Befehle „init” und „update” unterstützt" @@ -1724,7 +1729,7 @@ msgstr "Der Fingerabdruck des Repositories stimmt nicht." msgid "The repository's index could not be verified." msgstr "Der Index des Repositories konnte nicht verifiziert werden." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "Das Wurzelverzeichnis für local_copy_dir \"{path}\" existiert nicht!" @@ -1742,14 +1747,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "Dieses Repo hat bereits lokale Metadaten: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Um awsbucket zu benutzen, müssen awssecretkey und awsaccesskeyid auch in der config.py gesetzt sein!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode ist gesetzt, aber es sieht so aus, als ob checkupdates noch nicht ausgeführt wurde" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1894,13 +1895,6 @@ msgstr "Nicht verwendete Datei bei %s" msgid "Unused scanignore path: %s" msgstr "Nicht verwendete Datei bei %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Update Check Name ist auf die bekannte App-ID gesetzt - sie kann entfernt werden" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Paketquelleninformationen zu neuen Programmpaketen aktualisieren" @@ -1932,18 +1926,27 @@ msgstr "UpdateCheckData muss HTTPS-URL verwenden: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData hat eine ungültige URL: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode ist gesetzt, aber es sieht so aus, als ob checkupdates noch nicht ausgeführt wurde" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "Update Check Name ist auf die bekannte App-ID gesetzt - sie kann entfernt werden" + #: ../fdroidserver/lint.py #, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "Update Check Name ist auf die bekannte App-ID gesetzt - sie kann entfernt werden" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "Lese {apkfilename} aus dem Cache" @@ -1978,7 +1981,7 @@ msgstr "APK-Datum statt der aktuellen Zeit für neu hinzugefügte APKs verwenden msgid "Use date from apk instead of current time for newly added apks" msgstr "APK-Datum statt der aktuellen Zeit für neu hinzugefügte APKs verwenden" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Verwende {path} zur Konfiguration von s3cmd." @@ -2005,7 +2008,7 @@ msgstr "Verwende Androguard von \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Verwende vorhandenen Schlüsselspeicher \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Verwende s3cmd zum Synchronisieren mit: {url}" @@ -2026,7 +2029,7 @@ msgstr "Integrität der heruntergeladenen Programmpakete überprüfen" msgid "Verifying index signature:" msgstr "Überprüfe die Index-Signatur:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2087,7 +2090,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "App-ID, um auf Aktualisierungen zu prüfen" @@ -2095,7 +2097,6 @@ msgstr "App-ID, um auf Aktualisierungen zu prüfen" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "App-ID mit optionalem Versionscode in der Form APPID[:VERCODE]" @@ -2164,7 +2165,7 @@ msgstr "Kann das Update nicht veröffentlichen. Ist der Deploy-Schlüssel gesetz msgid "cloning {url}" msgstr "Klone {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "Ausführungsbefehl, entweder 'init' oder 'update'" @@ -2329,16 +2330,16 @@ msgstr "Ungültiger conflict_resolution-Wert: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "Ungültige Optionszeichenfolge %(option)r: muss mit einem Zeichen %(prefix_chars)r beginnen" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir endet nicht auf \"fdroid\", meinten Sie stattdessen: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir muß eine absolute Pfadangabe sein!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir muß ein Verzeichnis sein, keine Datei!" @@ -2470,11 +2471,16 @@ msgstr "Download über ungesicherte HTTP-Verbindung verweigert (verwenden Sie HT msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "Download über ungesicherte HTTP-Verbindung verweigert (verwenden Sie HTTPS oder geben Sie --no-https-check an): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd-Sync {path} indizieren auf {url} und dann löschen" @@ -2562,15 +2568,19 @@ msgstr "Syntax: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "Syntax: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "Verwende Apache libcloud zur Synchronisation mit {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2595,7 +2605,6 @@ msgstr "Die AndroidManifest.xml der App „{apkfilename}” hat ein ungültiges #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "{appid} besitzt keinen Namen! Verwende den Paketnamen stattdessen." @@ -2611,7 +2620,6 @@ msgstr "{appid} von {path} ist kein gültiger Android-Paketname!" #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" msgid "{appid} from {path} is not a valid Android application ID!" msgstr "{appid} von {path} ist kein gültiger Android-Paketname!" @@ -2686,7 +2694,7 @@ msgstr "{path} hat die schlechte Dateisignatur \"{pattern}\", möglicher Janus-E msgid "{path} is zero size!" msgstr "{path} hat Dateigröße Null!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" @@ -2713,12 +2721,6 @@ msgid_plural "{} builds succeeded" msgstr[0] "Buildvorgang erfolgreich" msgstr[1] "Buildvorgänge erfolgreich" -#~ msgid "Cannot find a packageName for {path}!" -#~ msgstr "packageName für {path} konnte nicht gefunden werden!" - -#~ msgid "Cannot find an appid for {path}!" -#~ msgstr "AppID für {path} konnte nicht gefunden werden!" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "GPG-Signaturen für Programmpakete in der Paketquelle hinzufügen" @@ -2726,6 +2728,12 @@ msgstr[1] "Buildvorgänge erfolgreich" #~ msgid "Add gpg signatures for packages in repo" #~ msgstr "GPG-Signaturen für Programmpakete in der Paketquelle hinzufügen" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "packageName für {path} konnte nicht gefunden werden!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "AppID für {path} konnte nicht gefunden werden!" + #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "Sauber - ohne Verwendung der Zwischenspeicher - aktualisieren, alle APKs wiederaufbereiten" diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index 44750384..274c4c7f 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-02 19:15+0000\n" "Last-Translator: Jo \n" "Language-Team: Spanish \n" @@ -81,7 +81,7 @@ msgstr "\"{path}\" contiene {name} ({version}) caducado" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" contiene {name} ({version}) reciente" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe pero ¡s3cmd no está instalado!" @@ -395,7 +395,6 @@ msgstr "¡No se puede leer \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "No se puede resolver el identificador de aplicación {appid}" @@ -525,12 +524,12 @@ msgstr "Cree una clave de firmado de repositorios en un llavero de claves" msgid "Create skeleton metadata files that are missing" msgstr "Crear esqueleto de metadatos de archivos que faltan" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Se ha creado el contenedor nuevo \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Creando \"{path}\" para configurar s3cmd." @@ -539,7 +538,7 @@ msgstr "Creando \"{path}\" para configurar s3cmd." msgid "Creating log directory" msgstr "Creando el directorio de registro (\"log\")" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Creando nuevo cubo S3: {url} 1" @@ -574,12 +573,12 @@ msgstr "DEBUG_KEYSTORE no está establecida o su valor es incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Borrar del repositorio archivos APK y/o OBB sin metadatos" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -641,7 +640,7 @@ msgstr "No haga nada con registros relacionados" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "No actualizar el repositorio, útil al probar una compilación sin conexión a Internet" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "No use rsync checksums" @@ -677,6 +676,10 @@ msgstr "Enlace duplicado en '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Ejecutar Fdroid dscanner de una aplicación APK, previamente construída," +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -708,7 +711,7 @@ msgstr "" "Introduzca la ruta a Android SDK (%s) aquí:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -746,7 +749,7 @@ msgstr "Fallo al cambiar de tamaño {path}: {error}" msgid "Failed to align application" msgstr "Fallo al alinear aplicación" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -873,7 +876,7 @@ msgstr "Ningún certificado de firma encontrado para el repositorio." msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "Procesando {apkfilename}" @@ -921,11 +924,11 @@ msgstr "La actualización del submodulo de Git falló" msgid "HTTPS must be used with Subversion URLs!" msgstr "¡Se debe usar HTTPS con URLs de Subversion!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1129,7 +1132,6 @@ msgstr "Depósito de claves para la clave de firma de repositorio:\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "La última confirmación utilizada '{commit}' parece una etiqueta, pero Update Check Mode es '{ucm}'" @@ -1158,7 +1160,7 @@ msgstr "Hacer que la construcción se detenga en las excepciones" msgid "Malformed repository mirrors." msgstr "Réplicas de repositorio mal formadas." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Línea serverwebroot mal formada:" @@ -1221,7 +1223,7 @@ msgstr "No hay necesidad de especificar que la aplicación es software libre" msgid "No need to specify that the app is for Android" msgstr "No hay necesidad de especificar que la aplicación es para Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "No hay opción establecida! Edita tu config.py para establecer al menos una de estas opciones:" @@ -1289,6 +1291,10 @@ msgstr "El nombre del archivo OBB debe comenzar con \"main.\" o \"patch.\":" msgid "OBB's packagename does not match a supported APK:" msgstr "El nombre de paquete de OBB no coincide con un APK soportado:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1436,12 +1442,12 @@ msgstr "Se debe evitar la puntuación" msgid "Push the log to this git remote repository" msgstr "Pulse el registro a este repositorio remoto Git" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Publicar el registro de transparencia binario en {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Empujando a {url}" @@ -1535,7 +1541,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "Ejecutar rewritemeta para arreglar el formato" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1642,11 +1648,11 @@ msgstr "Saltando {appid}: desactivado" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Especifique una carpeta local para sincronizar el" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Especifique un fichero de identidad que ofrezca SSH para rsync" @@ -1709,7 +1715,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Los únicos comandos soportados son 'init' y 'update'" @@ -1721,7 +1727,7 @@ msgstr "La huella digital del repositorio no coincide." msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1739,14 +1745,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "Este repo ya tiene metadatos locales: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1890,11 +1892,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Actualizar la información del repositorio para nuevos paquetes" @@ -1926,16 +1923,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1970,7 +1976,7 @@ msgstr "Use la fecha del APK en vez de la fecha actual para los nuevos APK añad msgid "Use date from apk instead of current time for newly added apks" msgstr "Use la fecha del «apk» en vez de la fecha actual para los nuevos «apk» añadidos" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1997,7 +2003,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -2018,7 +2024,7 @@ msgstr "Verificar la integridad de los paquetes descargados" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2079,7 +2085,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "applicationId para buscar actualizaciones" @@ -2087,7 +2092,6 @@ msgstr "applicationId para buscar actualizaciones" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "applicationId con código de versión opcional en la forma APPID [: VERCODE]" @@ -2155,7 +2159,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "Comando para ejecutar, ya sea 'init' o 'update'" @@ -2320,16 +2324,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2461,11 +2465,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2553,15 +2562,19 @@ msgstr "uso: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "Uso: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "usando Apache libcloud para sincronizar con {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2675,7 +2688,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" @@ -2702,12 +2715,6 @@ msgid_plural "{} builds succeeded" msgstr[0] "" msgstr[1] "" -#~ msgid "Cannot find a packageName for {path}!" -#~ msgstr "¡No se puede encontrar un packageName para {path}!" - -#~ msgid "Cannot find an appid for {path}!" -#~ msgstr "¡No se puede encontrar un appid para {path}!" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Añadir las firmas gpg para los paquetes en el repositorio" @@ -2715,6 +2722,12 @@ msgstr[1] "" #~ msgid "Add gpg signatures for packages in repo" #~ msgstr "Añadir las firmas gpg para los paquetes en el repositorio" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "¡No se puede encontrar un packageName para {path}!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "¡No se puede encontrar un appid para {path}!" + #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "Actualización limpia, no usa caché, reprocesa todas las aplicaciones APK" diff --git a/locale/es_AR/LC_MESSAGES/fdroidserver.po b/locale/es_AR/LC_MESSAGES/fdroidserver.po index 9dbbb5da..5dcd04d1 100644 --- a/locale/es_AR/LC_MESSAGES/fdroidserver.po +++ b/locale/es_AR/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-01 10:31+0000\n" "Last-Translator: riveravaldez \n" "Language-Team: Spanish (Argentina) \n" @@ -67,7 +67,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -514,12 +514,12 @@ msgstr "Crear una llave de firmado en un almacén de llaves para el repositorio" msgid "Create skeleton metadata files that are missing" msgstr "Crear plantilla de metadatos de los archivos faltantes" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -528,7 +528,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -563,12 +563,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Borrar archivos APK y/o OBBs sin metadatos del repositorio" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -631,7 +631,7 @@ msgstr "No hacer nada que refiera a los registros" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "No refrescar el repositorio, útil cuando se esta probando la construcción y no se tiene conexión a Internet" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "No usar sumas de validación de rsync" @@ -667,6 +667,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "Escanear dinámicamente APKs después de compilar" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -694,7 +698,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -733,7 +737,7 @@ msgstr "" msgid "Failed to align application" msgstr "Construir todas las aplicaciones disponibles" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -860,7 +864,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -908,11 +912,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1144,7 +1148,7 @@ msgstr "Parar esta construccion cuando haya excepciones" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1206,7 +1210,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1274,6 +1278,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1422,12 +1430,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "Subir el registro al repositorio remoto de git" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Actualizar el registro de transparencia binario de {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1523,7 +1531,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1631,11 +1639,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Especificar un directorio local donde sincronizar el repositorio" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, fuzzy msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Especifique una archivo de identificación para la resincronización vía SSH" @@ -1699,7 +1707,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy msgid "The only commands currently supported are 'init' and 'update'" msgstr "comando a ejecutar, ya sea 'iniciar' o 'actualizar'" @@ -1712,7 +1720,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1730,14 +1738,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1881,11 +1885,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Actualizar información del repositorio para paquetes nuevos" @@ -1917,16 +1916,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1962,7 +1970,7 @@ msgstr "Utilizar la fecha del apk en vez de la actual para los apks nuevos que s msgid "Use date from apk instead of current time for newly added apks" msgstr "Utilizar la fecha del apk en vez de la actual para los apks nuevos que se agreguen" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1989,7 +1997,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -2010,7 +2018,7 @@ msgstr "Verificar la integridad de los paquetes descargados" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2149,7 +2157,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "comando a ejecutar, ya sea 'iniciar' o 'actualizar'" @@ -2316,17 +2324,17 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "directorio_copia_local no termina en \"fdroid\", quizá quiso escribir: \"{ruta}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy msgid "local_copy_dir must be an absolute path!" msgstr "directorio_copia_local ¡tiene que ser una ruta absoluta!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "directorio_copia_local tiene que ser un directorio, ¡no un archivo!" @@ -2459,11 +2467,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2551,15 +2564,19 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "uso: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "usando libcloud de Apache para sincronizar con {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2673,7 +2690,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/es_MX/LC_MESSAGES/fdroidserver.po b/locale/es_MX/LC_MESSAGES/fdroidserver.po index bf0cc66c..fd036b37 100644 --- a/locale/es_MX/LC_MESSAGES/fdroidserver.po +++ b/locale/es_MX/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-04-29 12:49+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Spanish (Mexico) \n" @@ -66,7 +66,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -508,12 +508,12 @@ msgstr "Crear una clave de firma de repositorio en un almacén de claves" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Se creó un nuevo contenedor \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Creando \"{path}\" para configurar s3cmd." @@ -522,7 +522,7 @@ msgstr "Creando \"{path}\" para configurar s3cmd." msgid "Creating log directory" msgstr "Creando directorio de registro" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Crear un nuevo depósito de S3: {url}" @@ -557,12 +557,12 @@ msgstr "DEBUG_KEYSTORE no está establecido o el valor está incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -624,7 +624,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -660,6 +660,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -687,7 +691,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -725,7 +729,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -851,7 +855,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -899,11 +903,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1134,7 +1138,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1196,7 +1200,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1264,6 +1268,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1410,12 +1418,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1509,7 +1517,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1616,11 +1624,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1683,7 +1691,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1695,7 +1703,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1713,14 +1721,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1864,11 +1868,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1900,16 +1899,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1944,7 +1952,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1971,7 +1979,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1992,7 +2000,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2125,7 +2133,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2290,16 +2298,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2431,11 +2439,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2523,15 +2536,19 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2645,7 +2662,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/fa/LC_MESSAGES/fdroidserver.po b/locale/fa/LC_MESSAGES/fdroidserver.po index 2927aaa3..2aeb2d91 100644 --- a/locale/fa/LC_MESSAGES/fdroidserver.po +++ b/locale/fa/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: Mostafa Ahangarha \n" "Language-Team: Persian \n" @@ -66,7 +66,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -505,12 +505,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "پرونده‌های فراداده اسکلت را که موجود نیستند می‌سازد" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -519,7 +519,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -554,12 +554,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "پرونده‌های APK و یا OBB فاقد فراداده را از مخزن پاک می‌کند" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -621,7 +621,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -657,6 +657,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -684,7 +688,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -722,7 +726,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -848,7 +852,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -896,11 +900,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1131,7 +1135,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1193,7 +1197,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1261,6 +1265,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1407,12 +1415,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1506,7 +1514,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1613,11 +1621,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1680,7 +1688,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1692,7 +1700,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1710,14 +1718,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1861,11 +1865,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1897,16 +1896,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1941,7 +1949,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1968,7 +1976,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1989,7 +1997,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2122,7 +2130,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2287,16 +2295,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2428,11 +2436,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2520,15 +2533,19 @@ msgstr "مصرف: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "استفاده: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2642,7 +2659,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/fdroidserver.pot b/locale/fdroidserver.pot index 31ab5fc6..ee8e533c 100644 --- a/locale/fdroidserver.pot +++ b/locale/fdroidserver.pot @@ -5,9 +5,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: fdroidserver 1.1-681-gc19e8952\n" +"Project-Id-Version: fdroidserver 2.0a0-62-gc63c4b3d\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -657,6 +657,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -1261,6 +1265,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1714,10 +1722,6 @@ msgstr "" msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1861,11 +1865,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1897,6 +1896,15 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" @@ -2428,6 +2436,11 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" @@ -2529,6 +2542,10 @@ msgstr "" msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index 4d0b179c..9a64bb35 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-08 15:24+0000\n" "Last-Translator: Renaud Perrai \n" "Language-Team: French \n" @@ -92,7 +92,7 @@ msgstr "\"{path}\" contient {name} obsolète ({version})" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" contient le récent {name} ({version})" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe mais s3cmd n'est pas installé !" @@ -405,7 +405,6 @@ msgstr "Impossible de lire \"{path}\" !" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "Impossible de résoudre l'identifiant de l'application {appid}" @@ -532,12 +531,12 @@ msgstr "Créer une clé de signature de dépôt dans un gestionnaire de clés" msgid "Create skeleton metadata files that are missing" msgstr "Créer les métadonnées de base manquantes" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Nouveau container « {name} » créé" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Création de « {path} » pour configurer s3cmd." @@ -546,7 +545,7 @@ msgstr "Création de « {path} » pour configurer s3cmd." msgid "Creating log directory" msgstr "Création du répertoire des logs" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Création d'un nouveau bucket S3 : {url}" @@ -581,12 +580,12 @@ msgstr "DEBUG_KEYSTORE n'est pas définie ou sa valeur est incomplète" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Supprimer les APK et/ou OBB sans métadonnées dans le dépôt" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "Suppression de l'archive en cours, le dépôt occupe trop de place ({size} max {limit})" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "Suppression de l'historique de git-mirror, car le dépôt occupe trop de place ({size} max {limit})" @@ -648,7 +647,7 @@ msgstr "Ne pas toucher aux journaux d'applications (logs)" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Ne pas rafraîchir le dépôt, utile pour tester un build sans connexion internet" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Ne pas utiliser les sommes de contrôle rsync" @@ -684,6 +683,10 @@ msgstr "Lien dupliqué dans « {field} » : {url}" msgid "Dynamically scan APKs post build" msgstr "Analyser dynamiquement les APKs après compilation" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -715,7 +718,7 @@ msgstr "" "Entrez le chemin du SDK Android (%s1) :\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -753,7 +756,7 @@ msgstr "Échec au redimensionement de {path} : {error}" msgid "Failed to align application" msgstr "Impossible d'aligner les applications" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "La création du S3 Bucket a échoué : {url}" @@ -879,7 +882,7 @@ msgstr "Aucun certificat signée trouvée dans le dépot." msgid "Found non-file at %s" msgstr "Aucun fichier trouvée a %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "{apkfilename} trouvé à {url}" @@ -927,11 +930,11 @@ msgstr "Échec de la mise à jour du sous-module Git" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS doit être utilisé avec les URL de Subversion !" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "Si un miroir git prend trop de place, permet à l'archive d'être supprimé" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "Si ce téléversement échoue, tente de le téléverser manuellement vers {url}" @@ -1135,7 +1138,6 @@ msgstr "Stockage des clés signée :\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Le dernier archivage utiliser '{commit}' ressemble a une balise, mais le Mode De Vérification Des Mise A Jour est '{ucm}'" @@ -1163,7 +1165,7 @@ msgstr "Faire la construction s'arrèter si exceptions" msgid "Malformed repository mirrors." msgstr "Mirroirs de dépot malformée." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "serverwebroot malformer en ligne :" @@ -1226,7 +1228,7 @@ msgstr "Pas besoin de spécifier que l'application est un logiciel libre" msgid "No need to specify that the app is for Android" msgstr "Pas besoin de spécifier que l'application est pour Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Aucune option configurer ! Éditer votre config.py pour le mettre au moins a l'un d'eux :" @@ -1294,6 +1296,10 @@ msgstr "Le nom de fichier OBB doit commencer par «principal». ou \"patch\" : msgid "OBB's packagename does not match a supported APK:" msgstr "Le nom de paquet d'OBB ne correspond pas à un fichier APK pris en charge :" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1441,12 +1447,12 @@ msgstr "La ponctuation doit être évitée" msgid "Push the log to this git remote repository" msgstr "Envoyer les logs dans ce dépôt git distant" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Envoyer les logs de transparence de la compilation vers {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Envoyer vers {url}" @@ -1540,7 +1546,7 @@ msgstr "Exécuter sur le dépôt git qui a des modifications non validées" msgid "Run rewritemeta to fix formatting" msgstr "Exécuter rewritemeta pour corriger le formatage" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Exécution de la première passe avec la vérification MD5 désactivée" @@ -1648,11 +1654,11 @@ msgstr "Omission de {appid} : désactivé" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1715,7 +1721,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Les seules commandes disponibles actuellement sont 'init' et 'update'" @@ -1727,7 +1733,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1745,14 +1751,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1897,11 +1899,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Mettre à jour les données des dépôts pour les nouveaux paquets" @@ -1933,16 +1930,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "Lecture de {apkfilename} à partir du cache" @@ -1977,7 +1983,7 @@ msgstr "Utiliser la date de l'APK plutôt que la date courante pour les APKs nou msgid "Use date from apk instead of current time for newly added apks" msgstr "Utiliser la date de l'APK plutôt que la date courante pour les APKs nouvellement ajoutés" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Utiliser \"{path}\" pour configurer s3cmd." @@ -2004,7 +2010,7 @@ msgstr "Utilise le trousseau existant \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Utilise le trousseau existant \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -2025,7 +2031,7 @@ msgstr "Vérifier l'intégrité des paquets téléchargés" msgid "Verifying index signature:" msgstr "Vérification de la signature d'index :" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2086,7 +2092,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "applicationId pour vérifier les mises à jour" @@ -2094,7 +2099,6 @@ msgstr "applicationId pour vérifier les mises à jour" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "applicationId avec le versionCode optionnel sous la forme APPID[:VERCODE]" @@ -2163,7 +2167,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "Commande à exécuter : 'init' ou 'update'" @@ -2328,16 +2332,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir ne semble pas se terminer avec \"fdroid\", peut être voulez-vous dire : \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir doir être un chemin absolut !" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir doit être absolument un dossier, pas un fichier !" @@ -2469,11 +2473,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2561,15 +2570,19 @@ msgstr "usage : " msgid "usage: fdroid [-h|--help|--version] []" msgstr "utilisation : fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "utilisation de Apache libcloud pour syncronizer avec {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2683,7 +2696,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "{path} supérieur à 200MB, envoi manuel : {url}" @@ -2710,12 +2723,6 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} compilation réussie" msgstr[1] "{} compilations réussies" -#~ msgid "Cannot find a packageName for {path}!" -#~ msgstr "Impossible de trouver un packageName pour {path} !" - -#~ msgid "Cannot find an appid for {path}!" -#~ msgstr "Impossible de trouver un appid pour {path} !" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Ajouter des signatures GPG pour les paquets dans le dépôt" @@ -2726,6 +2733,12 @@ msgstr[1] "{} compilations réussies" #~ msgid "Android Build Tools path '{path}' does not exist!" #~ msgstr "Le chemin '{path}' pour Android Build Tools n'existe pas !" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Impossible de trouver un packageName pour {path} !" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Impossible de trouver un appid pour {path} !" + #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "Mise à jour propre - n'utilise pas les caches, ré-exécute tous les APKs" diff --git a/locale/hu/LC_MESSAGES/fdroidserver.po b/locale/hu/LC_MESSAGES/fdroidserver.po index 626b59a1..d24bae2a 100644 --- a/locale/hu/LC_MESSAGES/fdroidserver.po +++ b/locale/hu/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-04-07 13:43+0000\n" "Last-Translator: Balázs Meskó \n" "Language-Team: Hungarian \n" @@ -72,7 +72,7 @@ msgstr "A(z) „{path}” elavult {name} csomagot tartalmaz ({version})" msgid "\"{path}\" contains recent {name} ({version})" msgstr "A(z) „{path}” friss {name} csomagot tartalmaz ({version})" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "A(z) „{path}” létezik, de az s3cmd nincs telepítve." @@ -511,12 +511,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "Hiányzó metaadatfájl-vázak létrehozása" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -525,7 +525,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -560,12 +560,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Minden metaadat nélküli APK és OBB fájl törlése a tárolóból" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -627,7 +627,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -663,6 +663,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "APK-k dinamikus átvizsgálása összeállítás után" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -690,7 +694,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -728,7 +732,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -854,7 +858,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -902,11 +906,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1137,7 +1141,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1199,7 +1203,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1267,6 +1271,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1413,12 +1421,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1512,7 +1520,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1619,11 +1627,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1686,7 +1694,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1698,7 +1706,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1716,14 +1724,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1867,11 +1871,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Tárolóinformációk frissítése az új csomagoknál" @@ -1903,16 +1902,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1947,7 +1955,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1974,7 +1982,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1995,7 +2003,7 @@ msgstr "Ellenőrizze a letöltött csomagok érintetlenségét" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2128,7 +2136,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2293,16 +2301,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2434,11 +2442,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2526,15 +2539,19 @@ msgstr "használat: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "használat: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2648,7 +2665,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/id/LC_MESSAGES/fdroidserver.po b/locale/id/LC_MESSAGES/fdroidserver.po index 5df1253e..8cd4c205 100644 --- a/locale/id/LC_MESSAGES/fdroidserver.po +++ b/locale/id/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: signz signotorez \n" "Language-Team: Indonesian \n" @@ -65,7 +65,7 @@ msgstr "\"{path}\" berisi {name}({version}) kadaluarsa" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" berisi {name}({version}) sekarang" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -502,12 +502,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "Membuat kerangka berkas metadata yang hilang" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -516,7 +516,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -551,12 +551,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Hapus APK dan/atau OBB tanpa metada dari repo" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -618,7 +618,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -654,6 +654,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -681,7 +685,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -719,7 +723,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -845,7 +849,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -893,11 +897,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1128,7 +1132,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1190,7 +1194,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1258,6 +1262,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1404,12 +1412,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1503,7 +1511,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1609,11 +1617,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1676,7 +1684,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1688,7 +1696,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1706,14 +1714,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1857,11 +1861,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Perbarui informasi repo untuk paket yang baru" @@ -1893,16 +1892,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1937,7 +1945,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1964,7 +1972,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1985,7 +1993,7 @@ msgstr "Verifikasi integritas paket yang didownload" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2118,7 +2126,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2281,16 +2289,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2422,11 +2430,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2514,15 +2527,19 @@ msgstr "penggunaan: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "penggunaan: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2635,7 +2652,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index 9851dc7c..cc3d4a79 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-15 17:12+0000\n" "Last-Translator: IvanDan \n" "Language-Team: Italian \n" @@ -81,7 +81,7 @@ msgstr "\"{path}\" contiene {name} obsoleto ({version})" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" contiene {name} recente ({version})" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" esiste ma s3cmd non è installato!" @@ -523,12 +523,12 @@ msgstr "Crea una chiave di firma del repository in un keystore" msgid "Create skeleton metadata files that are missing" msgstr "Crea i file scheletro di metadata che mancano" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Nuovo container \"{name}\" creato" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Creazione \"{path}\" per configurazione s3cmd." @@ -537,7 +537,7 @@ msgstr "Creazione \"{path}\" per configurazione s3cmd." msgid "Creating log directory" msgstr "Creazione della directory dei log" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Creazione di un nuovo bucket S3: {url}" @@ -572,12 +572,12 @@ msgstr "DEBUG_KEYSTORE non impostato o il valore è incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Cancella gli APK e/o OBB senza metadata dal repository" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -639,7 +639,7 @@ msgstr "Non fare niente sui log" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Non aggiornare il repository, utile per testare una build offline" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Non usare checksum rsync" @@ -675,6 +675,10 @@ msgstr "Link duplicato in '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Scansiona gli APK dinamicamente dopo la costruzione" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -706,7 +710,7 @@ msgstr "" "Inserisci qui il percorso dell'Android SDK (%s):\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -744,7 +748,7 @@ msgstr "Impossibile ridimensionare {path}: {error}" msgid "Failed to align application" msgstr "Impossibile allineare l’applicazione" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "Impossibile creare il bucket S3: {url}" @@ -870,7 +874,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -918,11 +922,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1153,7 +1157,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1215,7 +1219,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "Non c'è bisogno di specificare che l'applicazione è per Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1283,6 +1287,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1429,12 +1437,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1528,7 +1536,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1635,11 +1643,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1702,7 +1710,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1714,7 +1722,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1732,14 +1740,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1883,11 +1887,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Aggiorna le informazioni del repository coi nuovi pacchetti" @@ -1919,16 +1918,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1963,7 +1971,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1990,7 +1998,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Utilizzando s3cmd per sincronizzare con: {url}" @@ -2011,7 +2019,7 @@ msgstr "Verifica l'integrità dei pacchetti scaricati" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2144,7 +2152,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2309,16 +2317,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir not finisce con \"fdroid\", forse intendevi: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir deve essere un percorso assoluto!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir deve essere una cartella, non un file!" @@ -2450,11 +2458,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2542,15 +2555,19 @@ msgstr "utilizzo: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "utilizzo: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "utilizzando Apache libcloud per sincronizzare con {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2664,7 +2681,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/ja/LC_MESSAGES/fdroidserver.po b/locale/ja/LC_MESSAGES/fdroidserver.po index 69411cf2..d2465585 100644 --- a/locale/ja/LC_MESSAGES/fdroidserver.po +++ b/locale/ja/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-224-g4b0ade7\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-09-02 16:10+0000\n" "Last-Translator: Hinaloe \n" "Language-Team: Japanese \n" @@ -65,7 +65,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -502,12 +502,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -516,7 +516,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -551,12 +551,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -618,7 +618,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -654,6 +654,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -681,7 +685,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -719,7 +723,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -845,7 +849,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -893,11 +897,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1128,7 +1132,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1190,7 +1194,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1258,6 +1262,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1404,12 +1412,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1503,7 +1511,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1609,11 +1617,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1676,7 +1684,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1688,7 +1696,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1706,14 +1714,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1857,11 +1861,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1893,16 +1892,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1937,7 +1945,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1964,7 +1972,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1985,7 +1993,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2118,7 +2126,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2281,16 +2289,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir は「froid」で終わっていません、もしかして: 「{path}」" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir は絶対パスの必要があります!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir はファイルではなくディレクトリにする必要があります!" @@ -2422,11 +2430,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2514,15 +2527,19 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2635,7 +2652,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/kab/LC_MESSAGES/fdroidserver.po b/locale/kab/LC_MESSAGES/fdroidserver.po index 479df7d0..fd9fd2e3 100644 --- a/locale/kab/LC_MESSAGES/fdroidserver.po +++ b/locale/kab/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: Kahina Messaoudi \n" "Language-Team: Kabyle \n" @@ -66,7 +66,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -505,12 +505,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Anagbar amaynut yettwarnan \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -519,7 +519,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -554,12 +554,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -621,7 +621,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -657,6 +657,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -684,7 +688,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -722,7 +726,7 @@ msgstr "" msgid "Failed to align application" msgstr "Areyyec n usnas ur yeddi ara" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -848,7 +852,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -896,11 +900,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -992,7 +996,6 @@ msgstr "" #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "no \"icon\" in {appid}" msgid "Invalid application ID {appid}" msgstr "ulac \"tignit\" deg {appid}" @@ -1132,7 +1135,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1194,7 +1197,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1262,6 +1265,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1408,12 +1415,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Adegger ɣer {url}" @@ -1507,7 +1514,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1614,11 +1621,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1681,7 +1688,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1693,7 +1700,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1711,14 +1718,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1862,11 +1865,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1898,16 +1896,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1942,7 +1949,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1969,7 +1976,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "Aseqdec n tqeffalt n uḥraz \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1990,7 +1997,7 @@ msgstr "Senqed timmad n yikemmusen yettwasadren" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2123,7 +2130,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2288,16 +2295,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2429,11 +2436,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2521,15 +2533,19 @@ msgstr "aqseqdac: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2643,7 +2659,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/ko/LC_MESSAGES/fdroidserver.po b/locale/ko/LC_MESSAGES/fdroidserver.po index d6cc6a17..788a0117 100644 --- a/locale/ko/LC_MESSAGES/fdroidserver.po +++ b/locale/ko/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-135-g16dd6d28\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2019-01-19 22:57+0000\n" "Last-Translator: Seokyong Jung \n" "Language-Team: Korean \n" @@ -73,7 +73,7 @@ msgstr "\"{path}\"는 오래된 {name} ({version})를 포함합니다" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\"는 최근 {name} ({version})를 포함합니다" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\"는 존재하지만 s3cmd는 설치되어 있지 않습니다!" @@ -385,7 +385,6 @@ msgstr "\"{path}\"를 읽을 수 없습니다!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "앱 id {appid}를 해결할 수 없습니다" @@ -512,12 +511,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "누락된 skeleton 메타데이터 파일을 만듭니다" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -526,7 +525,7 @@ msgstr "" msgid "Creating log directory" msgstr "기록 디렉터리 만들기" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -561,12 +560,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "저장소에서 메타데이터 없이 APK 및/또는 OBB를 삭제합니다" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -628,7 +627,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -664,6 +663,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "동적으로 APK 게시 빌드를 스캔합니다" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -691,7 +694,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -729,7 +732,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -855,7 +858,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "{path} 안으로 {apkfilename}을 복사 중" @@ -903,11 +906,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -999,7 +1002,6 @@ msgstr "잘못된 Vercode연산: {field}" #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" msgid "Invalid application ID {appid}" msgstr "잘못된 Vercode연산: {field}" @@ -1139,7 +1141,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1201,7 +1203,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1269,6 +1271,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1415,12 +1421,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1514,7 +1520,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1620,11 +1626,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1687,7 +1693,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1699,7 +1705,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1717,14 +1723,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1869,11 +1871,6 @@ msgstr "%s에서 사용되지 않은 파일" msgid "Unused scanignore path: %s" msgstr "%s에서 사용되지 않은 파일" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "새 패키지를 위한 저장소 정보를 업데이트합니다" @@ -1905,16 +1902,25 @@ msgstr "UpdateCheckData는 HTTPS URL을 사용해야 합니다: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData는 올바른 URL이 아닙니다: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "{path} 안으로 {apkfilename}을 복사 중" @@ -1949,7 +1955,7 @@ msgstr "새로 추가된 APK를 위해 현재 시간 대신에 APK에서의 날 msgid "Use date from apk instead of current time for newly added apks" msgstr "새로 추가된 apk를 위해 현재 시간 대신에 apk에서의 날짜를 사용합니다" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "s3cmd를 구성하기 위해 \"{path}\" 사용." @@ -1976,7 +1982,7 @@ msgstr "\"{path}\"에서 androguard를 사용 중" msgid "Using existing keystore \"{path}\"" msgstr "기존 키스토어 \"{path}\"를 사용 중" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "다음과 동기화하는 데 s3cmd 사용: {url}" @@ -1997,7 +2003,7 @@ msgstr "다운로드된 패키지의 무결성 확인" msgid "Verifying index signature:" msgstr "색인 서명을 검증 중:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2058,7 +2064,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "업데이트를 확인할 applicationId" @@ -2066,7 +2071,6 @@ msgstr "업데이트를 확인할 applicationId" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "양식 APPID[:VERCODE]에서 선택적인 versionCode로 된 applicationId" @@ -2134,7 +2138,7 @@ msgstr "" msgid "cloning {url}" msgstr "{url}를 복제 중" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "실행할 명령, 'init' 또는 'update' 중 하나" @@ -2297,16 +2301,16 @@ msgstr "올바르지 않은 conflict_resolution 값: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "올바르지 않은 옵션 문자열 %(option)r: 문자 %(prefix_chars)r로 시작해야 합니다" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir는 파일이 아니라, 디렉터리여야 합니다!" @@ -2438,11 +2442,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd 동기화는 {url}로 {path}를 색인하고 삭제합나다" @@ -2530,15 +2539,19 @@ msgstr "사용법: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "사용법: fdroid [-h|--help|--version] <명령> [<인수>]" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2562,7 +2575,6 @@ msgstr "{apkfilename}의 AndroidManifest.xml에 잘못된 날짜가 있습니다 #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "{appid}는 이름을 가지지 않습니다! 대신 패키지 이름 사용." @@ -2652,7 +2664,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "{path}는 영 크기입니다!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" @@ -2677,11 +2689,11 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} 빌드 성공됨" +#~ msgid "Add gpg signatures for packages in repo" +#~ msgstr "저장소에서 패키지에 gpg 서명을 추가합니다" + #~ msgid "Cannot find a packageName for {path}!" #~ msgstr "{path}를 위한 packageName을 찾을 수 없습니다!" #~ msgid "Cannot find an appid for {path}!" #~ msgstr "{path}를 위한 appid를 찾을 수 없습니다!" - -#~ msgid "Add gpg signatures for packages in repo" -#~ msgstr "저장소에서 패키지에 gpg 서명을 추가합니다" diff --git a/locale/ml/LC_MESSAGES/fdroidserver.po b/locale/ml/LC_MESSAGES/fdroidserver.po index 33e8d4f3..e711a5ea 100644 --- a/locale/ml/LC_MESSAGES/fdroidserver.po +++ b/locale/ml/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -65,7 +65,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -504,12 +504,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -518,7 +518,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -553,12 +553,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -620,7 +620,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -656,6 +656,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -683,7 +687,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -721,7 +725,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -847,7 +851,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -895,11 +899,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1130,7 +1134,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1192,7 +1196,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1260,6 +1264,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1406,12 +1414,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1505,7 +1513,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1612,11 +1620,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1679,7 +1687,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1691,7 +1699,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1709,14 +1717,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1860,11 +1864,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1896,16 +1895,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1940,7 +1948,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1967,7 +1975,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1988,7 +1996,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2121,7 +2129,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2286,16 +2294,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2427,11 +2435,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2519,15 +2532,19 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2641,7 +2658,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index 6fe4f914..d196989d 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-74-ga380b9f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-14 09:28+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" @@ -74,7 +74,7 @@ msgstr "\"{path}\" inneholder utdatert {name} ({version})" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" inneholder nylig {name} ({version})" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" finnes, men s3cmd er ikke installert!" @@ -522,12 +522,12 @@ msgstr "Opprett en nøkkelsigneringsnøkkel i et nøkkellager" msgid "Create skeleton metadata files that are missing" msgstr "Opprett skjelettmetadatafiler som mangler" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Opprettet ny beholder \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Oppretter \"{path}\" for oppsett av s3cmd." @@ -536,7 +536,7 @@ msgstr "Oppretter \"{path}\" for oppsett av s3cmd." msgid "Creating log directory" msgstr "Oppretter loggingsmappe" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Oppretter ny S3-spann: {url}" @@ -573,12 +573,12 @@ msgstr "DEBUG_KEYSTORE er ikke satt, eller så er verdien ufullstendig" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Slett APK-er og/eller OBB-er uten metadata fra pakkebrønnen" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "Sletter arkiv, pakkebrønnen er for stor ({size} maks. {limit})" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "Sletter historikk for git-mirror, pakkebrønnen er for stor ({size} maks. {limit})" @@ -644,7 +644,7 @@ msgstr "Ikke gjør noe relatert til logging" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Ikke gjenoppfrisk pakkebrønnen, nyttig under testing av et bygg uten å ha internettilkobling" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Ikke bruk rsync-sjekksummer" @@ -681,6 +681,10 @@ msgstr "Dobbeltlenke i \"{field}\": {url}" msgid "Dynamically scan APKs post build" msgstr "Dynamisk skanne APKs postbygg" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py #, fuzzy msgid "" @@ -714,7 +718,7 @@ msgstr "" "Skriv inn stien til Android SDK (%s) her:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, fuzzy, python-format msgid "Error while attempting to publish log: %s" @@ -754,7 +758,7 @@ msgstr "Klarte ikke å endre størrelse på {path}: {error}" msgid "Failed to align application" msgstr "Klarte ikke å justere program" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "Klarte ikke å opprette S3-spann: {url}" @@ -886,7 +890,7 @@ msgstr "Fant ikke noe signeringssertifikat for pakkebrønn." msgid "Found non-file at %s" msgstr "Fant ikke-fil i %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "Fant {apkfilename} i {url}" @@ -935,11 +939,11 @@ msgstr "Git-oppdatering av undermodul mislyktes" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS må brukes sammen med Subversjon-nettadresser." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1179,7 +1183,7 @@ msgstr "Stopp bygging ved unntak" msgid "Malformed repository mirrors." msgstr "Feilaktig innskrevne pakkebrønnsspeil." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Feilaktig innskrevet serverwebroot-linje:" @@ -1243,7 +1247,7 @@ msgstr "Inget behov for å spesifisere at programmet er fri programvare" msgid "No need to specify that the app is for Android" msgstr "Inget behov for å spesifisere at programmet er for Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Inget valg satt. Rediger din config.py og sett minst én av disse:" @@ -1311,6 +1315,10 @@ msgstr "OBB-filnavn må starte med \"main.\" eller \"patch.\":" msgid "OBB's packagename does not match a supported APK:" msgstr "OBB-pakkenavn samsvarer ikke med noen støttet APK:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, fuzzy, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1464,12 +1472,12 @@ msgstr "Tegnsetting bør unngås" msgid "Push the log to this git remote repository" msgstr "Dytt loggen til denne Git-pakkebrønnen annensteds hen" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Dytter binærgjennomsiktighetslogg til {url}." -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Dytter til {url}." @@ -1566,7 +1574,7 @@ msgstr "Kjør på Git-pakkebrønn som har uinnsendte endringer" msgid "Run rewritemeta to fix formatting" msgstr "Kjør rewritemetadata for å fikse formatering" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, fuzzy msgid "Running first pass with MD5 checking disabled" msgstr "Kjører første passering med MD5-sjekking avskrudd" @@ -1677,11 +1685,11 @@ msgstr "Hopper over {appid}: Avskrudd" msgid "Skipping {appid}: no builds specified" msgstr "Hopper over {appid}: Ingen bygg angitt" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Angi ei lokal mappe å synkronisere pakkebrønnen til" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, fuzzy msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Angi ei identitetsfil å tilby til SSH for rsync-ing" @@ -1746,7 +1754,7 @@ msgstr "Mappen å skrive speilet til" msgid "The file to be included in the repo (path or glob)" msgstr "Filen å inkludere i pakkebrønnen (sti eller glob)." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy msgid "The only commands currently supported are 'init' and 'update'" msgstr "De eneste kommandoene som støttes foreløpig er \"init\" og \"update\"." @@ -1760,7 +1768,7 @@ msgstr "Pakkebrønnens fingeravtrykk samsvarer ikke." msgid "The repository's index could not be verified." msgstr "Kunne ikke bekrefte pakkebrønnens indeks." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "Rotmappen for local_copy_dir \"{path}\" finnes ikke." @@ -1778,15 +1786,11 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "Denne pakkebrønnen har allerede lokal metadata: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, fuzzy msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "For å bruke AWS-spann, må \"awssecretkey\" og \"awsaccesskeyid\" også være satt i config.py." -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode er satt, men det ser ut til at checkupdates ikke har blitt kjørt enda." - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "Nettadressen må starte med https:// eller http://" @@ -1933,12 +1937,6 @@ msgstr "Ubrukt fil i %s" msgid "Unused scanignore path: %s" msgstr "Ubrukt fil i %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -#, fuzzy -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "\"Update Check Name\" er satt til den kjente App-ID-en - den kan fjernes." - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Oppdater repo informasjon for nye pakker" @@ -1970,17 +1968,27 @@ msgstr "UpdateCheckData må bruke HTTPS-nettadresse: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData er ikke en gyldig nettadresse: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode er satt, men det ser ut til at checkupdates ikke har blitt kjørt enda." + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "\"Update Check Name\" er satt til den kjente App-ID-en - den kan fjernes." + #: ../fdroidserver/lint.py #, fuzzy msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "\"Update Check Name\" er satt til den kjente App-ID-en - den kan fjernes." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "Behandler {apkfilename}" @@ -2016,7 +2024,7 @@ msgstr "Bruk dato fra APK istedenfor nåværende tid for nylig tillagte APK-er." msgid "Use date from apk instead of current time for newly added apks" msgstr "Bruk dato fra APK istedenfor nåværende tid for nylig tillagte APK-er" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Bruker \"{path}\" for oppsett av s3cmd." @@ -2046,7 +2054,7 @@ msgstr "Bruker Androguard fra \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Bruker eksisterende nøkkellager \"{path}\"." -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Bruk s3cmd til å synkronisere med: {url}" @@ -2067,7 +2075,7 @@ msgstr "Bekreft integriteten til nedlastede pakker" msgid "Verifying index signature:" msgstr "Bekrefter indekssignatur:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2130,7 +2138,6 @@ msgstr "fant ikke apksigner (som kreves for signering)." #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "App-ID å sjekke for oppdateringer" @@ -2138,7 +2145,6 @@ msgstr "App-ID å sjekke for oppdateringer" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "App-ID med valgfri versionCode, i formen APPID[:VERCODE]" @@ -2210,7 +2216,7 @@ msgstr "kan ikke offentliggjøre oppdatering, har du satt utrullingsnøkkelen?" msgid "cloning {url}" msgstr "kloner {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "kommando å kjøre, enten 'init' eller 'update'" @@ -2380,16 +2386,16 @@ msgstr "ugyldig conflict_resolution-verdi: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "Ugyldig valgstreng %(option)r: Må starte med et tegn %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir slutter ikke med \"fdroid\", kanskje du mente: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir må være en absolutt sti!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir må være ei mappe, ikke ei fil!" @@ -2522,11 +2528,16 @@ msgstr "nekt nedlasting via usikker HTTP-tilkobling (bruk HTTPS eller angi --no- msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "nekt nedlasting via usikker HTTP-tilkobling (bruk HTTPS eller angi --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, fuzzy, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd synkroniserer indekser {path} til {url} og sletter" @@ -2617,15 +2628,19 @@ msgstr "bruk: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "bruk: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, fuzzy, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "bruker Apache-libcloud for å synkronisere med {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2650,7 +2665,6 @@ msgstr "{apkfilename} sin AndroidManifest.xml har en feilaktig dato: " #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "{appid} mangler navn. Bruker pakkenavn istedenfor." @@ -2666,7 +2680,6 @@ msgstr "{appid} fra {path} er ikke et gyldig Android-pakkenavn!" #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" msgid "{appid} from {path} is not a valid Android application ID!" msgstr "{appid} fra {path} er ikke et gyldig Android-pakkenavn!" @@ -2741,7 +2754,7 @@ msgstr "{path} har feilaktig filsignatur \"{pattern}\", mulig Janus-utnyttelse." msgid "{path} is zero size!" msgstr "{path} er null størrelse." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "{path} er mer enn 200MB, last opp manuelt: {url}" @@ -2768,6 +2781,9 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} bygg fullført" msgstr[1] "{} bygg fullført" +#~ msgid "Add PGP signatures for packages in repo using GnuPG" +#~ msgstr "Legg til PGP-signaturer for pakker i pakkebrønnen ved bruk av GnuPG" + #, fuzzy #~ msgid "Cannot find a packageName for {path}!" #~ msgstr "Fant ikke packageName for {path}." @@ -2775,6 +2791,3 @@ msgstr[1] "{} bygg fullført" #, fuzzy #~ msgid "Cannot find an appid for {path}!" #~ msgstr "Finner ikke AppID for {path}." - -#~ msgid "Add PGP signatures for packages in repo using GnuPG" -#~ msgstr "Legg til PGP-signaturer for pakker i pakkebrønnen ved bruk av GnuPG" diff --git a/locale/nl/LC_MESSAGES/fdroidserver.po b/locale/nl/LC_MESSAGES/fdroidserver.po index fbc7b87e..541cd10c 100644 --- a/locale/nl/LC_MESSAGES/fdroidserver.po +++ b/locale/nl/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-01 20:58+0000\n" "Last-Translator: Bart Groeneveld \n" "Language-Team: Dutch \n" @@ -65,7 +65,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -505,12 +505,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -519,7 +519,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -554,12 +554,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -621,7 +621,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -657,6 +657,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -684,7 +688,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -722,7 +726,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -848,7 +852,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -896,11 +900,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1131,7 +1135,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1193,7 +1197,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1261,6 +1265,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1407,12 +1415,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1506,7 +1514,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1613,11 +1621,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1680,7 +1688,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1692,7 +1700,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1710,14 +1718,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1861,11 +1865,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1897,16 +1896,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1941,7 +1949,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1968,7 +1976,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1989,7 +1997,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2122,7 +2130,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2287,16 +2295,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2428,11 +2436,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2520,15 +2533,19 @@ msgstr "gebruik: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "gebruik: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2642,7 +2659,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index 7c62a94d..b8704f5c 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-14 09:28+0000\n" "Last-Translator: WaldiS \n" "Language-Team: Polish \n" @@ -71,7 +71,7 @@ msgstr "\"{path}\" zawiera nieaktualne {name} ({version})" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" zawiera najnowsze {name} ({version})" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" istnieje, ale s3cmd nie jest zainstalowany!" @@ -515,12 +515,12 @@ msgstr "Utwórz klucz podpisu repo w magazynie kluczy" msgid "Create skeleton metadata files that are missing" msgstr "Utwórz brakujące pliki metadanych szkieletu" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Utworzono nowy kontener \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Tworzenie \"{path}\" do konfiguracji s3cmd." @@ -529,7 +529,7 @@ msgstr "Tworzenie \"{path}\" do konfiguracji s3cmd." msgid "Creating log directory" msgstr "Tworzenie katalogu dzienników" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Tworzenie nowego zasobnika S3: {url}" @@ -564,12 +564,12 @@ msgstr "DEBUG_KEYSTORE nie jest ustawione lub wartość jest niepełna" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Usuń pliki APK i/lub OBB bez metadanych z repozytorium" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -631,7 +631,7 @@ msgstr "Nie wykonuj żadnych czynności związanych z logami" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Nie odświeżaj repozytorium, przydatne podczas testowania kompilacji bez połączenia z Internetem" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Nie używaj sum kontrolnych rsync" @@ -667,6 +667,10 @@ msgstr "Zduplikowany link w '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Dynamicznie skanuj kompilację postów APK" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -698,7 +702,7 @@ msgstr "" "Podaj ścieżkę do zestawu SDK systemu Android (%s) tutaj:\n" " > " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -736,7 +740,7 @@ msgstr "Nie udało się zmienić rozmiaru {path}: {error}" msgid "Failed to align application" msgstr "Nie udało się wyrównać aplikacji" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "Nie można utworzyć zasobnika S3: {url}" @@ -863,7 +867,7 @@ msgstr "Nie znaleziono certyfikatów do podpisywania dla repozytorium." msgid "Found non-file at %s" msgstr "Znaleziono plik nieprzechowy na %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "kopiowanie {apkfilename} na {path}" @@ -911,11 +915,11 @@ msgstr "Aktualizacja submodułu Git nie powiodła się" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS musi być używany z adresami URL Subversion!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1007,7 +1011,6 @@ msgstr "Nieprawidłowa VercodeOperation: {field}" #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" msgid "Invalid application ID {appid}" msgstr "Nieprawidłowa VercodeOperation: {field}" @@ -1120,7 +1123,6 @@ msgstr "Magazyn kluczy do podpisywania klucza:\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Ostatnio używany commit '{commit}' wygląda jak tag, ale tryb sprawdzania aktualizacji to '{ucm}'" @@ -1149,7 +1151,7 @@ msgstr "Wykonaj zatrzymanie kompilacji z wyjątkami" msgid "Malformed repository mirrors." msgstr "Nieprawidłowo repozytorium mirrors." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Nieprawidłowy wiersz serverwebroot:" @@ -1212,7 +1214,7 @@ msgstr "Nie musisz określać, że aplikacja jest wolnym oprogramowaniem" msgid "No need to specify that the app is for Android" msgstr "Nie musisz określać, że aplikacja jest przeznaczona dla Androida" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Brak opcji! Edytuj plik config.py, aby ustawić co najmniej jedno z poniższych:" @@ -1280,6 +1282,10 @@ msgstr "Nazwa pliku OBB musi zaczynać się od \"main\". lub \"patch.\":" msgid "OBB's packagename does not match a supported APK:" msgstr "Nazwa pakietu OBB nie jest zgodna z obsługiwanym pakietem APK:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1427,12 +1433,12 @@ msgstr "Należy unikać interpunkcji" msgid "Push the log to this git remote repository" msgstr "Przepchnij dziennik do tego zdalnego repozytorium git" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Przesyłanie dziennika zmian binarnych do {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Naciśnij na {url}" @@ -1526,7 +1532,7 @@ msgstr "Uruchom ponownie repozytorium git z niezatwierdzonymi zmianami" msgid "Run rewritemeta to fix formatting" msgstr "Uruchom rewritemeta, aby naprawić formatowanie" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Uruchomienie pierwszego przejścia z wyłączonym sprawdzaniem MD5" @@ -1634,11 +1640,11 @@ msgstr "Pomiń {appid}: wyłączone" msgid "Skipping {appid}: no builds specified" msgstr "Pomiń {appid}: nie określono żadnych kompilacji" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Określ folder lokalny do synchronizacji repo do" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Podaj plik tożsamości, który ma dostarczyć SSH dla rsyncing" @@ -1701,7 +1707,7 @@ msgstr "Katalog do zapisania kopii lustrzanej" msgid "The file to be included in the repo (path or glob)" msgstr "Plik do uwzględnienia w repozytorium (ścieżka lub glob)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Jedynymi obsługiwanymi obecnie poleceniami są 'init' i 'update'" @@ -1713,7 +1719,7 @@ msgstr "Odcisk palca repozytorium nie pasuje." msgid "The repository's index could not be verified." msgstr "Indeksu repozytorium nie można zweryfikować." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "Katalog główny katalogu local_copy_dir \"{path}\" nie istnieje!" @@ -1731,14 +1737,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "To repo ma już lokalne metadane: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Aby użyć awsbucket, awssecretkey i awsaccesskeyid muszą być również ustawione w config.py!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode jest ustawione, ale wygląda na to, że checkupdates nie zostało jeszcze uruchomione" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1883,13 +1885,6 @@ msgstr "Plik UNUSED, o %s" msgid "Unused scanignore path: %s" msgstr "Plik UNUSED, o %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Aktualizacja Check Name jest ustawiona na znany identyfikator aplikacji - można go usunąć" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Zaktualizuj informacje o repozytorium dla nowych pakietów" @@ -1921,18 +1916,27 @@ msgstr "UpdateCheckData musi używać adresu URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData nie jest prawidłowym adresem URL: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode jest ustawione, ale wygląda na to, że checkupdates nie zostało jeszcze uruchomione" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "Aktualizacja Check Name jest ustawiona na znany identyfikator aplikacji - można go usunąć" + #: ../fdroidserver/lint.py #, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "Aktualizacja Check Name jest ustawiona na znany identyfikator aplikacji - można go usunąć" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "Czytanie {apkfilename} z pamięci podręcznej" @@ -1967,7 +1971,7 @@ msgstr "Użyj daty z pliku APK zamiast aktualnego dla nowo dodanych pakietów AP msgid "Use date from apk instead of current time for newly added apks" msgstr "Użyj daty z apk zamiast bieżącego czasu dla nowo dodanych plików apk" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Użyj \"{path}\" do konfiguracji s3cmd." @@ -1994,7 +1998,7 @@ msgstr "Korzystanie z androguard od \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Korzystanie z istniejącego magazynu kluczy \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Użyj s3cmd do synchronizacji z: {url}" @@ -2015,7 +2019,7 @@ msgstr "Sprawdź integralność pobranych pakietów" msgid "Verifying index signature:" msgstr "Weryfikowanie podpisu indeksu:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2076,7 +2080,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "applicationId, aby sprawdzić dostępność aktualizacji" @@ -2084,7 +2087,6 @@ msgstr "applicationId, aby sprawdzić dostępność aktualizacji" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "applicationId z opcjonalnym versionCode w postaci APPID [:VERCODE]" @@ -2153,7 +2155,7 @@ msgstr "nie mogę opublikować aktualizacji, czy ustawiłeś klucz wdrożenia?" msgid "cloning {url}" msgstr "klonowanie {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "polecenie do wykonania, 'init' lub 'update'" @@ -2320,16 +2322,16 @@ msgstr "niepoprawna wartość parametru conflict_resolution: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "niepoprawny ciąg opcji %(option)r: musi zaczynać się od postaci %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir nie kończy się na \"fdroid\", może masz na myśli: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir musi być ścieżką bezwzględną!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir musi być katalogiem, a nie plikiem!" @@ -2461,11 +2463,16 @@ msgstr "odmów pobierania przez niezabezpieczone połączenie HTTP (użyj HTTPS msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "odmów pobierania przez niezabezpieczone połączenie http (użyj https lub określ --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd zsynchronizuj indeksy {path} do {url} i usuń" @@ -2553,15 +2560,19 @@ msgstr "stosowanie: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "użycie: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "używając Apache libcloud do zsynchronizowania z {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2587,7 +2598,6 @@ msgstr "{apkfilename} AndroidManifest.xml ma złą datę: " #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "{appid} nie ma nazwy! Zamiast tego użyj nazwy pakietu." @@ -2603,7 +2613,6 @@ msgstr "{appid} z {path} nie jest prawidłową nazwą pakietu Android!" #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" msgid "{appid} from {path} is not a valid Android application ID!" msgstr "{appid} z {path} nie jest prawidłową nazwą pakietu Android!" @@ -2678,7 +2687,7 @@ msgstr "{path} ma zły podpis pliku \"{pattern}\", możliwe wykorzystanie Janusa msgid "{path} is zero size!" msgstr "{path} ma zerowy rozmiar!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/pt/LC_MESSAGES/fdroidserver.po b/locale/pt/LC_MESSAGES/fdroidserver.po index ebab6be0..c32aa62a 100644 --- a/locale/pt/LC_MESSAGES/fdroidserver.po +++ b/locale/pt/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-14 09:28+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese \n" @@ -77,7 +77,7 @@ msgstr "\"{path}\" contém {name} ({version}) desatualizado" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" contém {name} ({version}) recente" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe, mas s3cmd não está instalado!" @@ -516,12 +516,12 @@ msgstr "Criar uma chave de assinatura do repositório numa keystore" msgid "Create skeleton metadata files that are missing" msgstr "Criação do esqueleto de metadados dos ficheiros que estão em falta" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Novo contentor criado: \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Criando \"{path}\" para configurar s3cmd." @@ -530,7 +530,7 @@ msgstr "Criando \"{path}\" para configurar s3cmd." msgid "Creating log directory" msgstr "Criando o diretório de log" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Criando novo bucket S3: {url}" @@ -565,12 +565,12 @@ msgstr "DEBUG_KEYSTORE não está definido ou o valor está incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Eliminação de APK'S e/ou OBBs que não contêm metadados do repositório" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "Apagar ficheiro, o reporte é muito grande ({size} max {limit})" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "Apagar o histórico do git-mirror, o repo é muito grande ({size} max {limit})" @@ -632,7 +632,7 @@ msgstr "Não fazer nada relacionado a registros de alterações" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Não atualizar o repositório; útil quando testando uma compilação sem conexão com a internet" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Não usar as somas de verificação (checksums) do rsync" @@ -668,6 +668,10 @@ msgstr "Ligação duplicada em '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Analise dinâmica dos APKs após a compilação" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -699,7 +703,7 @@ msgstr "" "Digite o caminho para o SDK do Android (%s) aqui:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -737,7 +741,7 @@ msgstr "Falha ao redimensionar {path}: {error}" msgid "Failed to align application" msgstr "Falha ao alinhar a aplicação" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "Falha ao criar o bucket S3: {url}" @@ -863,7 +867,7 @@ msgstr "Nenhum certificado de assinatura para repositório encontrado." msgid "Found non-file at %s" msgstr "Não-ficheiro encontrado em %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "{apkfilename} encontrado em {url}" @@ -911,11 +915,11 @@ msgstr "Git submodule update falhou" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS deve ser usado nos URLs do Subversion!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "Se um espelho git ficar muito grande, permite que o arquivo seja apagado" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "Se esse envio falhar, tente enviar manualmente para {url}" @@ -1146,7 +1150,7 @@ msgstr "Fazer a compilação parar se encontrar exceções" msgid "Malformed repository mirrors." msgstr "Espelhos de repositório malformados." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Linha de serverwebroot malformada:" @@ -1208,7 +1212,7 @@ msgstr "Não há necessidade de especificar que o app é software livre" msgid "No need to specify that the app is for Android" msgstr "Não há necessidade de especificar que o app é para Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Sem opção definida! Edite seu config.py para definir pelo menos um destes:" @@ -1276,6 +1280,10 @@ msgstr "O nome do ficheiro OBB deve começar com \"main.\" ou \"patch.\":" msgid "OBB's packagename does not match a supported APK:" msgstr "O packagename do OBB não corresponde a um APK suportado:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1422,12 +1430,12 @@ msgstr "A pontuação deve ser evitada" msgid "Push the log to this git remote repository" msgstr "Submeter o registo de eventos para este repositório git remoto" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "A submeter o registo de transparência de binário para {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "A submeter para {url}" @@ -1521,7 +1529,7 @@ msgstr "Executar no repo git que tem alterações não confirmadas" msgid "Run rewritemeta to fix formatting" msgstr "Executar rewritemeta para corrigir a formatação" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Executando a primeira passagem com a verificação de MD5 desativada" @@ -1628,11 +1636,11 @@ msgstr "Ignorando {appid}: desativado" msgid "Skipping {appid}: no builds specified" msgstr "Ignorando {appid}: nenhuma compilação especificada" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Especifique uma pasta local para ser sincronizada com o repositório" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Especifique um ficheiro identidade para fornecer ao SSH para usar o rsync" @@ -1695,7 +1703,7 @@ msgstr "O diretório para onde escrever o espelho" msgid "The file to be included in the repo (path or glob)" msgstr "O ficherio a ser incluído no repo (caminho ou glob)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Os únicos comandos suportados atualmente são 'init' e 'update'" @@ -1707,7 +1715,7 @@ msgstr "A impressão digital do repositório não corresponde." msgid "The repository's index could not be verified." msgstr "O índice do repositório não pôde ser verificado." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "O diretório raiz para local_copy_dir \"{path}\" não existe!" @@ -1725,14 +1733,10 @@ msgstr "Estas são as aplicações que foram arquivadas do repositório principa msgid "This repo already has local metadata: %s" msgstr "Este repositório já tem metadados locais: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser definidos no config.py!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "A URL deve começar com https:// ou http://" @@ -1876,11 +1880,6 @@ msgstr "O caminho de scandelete não é usado: %s" msgid "Unused scanignore path: %s" msgstr "O caminho de scanignore não é usado: %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comum da aplicação - pode ser removido" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Atualizar a informação do repositório para novos pacotes" @@ -1912,16 +1911,25 @@ msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comum da aplicação - pode ser removido" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comun da aplicação - pode ser removido" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "A enviar {apkfilename} ao androidobservatory.org" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "A enviar {apkfilename} ao virustotal" @@ -1956,7 +1964,7 @@ msgstr "Use da data do APK em vez do tempo atual para APKs recém-adicionados" msgid "Use date from apk instead of current time for newly added apks" msgstr "Use a data do apk em vez do tempo atual para apks recém-adicionados" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Usando \"{path}\" para configurar s3cmd." @@ -1983,7 +1991,7 @@ msgstr "Usando androguard de \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Utilizando armazenamento de chave existente \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Usando s3cmd para sincronizar com: {url}" @@ -2004,7 +2012,7 @@ msgstr "Verifique a integridade dos pacotes descarregados" msgid "Verifying index signature:" msgstr "Verificar o índice de assinatura:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "A chave VirusTotal API não pode enviar ficheiros maiores que 32MB, use {url} para enviar {path}." @@ -2137,7 +2145,7 @@ msgstr "não é possível publicar a atualização, definiu a chave de implanta msgid "cloning {url}" msgstr "clonagem {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "comando para executar, seja 'init' ou 'update'" @@ -2302,16 +2310,16 @@ msgstr "valor conflict_resolution inválido: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "Opção cadeia %(option)r inválida: deve começar com o caractere %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir não termina com \"fdroid\", talvez quis: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir deve ser um caminho absoluto!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir deve ser directory, não um ficheiro!" @@ -2443,11 +2451,16 @@ msgstr "Recusado o download via conexão HTTP insegura (use HTTPS ou especifique msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "Recusado o download via conexão http insegura (use https ou especifique --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "o ruamel.yaml não está instalado, não é possível escrever metadados." -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sincroniza índices {path} para {url} e apaga" @@ -2535,15 +2548,19 @@ msgstr "utilização: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "utilização: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "usando o Apache libcloud para sincronizar com {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "o virustotal.com está a limitar a taxa, à espera para voltar a tentar..." +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2657,7 +2674,7 @@ msgstr "{path} tem uma má assinatura de ficheiro \"{pattern}\", um exploração msgid "{path} is zero size!" msgstr "{path} tem um tamanho de zero!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "{path} mais de 200MB, enviar manualmente: {url}" diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 6035ada5..7fc0588f 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-06 08:26+0000\n" "Last-Translator: André Marcelo Alvarenga \n" "Language-Team: Portuguese (Brazil) \n" @@ -82,7 +82,7 @@ msgstr "\"{path}\" contém {name} ({version}) desatualizado" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" contém {name} ({version}) recente" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe, mas s3cmd não está instalado!" @@ -395,7 +395,6 @@ msgstr "Impossível ler \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "Impossível resolver o ID de Aplicativo '{appid}'" @@ -522,12 +521,12 @@ msgstr "Criar uma chave de assinatura do repositório em uma keystore" msgid "Create skeleton metadata files that are missing" msgstr "Criar as bases dos arquivos de metadados que estão faltando" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Novo container criado \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Criando \"{path}\" para configurar s3cmd." @@ -536,7 +535,7 @@ msgstr "Criando \"{path}\" para configurar s3cmd." msgid "Creating log directory" msgstr "Criando diretório de registro" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Criando o novo Balde de S3: {url}" @@ -571,12 +570,12 @@ msgstr "DEBUG_KEYSTORE não está definido ou o valor está incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Apagar os APKs e/ou OBBs sem metadados do repositório" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "Excluindo o pacote, o repositório está grande demais ({size} máx {limit})" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "Excluindo histórico de git-mirror, o repositório está grande demais ({size} máx {limit})" @@ -638,7 +637,7 @@ msgstr "Não fazer nada relacionado a registros de alterações" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Não atualizar o repositório; útil quando testando uma compilação sem conexão com a internet" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Não usar as somas de verificação (checksums) do rsync" @@ -674,6 +673,10 @@ msgstr "Link duplicado em '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Escanear dinamicamente os APKs após a compilação" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -705,7 +708,7 @@ msgstr "" "Digite o caminho para o Android SDK (%s) aqui:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -743,7 +746,7 @@ msgstr "Falha ao redimensionar {path}: {error}" msgid "Failed to align application" msgstr "Falha ao alinhar a aplicação" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "Falha ao criar o Balde do S3: {url}" @@ -869,7 +872,7 @@ msgstr "Não encontrado os certificados de assinatura para o repositório." msgid "Found non-file at %s" msgstr "Arquivo não encontrado em %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "Encontrado {apkfilename} em {url}" @@ -917,11 +920,11 @@ msgstr "Falha na atualização do submódulo Git" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS deve ser usado com URLs do Subversion(SVN)!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "Se um espelho git ficar muito grande, permite que o arquivo seja excluído" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "Se o upload falhar, tente fazer o upload manualmente para {url}" @@ -1013,7 +1016,6 @@ msgstr "Versão de Operação de Código inválido: {field}" #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" msgid "Invalid application ID {appid}" msgstr "Versão de Operação de Código inválido: {field}" @@ -1126,7 +1128,6 @@ msgstr "Armazenamento de chaves de assinatura:\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "O último commit usado '{commit}' parece com uma tag, mas o Update Check Mode é '{ucm}'" @@ -1154,7 +1155,7 @@ msgstr "Fazer a compilação parar se encontrar exceções" msgid "Malformed repository mirrors." msgstr "Espelhos de repositórios malformados." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Linha mal-formada do 'serverwebroot':" @@ -1216,7 +1217,7 @@ msgstr "Não há necessidade de especificar que o aplicativo é Software Livre" msgid "No need to specify that the app is for Android" msgstr "Não há necessidade de especificar que é um aplicativo para Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Nenhuma opção definida! Edite seu 'config.py' para definir pelo menos um destes:" @@ -1284,6 +1285,10 @@ msgstr "O nome do arquivo OBB deve começar com \"main.\" ou \"patch.\":" msgid "OBB's packagename does not match a supported APK:" msgstr "O nome do pacote do OBB não corresponde a um APK suportado:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1430,12 +1435,12 @@ msgstr "Pontuação deve ser evitada" msgid "Push the log to this git remote repository" msgstr "Mandar o registro de mudanças para este repositório git remoto" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Atualizar o log de transparência de um binário para {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Empurrando para {url}" @@ -1529,7 +1534,7 @@ msgstr "Executar no repositório do Git que tenha alterações não confirmadas" msgid "Run rewritemeta to fix formatting" msgstr "Executar rewritemeta para corrigir a formatação" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Execução da primeira passagem com a verificação do MD5 desativada" @@ -1636,11 +1641,11 @@ msgstr "Ignorando {appid}: desativado" msgid "Skipping {appid}: no builds specified" msgstr "Ignorando {appid}: nenhuma construção especificada" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Especifique uma pasta local para ser sincronizada com o repositório" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Especifique um arquivo identidade para fornecer ao SSH para usar o rsync" @@ -1703,7 +1708,7 @@ msgstr "O diretório para escrever o espelho para" msgid "The file to be included in the repo (path or glob)" msgstr "O arquivo a ser incluído no repositório (caminho ou glob)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Os únicos comandos suportados atualmente são 'init' e 'update'" @@ -1715,7 +1720,7 @@ msgstr "A impressão digital do repositório não corresponde." msgid "The repository's index could not be verified." msgstr "O índice do repositório não pôde ser verificado." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "O diretório raiz para local_copy_dir \"{path}\" não existe!" @@ -1733,14 +1738,10 @@ msgstr "Estas são as aplicações que foram arquivadas a partir do repositório msgid "This repo already has local metadata: %s" msgstr "Este repositório já tem metadados locais: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser definidos no config.py!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "A URL deve começar com https:// ou http://" @@ -1884,13 +1885,6 @@ msgstr "Caminho scandelete não usado: %s" msgid "Unused scanignore path: %s" msgstr "Caminho scanignore não usado: %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Atualize as informações do repositório para novos pacotes" @@ -1922,18 +1916,27 @@ msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" + #: ../fdroidserver/lint.py #, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "Enviando o {apkfilename} para o androidobservatory.org" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "Enviando o {apkfilename} para o virustotal" @@ -1968,7 +1971,7 @@ msgstr "Usar a data do apk ao invés do horário atual para APKs recentemente ad msgid "Use date from apk instead of current time for newly added apks" msgstr "Usar a data do apk ao invés do horário atual para APKs recentemente adicionados" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Usando \"{path}\" para configurar s3cmd." @@ -1995,7 +1998,7 @@ msgstr "Usando androguard de \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Utilizando armazenamento de chave existente \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Usando s3cmd para sincronizar com: {url}" @@ -2016,7 +2019,7 @@ msgstr "Verifique a integridade dos pacotes baixados" msgid "Verifying index signature:" msgstr "Verificar o índice de assinatura:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "A chave API do VirusTotal não pode carregar arquivos maiores que 32MB, utilize {url} para enviar para {path}." @@ -2077,7 +2080,6 @@ msgstr "o apksigner não foi encontrado, ele é necessário para assinar!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "applicationId para verificar se há atualizações" @@ -2085,7 +2087,6 @@ msgstr "applicationId para verificar se há atualizações" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" @@ -2153,7 +2154,7 @@ msgstr "não é possível publicar a atualização, você definiu a chave de imp msgid "cloning {url}" msgstr "clonagem {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "comando para executar, seja 'init' ou 'update'" @@ -2318,16 +2319,16 @@ msgstr "valor conflict_resolution inválido: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "Opção cadeia %(option)r inválida: deve começar com o caractere %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir não termina com \"fdroid\", talvez você quis: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir deve ser um caminho absoluto!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir deve ser directory, não um arquivo!" @@ -2459,11 +2460,16 @@ msgstr "Recuse o download inseguro via conexão HTTP (use HTTPS ou especifique - msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "Recuse o download insegura via conexão http (use https ou especifique --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "o ruamel.yaml não está instalado, não é possível escrever os metadados." -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sincroniza índices {path} para {url} e exclui" @@ -2551,15 +2557,19 @@ msgstr "uso: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "uso: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "usando o Apache libcloud para sincronizar com {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "o virustotal.com está limitando a taxa, esperando para tentar novamente ..." +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2584,7 +2594,6 @@ msgstr "AndroidManifest.xml do {apkfilename} tem uma data má: " #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." @@ -2600,7 +2609,6 @@ msgstr "O {appid} do {path} não é um Nome de Pacote Android válido!" #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" msgid "{appid} from {path} is not a valid Android application ID!" msgstr "O {appid} do {path} não é um Nome de Pacote Android válido!" @@ -2675,7 +2683,7 @@ msgstr "{path} tem uma má assinatura de arquivo \"{pattern}\", um exploração msgid "{path} is zero size!" msgstr "{path} tem um tamanho de zero!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "o {path} tem mais de 200MB, upload manual: {url}" @@ -2702,12 +2710,6 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} compilação foi bem sucedida" msgstr[1] "{} compilações foram bem sucedidas" -#~ msgid "Cannot find a packageName for {path}!" -#~ msgstr "Não é possível encontrar um packageName para {path} 1!" - -#~ msgid "Cannot find an appid for {path}!" -#~ msgstr "Não é possível encontrar um appid para {path} 1!" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Adicione assinaturas gpg para os pacotes no repositório" @@ -2715,6 +2717,12 @@ msgstr[1] "{} compilações foram bem sucedidas" #~ msgid "Add gpg signatures for packages in repo" #~ msgstr "Adicione assinaturas gpg para os pacotes no repositório" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Não é possível encontrar um packageName para {path} 1!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Não é possível encontrar um appid para {path} 1!" + #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "Atualização limpa - não usa cache, reprocessa todos os APKs" diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index 426e2673..e6db64aa 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-14 09:28+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese (Portugal) \n" @@ -80,7 +80,7 @@ msgstr "\"{path}\" contém {name} ({version}) desatualizado" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" contém {name} ({version}) recente" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe, mas s3cmd não está instalado!" @@ -519,12 +519,12 @@ msgstr "Criar uma chave de assinatura do repositório numa keystore" msgid "Create skeleton metadata files that are missing" msgstr "Criação do esqueleto de metadados dos ficheiros que estão em falta" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Novo contentor criado: \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Criando \"{path}\" para configurar s3cmd." @@ -533,7 +533,7 @@ msgstr "Criando \"{path}\" para configurar s3cmd." msgid "Creating log directory" msgstr "Criando o diretório de log" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Criando novo bucket S3: {url}" @@ -568,12 +568,12 @@ msgstr "DEBUG_KEYSTORE não está definido ou o valor está incompleto" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Eliminação de APK'S e/ou OBBs que não contêm metadados do repositório" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "Apagar ficheiro, o reporte é muito grande ({size} max {limit})" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "Apagar o histórico do git-mirror, o repo é muito grande ({size} max {limit})" @@ -635,7 +635,7 @@ msgstr "Não fazer nada relacionado a registros de alterações" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Não atualizar o repositório; útil quando testando uma compilação sem conexão com a internet" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Não usar as somas de verificação (checksums) do rsync" @@ -671,6 +671,10 @@ msgstr "Ligação duplicada em '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Analise dinâmica dos APKs após a compilação" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -702,7 +706,7 @@ msgstr "" "Digite o caminho para o SDK do Android (%s) aqui:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -740,7 +744,7 @@ msgstr "Falha ao redimensionar {path}: {error}" msgid "Failed to align application" msgstr "Falha ao alinhar a aplicação" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "Falha ao criar o bucket S3: {url}" @@ -866,7 +870,7 @@ msgstr "Nenhum certificado de assinatura para repositório encontrado." msgid "Found non-file at %s" msgstr "Não-ficheiro encontrado em %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "{apkfilename} encontrado em {url}" @@ -914,11 +918,11 @@ msgstr "Git submodule update falhou" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS deve ser usado nos URLs do Subversion!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "Se um espelho git ficar muito grande, permite que o arquivo seja apagado" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "Se esse envio falhar, tente enviar manualmente para {url}" @@ -1149,7 +1153,7 @@ msgstr "Fazer a compilação parar se encontrar exceções" msgid "Malformed repository mirrors." msgstr "Espelhos de repositório malformados." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Linha de serverwebroot malformada:" @@ -1211,7 +1215,7 @@ msgstr "Não há necessidade de especificar que o app é software livre" msgid "No need to specify that the app is for Android" msgstr "Não há necessidade de especificar que o app é para Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Sem opção definida! Edite seu config.py para definir pelo menos um destes:" @@ -1279,6 +1283,10 @@ msgstr "O nome do ficheiro OBB deve começar com \"main.\" ou \"patch.\":" msgid "OBB's packagename does not match a supported APK:" msgstr "O packagename do OBB não corresponde a um APK suportado:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1425,12 +1433,12 @@ msgstr "A pontuação deve ser evitada" msgid "Push the log to this git remote repository" msgstr "Submeter o registo de eventos para este repositório git remoto" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "A submeter o registo de transparência de binário para {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "A submeter para {url}" @@ -1524,7 +1532,7 @@ msgstr "Executar no repo git que tem alterações não confirmadas" msgid "Run rewritemeta to fix formatting" msgstr "Executar rewritemeta para corrigir a formatação" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Executando a primeira passagem com a verificação de MD5 desativada" @@ -1631,11 +1639,11 @@ msgstr "Ignorando {appid}: desativado" msgid "Skipping {appid}: no builds specified" msgstr "Ignorando {appid}: nenhuma compilação especificada" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Especifique uma pasta local para ser sincronizada com o repositório" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Especifique um ficheiro identidade para fornecer ao SSH para usar o rsync" @@ -1698,7 +1706,7 @@ msgstr "O diretório para onde escrever o espelho" msgid "The file to be included in the repo (path or glob)" msgstr "O ficherio a ser incluído no repo (caminho ou glob)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Os únicos comandos suportados atualmente são 'init' e 'update'" @@ -1710,7 +1718,7 @@ msgstr "A impressão digital do repositório não corresponde." msgid "The repository's index could not be verified." msgstr "O índice do repositório não pôde ser verificado." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "O diretório raiz para local_copy_dir \"{path}\" não existe!" @@ -1728,14 +1736,10 @@ msgstr "Estas são as aplicações que foram arquivadas do repositório principa msgid "This repo already has local metadata: %s" msgstr "Este repositório já tem metadados locais: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Para usar awsbucket, os awssecretkey e awsaccesskeyid também devem ser definidos no config.py!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "A URL deve começar com https:// ou http://" @@ -1879,11 +1883,6 @@ msgstr "O caminho de scandelete não é usado: %s" msgid "Unused scanignore path: %s" msgstr "O caminho de scanignore não é usado: %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comum da aplicação - pode ser removido" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Atualizar a informação do repositório para novos pacotes" @@ -1915,16 +1914,25 @@ msgstr "UpdateCheckData deve usar um URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData não é uma URL válida: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi executado" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comum da aplicação - pode ser removido" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "UpdateCheckName (o nome da verificação de atualização) é definido como o ID comun da aplicação - pode ser removido" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "A enviar {apkfilename} ao androidobservatory.org" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "A enviar {apkfilename} ao virustotal" @@ -1959,7 +1967,7 @@ msgstr "Use da data do APK em vez do tempo atual para APKs recém-adicionados" msgid "Use date from apk instead of current time for newly added apks" msgstr "Use a data do apk em vez do tempo atual para apks recém-adicionados" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Usando \"{path}\" para configurar s3cmd." @@ -1986,7 +1994,7 @@ msgstr "Usando androguard de \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Utilizando armazenamento de chave existente \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Usando s3cmd para sincronizar com: {url}" @@ -2007,7 +2015,7 @@ msgstr "Verifique a integridade dos pacotes descarregados" msgid "Verifying index signature:" msgstr "Verificar o índice de assinatura:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "A chave VirusTotal API não pode enviar ficheiros maiores que 32MB, use {url} para enviar {path}." @@ -2140,7 +2148,7 @@ msgstr "não é possível publicar a atualização, definiu a chave de implanta msgid "cloning {url}" msgstr "clonagem {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "comando para executar, seja 'init' ou 'update'" @@ -2305,16 +2313,16 @@ msgstr "valor conflict_resolution inválido: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "Opção cadeia %(option)r inválida: deve começar com o caractere %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir não termina com \"fdroid\", talvez quis: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir deve ser um caminho absoluto!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir deve ser directory, não um ficheiro!" @@ -2446,11 +2454,16 @@ msgstr "Recusado o download via conexão HTTP insegura (use HTTPS ou especifique msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "Recusado o download via conexão http insegura (use https ou especifique --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "o ruamel.yaml não está instalado, não é possível escrever metadados." -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sincroniza índices {path} para {url} e exclui" @@ -2538,15 +2551,19 @@ msgstr "utilização: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "utilização: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "usando o Apache libcloud para sincronizar com {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "o virustotal.com está a limitar a taxa, à espera para voltar a tentar..." +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2660,7 +2677,7 @@ msgstr "{path} tem uma má assinatura de ficheiro \"{pattern}\", um exploração msgid "{path} is zero size!" msgstr "{path} tem um tamanho de zero!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "{path} mais de 200MB, enviar manualmente: {url}" diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index bec29d58..1d587503 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-05 12:34+0000\n" "Last-Translator: Boris Timofeev \n" "Language-Team: Russian \n" @@ -77,7 +77,7 @@ msgstr "В пути \"{path}\" устаревшие имя {name} или вер msgid "\"{path}\" contains recent {name} ({version})" msgstr "в пути \"{path}\" последние имя {name} и версия {version} пакета" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "путь \"{path}\" существует, но s3cmd клиент не установлен!" @@ -392,7 +392,6 @@ msgstr "Неправильно указан путь \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "Не удалось разобрать app id {appid}" @@ -519,12 +518,12 @@ msgstr "Создать ключ для подписывания репозито msgid "Create skeleton metadata files that are missing" msgstr "Создать отсутствующие основные метаданные" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Новый контейнер \"{name}\" создан" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Создание \"{path}\" для конфигурации s3cmd." @@ -533,7 +532,7 @@ msgstr "Создание \"{path}\" для конфигурации s3cmd." msgid "Creating log directory" msgstr "Создание директории для хранения логов" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Создание нового S3 bucket: {url}" @@ -568,12 +567,12 @@ msgstr "Переменная DEBUG_KEYSTORE пустая или заполнен msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Удалить из репозитория APK и/или OBB файлы без метаданных" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -635,7 +634,7 @@ msgstr "Не писать никаких логов" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Не обновлять репозиторий. Упрощает тестовые сборки при отсутствии интернета" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Не использовать контрольные суммы rsync" @@ -671,6 +670,10 @@ msgstr "Точная копия ссылки в '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Сканировать APK файлы после сборки" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -702,7 +705,7 @@ msgstr "" "Укажите путь к Android SDK (%s): \n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -740,7 +743,7 @@ msgstr "Не удалось изменить размер {path}: {error}" msgid "Failed to align application" msgstr "Оптимизировать (align) приложение не удалось" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "Создать S3 объект (S3 bucket) не получилось: {url}" @@ -868,7 +871,7 @@ msgstr "Сертификат для подписывания для этого msgid "Found non-file at %s" msgstr "Это не похоже на файл: %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "Найдено {apkfilename} в {url}" @@ -916,12 +919,12 @@ msgstr "Не удалось обновить модули Git (git submodules up msgid "HTTPS must be used with Subversion URLs!" msgstr "URL-адреса для Subversion должны начинаться с HTTPS!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "Если git-зеркало станет большим, разрешите удалить архив." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "Если эта загрузка не удалась, попробуйте вручную загрузить в {url}." @@ -1013,7 +1016,6 @@ msgstr "Расхождение версий приложения в метада #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" msgid "Invalid application ID {appid}" msgstr "Расхождение версий приложения в метаданных: {field}" @@ -1126,7 +1128,6 @@ msgstr "Хранилище ключа для подписывания:→\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Последний наложенный коммит '{commit}' похож на метку (tag), но режим проверки обновлений (Update Check Mode) — '{ucm}'" @@ -1155,7 +1156,7 @@ msgstr "Останавливать сборку при появлении иск msgid "Malformed repository mirrors." msgstr "Неверные адреса зеркал для репозитория." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Неверный путь serverwebroot:" @@ -1218,7 +1219,7 @@ msgstr "Указывать в описании, что приложение св msgid "No need to specify that the app is for Android" msgstr "Указывать в описании, что приложение для Android, не обязательно. Других здесь не держат" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Недостаточно опций сборки! Настройте как минимум вот эти (в config.py):" @@ -1286,6 +1287,10 @@ msgstr "Имя файла OBB должно начинаться с \"main.\" и msgid "OBB's packagename does not match a supported APK:" msgstr "Указанный в OBB файле packagename не соответствует указанному в APK:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1433,12 +1438,12 @@ msgstr "Знаки препинания недопустимы" msgid "Push the log to this git remote repository" msgstr "Отправить лог в удаленный репозиторий git" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Публикация лога прозрачности кода в {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Публикация в {url}" @@ -1532,7 +1537,7 @@ msgstr "Запустить для репозитория git с несохран msgid "Run rewritemeta to fix formatting" msgstr "Запустить rewritemeta для исправления ошибок форматирования" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Первая попытка загрузить данные (выполняется с отключенной проверкой MD5)" @@ -1640,11 +1645,11 @@ msgstr "Пропустить {appid}: отключено" msgid "Skipping {appid}: no builds specified" msgstr "Пропустить {appid}: нет выбранных сборок" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Выбрать локальную директорию, с которой будет синхронизирован репозиторий" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Выбрать идентификационный файл (нужен SSH для rsync)" @@ -1707,7 +1712,7 @@ msgstr "Директория для сохранения зеркала" msgid "The file to be included in the repo (path or glob)" msgstr "Файл для включения в репозиторий (путь или шаблон пути)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "В настоящее время поддерживаются только команды 'init' и 'update'" @@ -1719,7 +1724,7 @@ msgstr "Идентификационная метка (fingerprint) репози msgid "The repository's index could not be verified." msgstr "Индекс репозитория не прошёл проверку." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "Корневой директории для local_copy_dir \"{path}\" нет!" @@ -1737,14 +1742,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "Локальная копия метаданных репозитория уже существует: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Необходимо определить переменные awsbucket, awssecretkey и awsaccesskeyid в config.py!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "Режим проверки обновлений (Update Check Mode) выбран, но проверка еще ни разу не выполнялась" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1889,13 +1890,6 @@ msgstr "Файл не ипользуется %s" msgid "Unused scanignore path: %s" msgstr "Файл не ипользуется %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Имя приложения для проверки обновлений (Update Check Name) соответствует app id. Это поле можно удалить" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Обновить информацию о репозитории для новых пакетов" @@ -1927,18 +1921,27 @@ msgstr "URL-адрес в UpdateCheckData должен начинаться с H msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData содержит некорректный URL-адрес: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "Режим проверки обновлений (Update Check Mode) выбран, но проверка еще ни разу не выполнялась" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "Имя приложения для проверки обновлений (Update Check Name) соответствует app id. Это поле можно удалить" + #: ../fdroidserver/lint.py #, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "Имя приложения для проверки обновлений (Update Check Name) соответствует app id. Это поле можно удалить" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "Чтение {apkfilename} из кеша" @@ -1973,7 +1976,7 @@ msgstr "Использовать время date из APK вместо теку msgid "Use date from apk instead of current time for newly added apks" msgstr "Использовать время date из APK вместо текущего при добавлении новых APK" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Для конфигурации s3cmd используется \"{path}\"." @@ -2000,7 +2003,7 @@ msgstr "Запуск androguard из \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Используются ключи из \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "s3cmd синхронизация с: {url}" @@ -2021,7 +2024,7 @@ msgstr "Проверить загруженные пакеты на повреж msgid "Verifying index signature:" msgstr "Проверка подписи индекса:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2082,7 +2085,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "applicationId для проверки обновлений" @@ -2090,7 +2092,6 @@ msgstr "applicationId для проверки обновлений" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "applicationId и внутренняя версия приложения (versionCode) в виде APPID[:VERCODE]" @@ -2159,7 +2160,7 @@ msgstr "не получается опубликовать обновление. msgid "cloning {url}" msgstr "клонирование {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "выполняемая команда, 'init' или 'update'" @@ -2326,16 +2327,16 @@ msgstr "неверное значение conflict_resolution: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "неверный синтаксис в строке опции %(option)r: она должна начинаться с символа %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir должна заканчиваться на \"fdroid\". Возможно, имелось в виду \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "Путь к local_copy_dir должен быть абсолютным!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir должна быть директорией, а не файлом!" @@ -2467,11 +2468,16 @@ msgstr "использовать для загрузки небезопасно msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "использовать для загрузки небезопасное HTTP-соединение не стоит (пользуйтесь HTTPS или укажите --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd синхронизировать индексы из {path} в {url} и удалить их" @@ -2559,15 +2565,19 @@ msgstr "использование: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "использование: fdroid [-h|--help|--version] <команда> []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "Аpache libcloud: синхронизация с {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2593,7 +2603,6 @@ msgstr "AndroidManifest.xml приложения {apkfilename} содержит #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "У {appid} нет имени! Будет использовано имя пакета." @@ -2609,7 +2618,6 @@ msgstr "{appid} из {path} не годится в качестве имени #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" msgid "{appid} from {path} is not a valid Android application ID!" msgstr "{appid} из {path} не годится в качестве имени пакета Android!" @@ -2684,7 +2692,7 @@ msgstr "{path}: неверная подпись \"{pattern}\". Выглядит msgid "{path} is zero size!" msgstr "размер {path} равен нулю!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/sk/LC_MESSAGES/fdroidserver.po b/locale/sk/LC_MESSAGES/fdroidserver.po index 798257b3..07e91cbd 100644 --- a/locale/sk/LC_MESSAGES/fdroidserver.po +++ b/locale/sk/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -64,7 +64,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -505,12 +505,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -519,7 +519,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -554,12 +554,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -621,7 +621,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -657,6 +657,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -684,7 +688,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -722,7 +726,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -848,7 +852,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -896,11 +900,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1131,7 +1135,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1193,7 +1197,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1261,6 +1265,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1407,12 +1415,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1506,7 +1514,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1614,11 +1622,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1681,7 +1689,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1693,7 +1701,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1711,14 +1719,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1862,11 +1866,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1898,16 +1897,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1942,7 +1950,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1969,7 +1977,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1990,7 +1998,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2123,7 +2131,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2290,16 +2298,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2431,11 +2439,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2523,15 +2536,19 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2646,7 +2663,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/sq/LC_MESSAGES/fdroidserver.po b/locale/sq/LC_MESSAGES/fdroidserver.po index a90be56f..f17bcb2e 100644 --- a/locale/sq/LC_MESSAGES/fdroidserver.po +++ b/locale/sq/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-04-26 19:11+0000\n" "Last-Translator: Besnik Bleta \n" "Language-Team: Albanian \n" @@ -72,7 +72,7 @@ msgstr "\"{path}\" përmban {name} të vjetruar ({version})" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" përmban {name} të freskët ({version})" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" ekziston, por s3cmd s’është e instaluar!" @@ -386,7 +386,6 @@ msgstr "S’lexohet dot \"${path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "S’ftillohet dot ID aplikacioni {appid}" @@ -516,12 +515,12 @@ msgstr "Krijoni një kyç nënshkrimi depoje në një depo kyçesh" msgid "Create skeleton metadata files that are missing" msgstr "Krijoni kartela tejtëdhënash skeleton që mungojnë" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "U krijua kontejner i ri \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Po krijohet \"{path}\" për formësim të s3cmd." @@ -530,7 +529,7 @@ msgstr "Po krijohet \"{path}\" për formësim të s3cmd." msgid "Creating log directory" msgstr "Po krijohet drejtori regjistrash" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Po krijohet S3 bucket i ri: {url}" @@ -565,12 +564,12 @@ msgstr "DEBUG_KEYSTORE s’është ujdisur ose vlera është e paplotë" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Fshi APK-ra dhe/ose OBB-ra pa tejtëdhëna prej depos" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -632,7 +631,7 @@ msgstr "Mos bëj gjë që lidhet me regjistrat" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Mos rifresko depon, e dobishme kur testohet një montim pa lidhje internet" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Mos përdorni checksum-e rsync-u" @@ -668,6 +667,10 @@ msgstr "Lidhje e përsëdytur te '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Skano dinamikisht APK-ra pas montimi" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -699,7 +702,7 @@ msgstr "" "Jepni shtegun për te Android SDK (%s) këtu:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -737,7 +740,7 @@ msgstr "S’u arrit të ripërmasohej {path}: {error}" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "S’u arrit të krijohej bucket S3: {url}" @@ -864,7 +867,7 @@ msgstr "S’u gjetën dëshmi nënshkrimi për depon." msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "po kopjohet {apkfilename} te {path}" @@ -912,11 +915,11 @@ msgstr "Veprimi “git submodule update” dështoi" msgid "HTTPS must be used with Subversion URLs!" msgstr "Me URL Subversion duhet përdorur HTTPS!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1008,7 +1011,6 @@ msgstr "VercodeOperationi pavlefshëm: {field}" #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" msgid "Invalid application ID {appid}" msgstr "VercodeOperationi pavlefshëm: {field}" @@ -1121,7 +1123,6 @@ msgstr "Depo kyçesh për kyç nënshkrimi:\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "Parashtrimi '{commit}' i përdorur së fundi duket si etiketë, por si Mënyrë Kontrolli Përditësimesh është '{ucm}'" @@ -1150,7 +1151,7 @@ msgstr "Bëje montimin të ndalet kur has përjashtime" msgid "Malformed repository mirrors." msgstr "Pasqyra depoje të keqformuara." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Rresht serverwebroot i keqformuar:" @@ -1213,7 +1214,7 @@ msgstr "S’ka nevojë të specifikohet që aplikacioni është Software i Lirë msgid "No need to specify that the app is for Android" msgstr "S’ka nevojë të specifikohet që aplikacioni është për Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "S’ka mundësi të ujdisur! Përpunoni config.py tuaj që të ujdisni të paktën një prej:" @@ -1281,6 +1282,10 @@ msgstr "Emri i kartelës OBB duhet të fillojë me \"main.\" ose \"patch.\":" msgid "OBB's packagename does not match a supported APK:" msgstr "packagename i OBB-së nuk përputhet me ndonjë APK të mbuluar:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1428,12 +1433,12 @@ msgstr "Pikësimi duhet shmangur" msgid "Push the log to this git remote repository" msgstr "Kryej push të regjistrit te kjo depo e largët git" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1527,7 +1532,7 @@ msgstr "Xhirojeni në depo git që ka ndryshime të padepozituara te dega vendor msgid "Run rewritemeta to fix formatting" msgstr "Që të ndreqet formatimi, xhironi rewritemeta" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Po xhirohet kalimi i parë me kontrollin MD5 të çaktivizuar" @@ -1634,11 +1639,11 @@ msgstr "Po anashkalohet {appid}: e çaktivizuar" msgid "Skipping {appid}: no builds specified" msgstr "Po anashkalohet {appid}: s’u specifikuan montime" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Specifikoni një dosje vendore te e cila të njëkohësohet depoja" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Specifikoni një kartelë identiteti për t’ia furnizuar SSH-s për njëkohësim me rsync-un" @@ -1701,7 +1706,7 @@ msgstr "Drejtoria ku të shkruhet pasqyra" msgid "The file to be included in the repo (path or glob)" msgstr "Kartela që duhet përfshirë te depoja (shteg ose shenjë e gjithëpushtetshme)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Urdhrat e vetme të mbuluara janë 'init' dhe 'update'" @@ -1713,7 +1718,7 @@ msgstr "Shenjat e gishtave të depos nuk përputhen." msgid "The repository's index could not be verified." msgstr "Treguesi i depos s’u verifikua dot." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "Drejtoria rrënjë për local_copy_dir \"{path}\" s’ekziston!" @@ -1731,14 +1736,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "Kjo depo ka tashmë tejtëdhëna vendore: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Për të përdorur awsbucket, te config.py duhen ujdisur edhe awssecretkey dhe awsaccesskey!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode është ujdisur, por duket sikur checkupdates s’është xhiruar ende" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1883,13 +1884,6 @@ msgstr "Kartelë e papërdorur te %s" msgid "Unused scanignore path: %s" msgstr "Kartelë e papërdorur te %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Përditësoni të dhëna depoje për paketa të reja" @@ -1921,18 +1915,27 @@ msgstr "UpdateCheckData duhet të përdorë URL HTTPS: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData s’është URL e vlefshme: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode është ujdisur, por duket sikur checkupdates s’është xhiruar ende" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" + #: ../fdroidserver/lint.py #, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "Po lexohet {apkfilename} prej fshehtine" @@ -1967,7 +1970,7 @@ msgstr "Për APK-ra të shtuara rishtazi, përdor datë prej APK-je, në vend se msgid "Use date from apk instead of current time for newly added apks" msgstr "Për APK-ra të shtuara rishtazi, përdor datë prej APK-je, në vend se të kohës së tanishme" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Po përdoret \"{path}\" për formësim të s3cmd." @@ -1994,7 +1997,7 @@ msgstr "Po përdoret androguard prej \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Po përdoret depo ekzistuese kyçesh \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Po përdoret s3cmd për njëkohësim me: {url}" @@ -2015,7 +2018,7 @@ msgstr "Verifikoni integritetin e paketave të shkarkuara" msgid "Verifying index signature:" msgstr "Po verifikohet nënshkrim treguesi:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2076,7 +2079,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "applicationId për të cilin të kontrollohet për përditësime" @@ -2084,7 +2086,6 @@ msgstr "applicationId për të cilin të kontrollohet për përditësime" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "applicationId me versionCode opsional në formën APPID[:VERCODE]" @@ -2153,7 +2154,7 @@ msgstr "s’mund të botohet përditësim, e ujdisët kyçin e sendërtimit?" msgid "cloning {url}" msgstr "po klonohet {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "urdhër për t’u ekzekutuar, ose 'init', ose 'update'" @@ -2318,16 +2319,16 @@ msgstr "vlerë e pavlefshme conflict_resolution: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "varg i pavlefshëm mundësie %(option)r: duhet të fillojë me një shenjë %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir does s’mbaron me \"fdroid\", ndoshta kishit në mendje: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir duhet të jetë një shteg absolut!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir duhet të jetë një drejtori, jo një kartelë!" @@ -2459,11 +2460,16 @@ msgstr "refuzo shkarkim përmes lidhjeje HTTP të pasigurt (përdorni HTTPS ose msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "mos pranon shkarkim përmes lidhjeje http të pasigurt (përdorni https ose specifikoni --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2551,15 +2557,19 @@ msgstr "përdorimi: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "përdorimi: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "po përdoret Apache libcloud për njëkohësim me {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2584,7 +2594,6 @@ msgstr "AndroidManifest.xml e {apkfilename} ka një datë të gabuar: " #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "{appid} s’ka emër! Në vend të tij po përdoret emër pakete." @@ -2600,7 +2609,6 @@ msgstr "{appid} prej {path} s’është Emër i vlefshëm Pakete Android!" #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" msgid "{appid} from {path} is not a valid Android application ID!" msgstr "{appid} prej {path} s’është Emër i vlefshëm Pakete Android!" @@ -2675,7 +2683,7 @@ msgstr "{path} ka \"{pattern}\" të gabuar nënshkrimi kartele, ka gjasa të jet msgid "{path} is zero size!" msgstr "{path} është me madhësi zero!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/sv/LC_MESSAGES/fdroidserver.po b/locale/sv/LC_MESSAGES/fdroidserver.po index e742cba5..4acafd43 100644 --- a/locale/sv/LC_MESSAGES/fdroidserver.po +++ b/locale/sv/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2018-10-14 14:43+0000\n" "Last-Translator: Jonatan Nyberg \n" "Language-Team: Swedish \n" @@ -66,7 +66,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -505,12 +505,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "Skapa skelettmetadatafiler som saknas" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -519,7 +519,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -554,12 +554,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Ta bort APKs och/eller OBBs utan metadata från förråd" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -621,7 +621,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -657,6 +657,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -684,7 +688,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -722,7 +726,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -848,7 +852,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -896,11 +900,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1131,7 +1135,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1193,7 +1197,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1261,6 +1265,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1407,12 +1415,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1506,7 +1514,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1613,11 +1621,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1680,7 +1688,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1692,7 +1700,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1710,14 +1718,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1861,11 +1865,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Uppdatera förrådinformation för nya paket" @@ -1897,16 +1896,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1941,7 +1949,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1968,7 +1976,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1989,7 +1997,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2122,7 +2130,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2287,16 +2295,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2428,11 +2436,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2520,15 +2533,19 @@ msgstr "användning: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "användning: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2642,7 +2659,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index 320a615e..c004df9f 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-08 06:06+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" @@ -77,7 +77,7 @@ msgstr "\"{path}\" tarihi geçmiş {name} ({version}) içeriyor" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" en son {name} ({version}) içeriyor" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" var ancak s3cmd kurulu değil!" @@ -516,12 +516,12 @@ msgstr "Bir anahtar deposunda, depo imzalama anahtarı yaratır" msgid "Create skeleton metadata files that are missing" msgstr "Eksik olan iskelet üst veri dosyalarını yarat" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Yeni kapsayıcı \"{name}\" oluşturuldu" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "s3cmd yapılandırması için \"{path}\" oluşturuluyor." @@ -530,7 +530,7 @@ msgstr "s3cmd yapılandırması için \"{path}\" oluşturuluyor." msgid "Creating log directory" msgstr "Günlük dizini oluşturuluyor" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Yeni S3 kovası oluşturuluyor: {url}" @@ -565,12 +565,12 @@ msgstr "DEBUG_KEYSTORE ayarlı değil veya değer eksik" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Depodan üst verisi olmayan APKları ve/veya OBBleri sil" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "Arşiv siliniyor, depo çok büyük ({size}, en fazla {limit})" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "git-mirror geçmişi siliniyor, depo çok büyük ({size}, en fazla {limit})" @@ -632,7 +632,7 @@ msgstr "Günlüklerle ilgili bir şey yapma" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Depoyu yenileme, bir inşa internet bağlantısı olmadan sınanırken yararlıdır" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Rsync sağlama toplamlarını kullanma" @@ -668,6 +668,10 @@ msgstr "'{field}' içinde yinelenen bağlantı: {url}" msgid "Dynamically scan APKs post build" msgstr "İnşa sonrası APKları dinamik olarak tara" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -699,7 +703,7 @@ msgstr "" "Android SDK (%s) konumunu buraya girin:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -737,7 +741,7 @@ msgstr "{path} yeniden boyutlandırılamadı: {error}" msgid "Failed to align application" msgstr "Uygulama hizalama başarısız oldu" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "S3 kovası oluşturulamadı: {url}" @@ -863,7 +867,7 @@ msgstr "Depo için imzalama sertifikaları bulunmadı." msgid "Found non-file at %s" msgstr "%s konumunda dosya olmayan bulundu" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "{url} adresinde {apkfilename} bulundu" @@ -911,11 +915,11 @@ msgstr "Git alt modülü güncellemesi başarısız oldu" msgid "HTTPS must be used with Subversion URLs!" msgstr "Subversion URL'leriyle HTTPS kullanılmalı!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "Git yansısı çok büyük olursa, arşivin silinmesine izin ver" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "Bu yükleme başarısız olursa, {url} adresine elle yüklemeyi deneyin" @@ -1146,7 +1150,7 @@ msgstr "Özel durumlarda inşayı durdur" msgid "Malformed repository mirrors." msgstr "Bozuk depo yansımaları." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Bozuk serverwebroot satırı:" @@ -1208,7 +1212,7 @@ msgstr "Uygulamanın Özgür Yazılım olduğunu belirtmeye gerek yok" msgid "No need to specify that the app is for Android" msgstr "Uygulamanın Android için olduğunu belirtmeye gerek yok" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Ayarlı seçenek yok! Sunlardan en az birini ayarlamak için config.py dosyanızı düzenleyin:" @@ -1276,6 +1280,10 @@ msgstr "OBB dosya adı \"main.\" veya \"patch.\" ile başlamalıdır:" msgid "OBB's packagename does not match a supported APK:" msgstr "OBB'ın packagename değeri desteklenen APK ile eşleşmiyor:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1422,12 +1430,12 @@ msgstr "Noktalama işaretlerinden kaçınılmalı" msgid "Push the log to this git remote repository" msgstr "Günlüğü bu git uzak deposuna it" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "İkili şeffaflık günlüğü {url} konumuna gönderiliyor" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "{url} adresine itiliyor" @@ -1521,7 +1529,7 @@ msgstr "Değişiklikleri olmayan git repo üzerinde çalış" msgid "Run rewritemeta to fix formatting" msgstr "Biçimlemeyi düzeltmek için rewritemeta çalıştır" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "İlk geçiş MD5 doğrulama olmadan çalıştırılıyor" @@ -1628,11 +1636,11 @@ msgstr "{appid} atlanıyor: devre dışı" msgid "Skipping {appid}: no builds specified" msgstr "{appid} atlanıyor: belirtilmiş inşa yok" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Deponun eşleneceği yerel bir klasör belirtin" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Rsync için SSH'a sağlanacak bir kimlik dosyası belirtin" @@ -1695,7 +1703,7 @@ msgstr "Yansımanın yazılacağı dizin" msgid "The file to be included in the repo (path or glob)" msgstr "Repo'ya dahil edilecek dosya (yol veya glob)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Şu anda desteklenen komutlar sadece 'init' ve 'update'" @@ -1707,7 +1715,7 @@ msgstr "Deponun parmak izi eşleşmiyor." msgid "The repository's index could not be verified." msgstr "Deponun indeksi doğrulanamıyor." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "local_copy_dir \"{path}\" için kök dizini yok!" @@ -1725,14 +1733,10 @@ msgstr "Bunlar ana depodan arşivlenmiş uygulamalardır." msgid "This repo already has local metadata: %s" msgstr "Bu deponun zaten yerel üst verisi var: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Awsbucket kullanmak için, awssecretkey ve awsaccesskeyid de config.py içinde ayarlanmalı!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode ayarlı ancak checkupdates henüz çalıştırılmamış gibi görünüyor" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "URL https:// veya http:// ile başlamalı" @@ -1876,11 +1880,6 @@ msgstr "Kullanılmayan scandelete yolu: %s" msgid "Unused scanignore path: %s" msgstr "Kullanılmayan scanignore yolu: %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "UpdateCheckName bilinen uygulama kimliğine ayarlı - kaldırılabilir" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Yeni paketler için depo bilgisini güncelle" @@ -1912,16 +1911,25 @@ msgstr "UpdateCheckData, HTTPS URL'sini kullanmalıdır: {url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData geçerli bir URL değil: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode ayarlı ancak checkupdates henüz çalıştırılmamış gibi görünüyor" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "UpdateCheckName bilinen uygulama kimliğine ayarlı - kaldırılabilir" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "UpdateCheckName bilinen uygulama kimliğine ayarlı - kaldırılabilir" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "{apkfilename}, androidobservatory.org'a yükleniyor" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "{apkfilename} virustotal'e yükleniyor" @@ -1956,7 +1964,7 @@ msgstr "Yeni eklenen APKlar için o anki zaman yerine APK'daki tarihi kullan" msgid "Use date from apk instead of current time for newly added apks" msgstr "Yeni eklenen APKlar için o anki zaman yerine APK tarihini kullan" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "s3cmd yapılandırması için \"{path}\" kullanılıyor." @@ -1983,7 +1991,7 @@ msgstr "\"{path}\" adresinden androguard'ı kullanıyor" msgid "Using existing keystore \"{path}\"" msgstr "Var olan anahtar deposu \"{path}\" kullanılıyor" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "{url} ile eşitleme için s3cmd kullanılıyor" @@ -2004,7 +2012,7 @@ msgstr "İndirilen paketlerin bütünlüğünü doğrula" msgid "Verifying index signature:" msgstr "İndeks imzası doğrulanıyor:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "VirusTotal API anahtarı 32MB'den büyük dosyaları yükleyemiyor, {path} yüklemek için {url} kullanın." @@ -2137,7 +2145,7 @@ msgstr "güncelleme yayımlanamıyor, dağıtım anahtarını ayarladınız mı? msgid "cloning {url}" msgstr "{url} klonlanıyor" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "çalıştırılacak komut, 'init' ya da 'update'" @@ -2302,16 +2310,16 @@ msgstr "geçersiz conflict_resolution değeri: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "geçersiz seçenek satırı %(option)r: %(prefix_chars)r karakteri ile başlamalı" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir \"fdroid\" ile sonlanmıyor, belki de \"{path}\" demek istediniz" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir mutlak bir yol olmalı!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir bir dizin olmalı, dosya değil!" @@ -2443,11 +2451,16 @@ msgstr "güvensiz HTTP bağlantısı ile indirmeyi reddet (HTTPS kullanın veya msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "güvensiz http bağlantısı ile indirmeyi reddet (https kullanın veya --no-https-check belirtin): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "ruamel.yaml kurulu değil, üst veriler yazılamıyor." -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd sync {path} konumunu {url} adresine indeksler ve siler" @@ -2535,15 +2548,19 @@ msgstr "kullanım: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "kullanım: fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "{url} ile eşitleme için Apache libcloud kullanılıyor" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "virustotal.com hızı sınırlıyor, yeniden deneme bekleniyor..." +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2657,7 +2674,7 @@ msgstr "{path} konumunun bozum imzası \"{pattern}\" var, olası Janus istismar msgid "{path} is zero size!" msgstr "{path} boyutu sıfır!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "{path} 200MB'den fazla, elle yükleyin: {url}" @@ -2684,12 +2701,6 @@ msgid_plural "{} builds succeeded" msgstr[0] "{} inşa başarılı" msgstr[1] "{} inşa başarılı" -#~ msgid "Cannot find a packageName for {path}!" -#~ msgstr "{path} için bir packageName bulunamıyor!" - -#~ msgid "Cannot find an appid for {path}!" -#~ msgstr "{path} için bir appid bulunamıyor!" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Depodaki paketler için GPG imzaları ekle" @@ -2700,6 +2711,12 @@ msgstr[1] "{} inşa başarılı" #~ msgid "Android Build Tools path '{path}' does not exist!" #~ msgstr "Android Build Tools konumu '{path}' yok!" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "{path} için bir packageName bulunamıyor!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "{path} için bir appid bulunamıyor!" + #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "Temiz güncelleme - önbellekleri kullanmaz, tüm APKları yeniden işler" diff --git a/locale/tzm/LC_MESSAGES/fdroidserver.po b/locale/tzm/LC_MESSAGES/fdroidserver.po index d40cb39b..4b29af0f 100644 --- a/locale/tzm/LC_MESSAGES/fdroidserver.po +++ b/locale/tzm/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.1-681-gc19e8952\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -64,7 +64,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -503,12 +503,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -517,7 +517,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -552,12 +552,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -619,7 +619,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -655,6 +655,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -682,7 +686,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -720,7 +724,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -846,7 +850,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -894,11 +898,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1129,7 +1133,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1191,7 +1195,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1259,6 +1263,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1405,12 +1413,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1504,7 +1512,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1611,11 +1619,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1678,7 +1686,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1690,7 +1698,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1708,14 +1716,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1859,11 +1863,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1895,16 +1894,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1939,7 +1947,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1966,7 +1974,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1987,7 +1995,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2120,7 +2128,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2285,16 +2293,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2426,11 +2434,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2518,15 +2531,19 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2640,7 +2657,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/ug/LC_MESSAGES/fdroidserver.po b/locale/ug/LC_MESSAGES/fdroidserver.po index 3c5fa0cd..c3fa98a6 100644 --- a/locale/ug/LC_MESSAGES/fdroidserver.po +++ b/locale/ug/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2018-06-08 03:44+0000\n" "Last-Translator: ۋولقان \n" "Language-Team: Uyghur \n" @@ -66,7 +66,7 @@ msgstr "" msgid "\"{path}\" contains recent {name} ({version})" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" @@ -505,12 +505,12 @@ msgstr "" msgid "Create skeleton metadata files that are missing" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -519,7 +519,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -554,12 +554,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -621,7 +621,7 @@ msgstr "" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "" @@ -657,6 +657,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -684,7 +688,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -722,7 +726,7 @@ msgstr "" msgid "Failed to align application" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -848,7 +852,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -896,11 +900,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -992,7 +996,6 @@ msgstr "" #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "no \"icon\" in {appid}" msgid "Invalid application ID {appid}" msgstr "{appid} ئىچىدە \"سىنبەلگە\" تېپىلمىدى" @@ -1132,7 +1135,7 @@ msgstr "" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1194,7 +1197,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1262,6 +1265,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1408,12 +1415,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1507,7 +1514,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1614,11 +1621,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "" @@ -1681,7 +1688,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "" @@ -1693,7 +1700,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1711,14 +1718,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1862,11 +1865,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "" @@ -1898,16 +1896,25 @@ msgstr "" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1942,7 +1949,7 @@ msgstr "" msgid "Use date from apk instead of current time for newly added apks" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1969,7 +1976,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "" @@ -1990,7 +1997,7 @@ msgstr "" msgid "Verifying index signature:" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2123,7 +2130,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "" @@ -2288,16 +2295,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "" @@ -2429,11 +2436,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2521,15 +2533,19 @@ msgstr "" msgid "usage: fdroid [-h|--help|--version] []" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2643,7 +2659,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index 166df0ab..c714d9ad 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-08 06:06+0000\n" "Last-Translator: ihor_ck \n" "Language-Team: Ukrainian \n" @@ -78,7 +78,7 @@ msgstr "\"{path}\" містить застарілу {name}{version}" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" містить найновішу {name}{version}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" існує, але s3cmd не встановлений!" @@ -519,12 +519,12 @@ msgstr "Створіть ключ підписування сховищ у сх msgid "Create skeleton metadata files that are missing" msgstr "Створення скелетів файлів метаданих, які відсутні" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "Створено новий контейнер \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Створення \"{path}\" для налаштування s3cmd." @@ -533,7 +533,7 @@ msgstr "Створення \"{path}\" для налаштування s3cmd." msgid "Creating log directory" msgstr "Створення каталогу журналу" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "Створення нового блоку S3: {url}" @@ -568,12 +568,12 @@ msgstr "DEBUG_KEYSTORE не встановлено або значення є н msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "Видалити APKs і/або OBBs без метаданих зі сховища" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "Видалення архіву, сховище завелике ({size} макс. {limit})" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "Видалення історії git-mirror, сховище завелике ({size} макс {limit})" @@ -635,7 +635,7 @@ msgstr "Не робіть нічого пов'язаного з журналам msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "Не оновлюйте сховище, корисне під час тестування створення без підключення до Інтернету" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "Не використовуйте контрольні суми rsync" @@ -671,6 +671,10 @@ msgstr "Дублікат посилання в '{field}': {url}" msgid "Dynamically scan APKs post build" msgstr "Динамічно сканувати створення білдового допису APKs" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -702,7 +706,7 @@ msgstr "" "Введіть шлях до Android SDK (%s) тут:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -740,7 +744,7 @@ msgstr "Не вдалося змінити розмір {path}: {error}" msgid "Failed to align application" msgstr "Не вдалося оптимізувати (align) застосунок" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "Не вдалося створити сигмент S3: {url}" @@ -866,7 +870,7 @@ msgstr "Не знайдено сертифікатів підписування msgid "Found non-file at %s" msgstr "Знайдено не файл у %s" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "Знайдено {apkfilename} у {url}" @@ -914,11 +918,11 @@ msgstr "Не вдалося оновити підмодуль Git" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS потрібно використовувати з URL-адресами Subversion!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "Якщо git mirror стає великим, дозволити видалити архів" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "Якщо це завантаження не вдалося, спробуйте завантажити власноруч на {url}" @@ -1149,7 +1153,7 @@ msgstr "Зробити зупинку створення за винятками msgid "Malformed repository mirrors." msgstr "Несправні дзеркала сховища." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "Несправний шлях serverwebroot:" @@ -1211,7 +1215,7 @@ msgstr "Не має потреби вказувати, що застосунок msgid "No need to specify that the app is for Android" msgstr "Не має потреби вказувати, що застосунок призначено для Android" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "Недостатньо параметрів! Змініть свій config.py, щоб встановити принаймні один з цих:" @@ -1279,6 +1283,10 @@ msgstr "Назва файлу OBB повинна починатися з \"main. msgid "OBB's packagename does not match a supported APK:" msgstr "Назва пакунку OBB не відповідає підтримуваному APK:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1425,12 +1433,12 @@ msgstr "Слід уникати пунктуації" msgid "Push the log to this git remote repository" msgstr "Натисніть вхід цього віддаленого сховища git" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "Оновити двійковий журнал прозорості для {url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "Оприлюднення до {url}" @@ -1524,7 +1532,7 @@ msgstr "Запустити на git сховище, яке не подало з msgid "Run rewritemeta to fix formatting" msgstr "Запустити rewritemeta виправити форматування" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "Запуск першого проходу з вимкненою перевіркою MD5" @@ -1632,11 +1640,11 @@ msgstr "Пропуск {appid}: вимкнено" msgid "Skipping {appid}: no builds specified" msgstr "Пропуск {appid}: жодних збірок не вказано" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "Вкажіть локальну теку, аби синхронізувати сховище у" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "Вкажіть файл ідентифікатора для надання SSH для rsyncing" @@ -1699,7 +1707,7 @@ msgstr "Каталог для запису дзеркала" msgid "The file to be included in the repo (path or glob)" msgstr "Файл, який слід включити до сховища (шлях чи шаблон шляху)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "Підтримуються лише команди 'init' або 'update'" @@ -1711,7 +1719,7 @@ msgstr "Цифровий відбиток сховища не збігаєтьс msgid "The repository's index could not be verified." msgstr "Не вдалося перевірити індекс сховища." -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "Кореневої теки local_copy_dir \"{path}\" не існує!" @@ -1729,14 +1737,10 @@ msgstr "Це застосунки, заархівовані з основног msgid "This repo already has local metadata: %s" msgstr "Сховище вже має локальні метадані: %s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "Для використання awsbucket, awssecretkey та awsaccesskeyid також слід налаштувати config.py!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "Режим перевірки оновлень встановлено, але схоже, що ще не запущено перевірку" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "URL-адреса має починатися з https:// або http://" @@ -1880,11 +1884,6 @@ msgstr "Невикористаний шлях scandelete: %s" msgid "Unused scanignore path: %s" msgstr "Невикористаний шлях scanignore: %s" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Назву застосунку для перевірки оновлень встановлено на відомий ID застосунку — його можна буде вилучити" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "Оновіть інформацію сховища для нових пакетів" @@ -1916,16 +1915,25 @@ msgstr "UpdateCheckData має використовувати URL-адресу H msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData не є дійсною URL-адресою: {url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "Режим перевірки оновлень встановлено, але схоже, що ще не запущено перевірку" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "Назву застосунку для перевірки оновлень встановлено на відомий ID застосунку — його можна буде вилучити" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "Назву застосунку для перевірки оновлень встановлено на відомий ID застосунку — його можна буде вилучити" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "Завантаження {apkfilename} на androidobservatory.org" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "Завантаження {apkfilename} до virustotal" @@ -1960,7 +1968,7 @@ msgstr "Використовуйте дату з APK замість поточн msgid "Use date from apk instead of current time for newly added apks" msgstr "Використовуйте дату з apk, замість поточного часу для нових доданих apks" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "Використання \"{path}\" для налаштування s3cmd." @@ -1987,7 +1995,7 @@ msgstr "Використання androguard від \"{path}\"" msgid "Using existing keystore \"{path}\"" msgstr "Застосування наявного сховища ключів \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "Використовувати s3cmd для синхронізації з: {url}" @@ -2008,7 +2016,7 @@ msgstr "Перевірте цілісність завантажених пак msgid "Verifying index signature:" msgstr "Перевірка підпису індексу:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "Ключ API VirusTotal не може завантажити файли, розмір яких понад 32 МБ, використовуйте {url} для завантаження {path}." @@ -2141,7 +2149,7 @@ msgstr "не вдалося оприлюднити оновлення. Ви вс msgid "cloning {url}" msgstr "клонування {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "команда виконати, 'init' або 'update'" @@ -2308,16 +2316,16 @@ msgstr "недійсне значення conflict_resolution: %r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "неправильний рядок параметра %(option)r: повинен починатися зі знаку %(prefix_chars)r" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir мусить закінчуватися на \"fdroid\", ймовірно, малося на увазі: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir мусить бути абсолютним шляхом!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir мусить бути текою, не файлом!" @@ -2449,11 +2457,16 @@ msgstr "відмовитись від завантаження через неб msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "відмовитись від завантаження через незахищене з'єднання http (користати https чи вказати --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "ruamel.yaml не встановлено, не вдається записати метадані." -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd синхронізувати індекси з {path} до {url} та видалити" @@ -2541,15 +2554,19 @@ msgstr "використання: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "використання: fdroid [-h|--help|--version] <команда> [<аргументи>]" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "Apache libcloud: синхронізація з {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "virustotal.com обмежує швидкість, очікування повторної спроби..." +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2664,7 +2681,7 @@ msgstr "{path}: недійсний підпис \"{pattern}\". Виглядає msgid "{path} is zero size!" msgstr "{path} не має розміру!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "{path} понад 200 МБ, вивантажити власноруч: {url}" @@ -2693,12 +2710,6 @@ msgstr[0] "{} зібрано успішно" msgstr[1] "{} зібрано успішно" msgstr[2] "{} зібрано успішно" -#~ msgid "Cannot find a packageName for {path}!" -#~ msgstr "Неможливо знайти packageName за шляхом {path}!" - -#~ msgid "Cannot find an appid for {path}!" -#~ msgstr "Не вдається знайти appid за шляхом {path}!" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "Додайте підписи gpg для пакетів у репозиторії" @@ -2709,6 +2720,12 @@ msgstr[2] "{} зібрано успішно" #~ msgid "Android Build Tools path '{path}' does not exist!" #~ msgstr "Шлях '{path}' до інструментів створення Android не існує!" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "Неможливо знайти packageName за шляхом {path}!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "Не вдається знайти appid за шляхом {path}!" + #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "Очистити оновлення - не використовує кеш, повторно обробляє всі apks" diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index e7e797b9..6a658488 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-08 06:06+0000\n" "Last-Translator: Eric \n" "Language-Team: Chinese (Simplified) \n" @@ -75,7 +75,7 @@ msgstr "\"{path}\" 包含过时的 {name} ({version})" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" 包含近期的 {name} ({version})" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\"存在,但未安装 s3cmd!" @@ -512,12 +512,12 @@ msgstr "在密钥存储中创建资源库签名密钥" msgid "Create skeleton metadata files that are missing" msgstr "创建缺少的主干元数据文件" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "" @@ -526,7 +526,7 @@ msgstr "" msgid "Creating log directory" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "" @@ -561,12 +561,12 @@ msgstr "" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "从资源库中删除没有元数据的 APK 和 OBB" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -628,7 +628,7 @@ msgstr "请勿做任何日志相关的操作" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "不刷新资源库,便于没有互联网时的内部版本测试" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "请勿使用 rsync 校验和" @@ -664,6 +664,10 @@ msgstr "" msgid "Dynamically scan APKs post build" msgstr "动态扫描已编译的 APKs" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -691,7 +695,7 @@ msgid "" "> " msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -729,7 +733,7 @@ msgstr "" msgid "Failed to align application" msgstr "未能匹配应用程序" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "" @@ -855,7 +859,7 @@ msgstr "" msgid "Found non-file at %s" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "" @@ -903,11 +907,11 @@ msgstr "" msgid "HTTPS must be used with Subversion URLs!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1138,7 +1142,7 @@ msgstr "异常时中止编译" msgid "Malformed repository mirrors." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "" @@ -1200,7 +1204,7 @@ msgstr "" msgid "No need to specify that the app is for Android" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "" @@ -1268,6 +1272,10 @@ msgstr "" msgid "OBB's packagename does not match a supported APK:" msgstr "" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1414,12 +1422,12 @@ msgstr "" msgid "Push the log to this git remote repository" msgstr "拖送日志至 git 远程资源库" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "正推送二进制文件透明日志到{url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "" @@ -1513,7 +1521,7 @@ msgstr "" msgid "Run rewritemeta to fix formatting" msgstr "运行“重写元数据”(rewritemeta)修复格式" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "" @@ -1619,11 +1627,11 @@ msgstr "" msgid "Skipping {appid}: no builds specified" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "指定资源库同步的本地文件夹" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "指定 rsync 同步时 SSH 所用的标识文件" @@ -1686,7 +1694,7 @@ msgstr "" msgid "The file to be included in the repo (path or glob)" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "当前支持的命令只有'init'和'update'" @@ -1698,7 +1706,7 @@ msgstr "" msgid "The repository's index could not be verified." msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "" @@ -1716,14 +1724,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1867,11 +1871,6 @@ msgstr "" msgid "Unused scanignore path: %s" msgstr "" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "更新新包的资源库信息" @@ -1903,16 +1902,25 @@ msgstr "UpdateCheckData必须使用HTTPS URL:{url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "" + #: ../fdroidserver/lint.py msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "" @@ -1947,7 +1955,7 @@ msgstr "对于新添加的 apk 文件,使用来自 apk 文件的时间,而 msgid "Use date from apk instead of current time for newly added apks" msgstr "对于最新添加的 apk,使用来自 apk 的日期,而不是当前时间" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "" @@ -1974,7 +1982,7 @@ msgstr "" msgid "Using existing keystore \"{path}\"" msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "正使用 s3cmd 与 {url} 同步" @@ -1995,7 +2003,7 @@ msgstr "验证已下载包的完整性" msgid "Verifying index signature:" msgstr "验证目录签名中:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2128,7 +2136,7 @@ msgstr "" msgid "cloning {url}" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "执行命令:init 或 update" @@ -2291,16 +2299,16 @@ msgstr "" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir未以“ fdroid”结尾,也许你指的是:“ {path}”" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir必须为绝对路径!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir必须是目录,不能是文件!" @@ -2432,11 +2440,16 @@ msgstr "" msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "" @@ -2524,15 +2537,19 @@ msgstr "用法: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "用法:fdroid [-h|--help|--version] []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "正在用Apache libcloud同步{url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2645,7 +2662,7 @@ msgstr "" msgid "{path} is zero size!" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index ad8fbda6..2aea4a9d 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2020-10-01 12:22+0200\n" +"POT-Creation-Date: 2020-10-21 18:05+0200\n" "PO-Revision-Date: 2020-10-01 09:00+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Chinese (Traditional) \n" @@ -73,7 +73,7 @@ msgstr "\"{path}\" 包含過時的 {name} ({version})" msgid "\"{path}\" contains recent {name} ({version})" msgstr "\"{path}\" 包含近期的 {name} ({version})" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "有 \"{path}\" 存在,但是沒有安裝 s3cmd!" @@ -385,7 +385,6 @@ msgstr "無法讀取 \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py #, fuzzy, python-brace-format -#| msgid "Cannot resolve app id {appid}" msgid "Cannot resolve application ID {appid}" msgstr "無法解析 {appid} id" @@ -515,12 +514,12 @@ msgstr "在金鑰庫中建立一個軟體庫的簽署金鑰" msgid "Create skeleton metadata files that are missing" msgstr "建立缺少的骨幹中介資料檔案" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Created new container \"{name}\"" msgstr "建立新容器 \"{name}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating \"{path}\" for configuring s3cmd." msgstr "正在建立組態 s3cmd 的 \"{path}\"。" @@ -529,7 +528,7 @@ msgstr "正在建立組態 s3cmd 的 \"{path}\"。" msgid "Creating log directory" msgstr "建立日誌目錄" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Creating new S3 bucket: {url}" msgstr "建立新的 S3 bucket:{url}" @@ -564,12 +563,12 @@ msgstr "DEBUG_KEYSTORE 未作設定或是不完整" msgid "Delete APKs and/or OBBs without metadata from the repo" msgstr "從軟體庫刪除缺少中介資料的 APK 和/或 OBB" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" msgstr "" @@ -631,7 +630,7 @@ msgstr "不要做任何與日誌有關的事情" msgid "Don't refresh the repository, useful when testing a build with no internet connection" msgstr "不要更新軟體庫,在沒有網路連線時測試構建很有用" -#: ../fdroidserver/server.py ../fdroidserver/nightly.py +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py #: ../fdroidserver/upload.py msgid "Don't use rsync checksums" msgstr "不使用 rsync 檢驗和" @@ -667,6 +666,10 @@ msgstr "'{field}' 有重複的連結:{url}" msgid "Dynamically scan APKs post build" msgstr "動態掃描建置後的 APK" +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "" + #: ../fdroidserver/mirror.py msgid "" "ERROR: this command should never be used to mirror f-droid.org!\n" @@ -698,7 +701,7 @@ msgstr "" "請在此輸入 Android SDK (%s) 的路徑:\n" "> " -#: ../fdroidserver/server.py ../fdroidserver/checkupdates.py +#: ../fdroidserver/deploy.py ../fdroidserver/checkupdates.py #: ../fdroidserver/upload.py #, python-format msgid "Error while attempting to publish log: %s" @@ -736,7 +739,7 @@ msgstr "{path} 無法調整大小:錯誤訊息 {error}" msgid "Failed to align application" msgstr "校正應用程式失敗" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Failed to create S3 bucket: {url}" msgstr "無法建立 S3 bucket : {url}" @@ -863,7 +866,7 @@ msgstr "軟體庫查無簽名證書。" msgid "Found non-file at %s" msgstr "%s 中找到 non-file" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Found {apkfilename} at {url}" msgstr "複製 {apkfilename} 到 {path}" @@ -911,11 +914,11 @@ msgstr "Git 子模組更新失敗" msgid "HTTPS must be used with Subversion URLs!" msgstr "HTTPS 必須與 Subversion 網址一起使用!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" msgstr "" @@ -1007,7 +1010,6 @@ msgstr "無效的 VercodeOperation:{field}" #: ../fdroidserver/common.py #, fuzzy, python-brace-format -#| msgid "Invalid VercodeOperation: {field}" msgid "Invalid application ID {appid}" msgstr "無效的 VercodeOperation:{field}" @@ -1120,7 +1122,6 @@ msgstr "金鑰庫的簽署金鑰:\t" #: ../fdroidserver/lint.py #, fuzzy, python-brace-format -#| msgid "Last used commit '{commit}' looks like a tag, but Update Check Mode is '{ucm}'" msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" msgstr "最近採用的提交 '{commit}' 似乎是一個標籤,但更新的檢查模式為 '{ucm}'" @@ -1149,7 +1150,7 @@ msgstr "異常時停止做構建" msgid "Malformed repository mirrors." msgstr "軟體庫鏡像異常。" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "Malformed serverwebroot line:" msgstr "異常的 serverwebroot 行:" @@ -1212,7 +1213,7 @@ msgstr "不必要指明的應用程式為自由軟體" msgid "No need to specify that the app is for Android" msgstr "不必指明該應用為 Android 版本" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "No option set! Edit your config.py to set at least one of these:" msgstr "未設定選項!編輯 config.py 檔,其中至少要設定一個:" @@ -1280,6 +1281,10 @@ msgstr "OBB 檔名的前綴須為 \"main.\" 或 \"patch.\":" msgid "OBB's packagename does not match a supported APK:" msgstr "OBB 的套件包名稱與支援的 APK 並不相符:" +#: ../fdroidserver/deploy.py +msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" +msgstr "" + #: ../fdroidserver/common.py #, python-brace-format msgid "Old APK signature failed to verify: {path}" @@ -1427,12 +1432,12 @@ msgstr "標點應予避免" msgid "Push the log to this git remote repository" msgstr "將日誌推送到 git 遠端軟體庫" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing binary transparency log to {url}" msgstr "推二進制的透明日誌到{url}" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Pushing to {url}" msgstr "發佈到 {url}" @@ -1526,7 +1531,7 @@ msgstr "在有未遞交變更的 git 倉庫上執行" msgid "Run rewritemeta to fix formatting" msgstr "執行 rewritemeta 到固定格式" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Running first pass with MD5 checking disabled" msgstr "關閉 MD5 檢查以執行首次通過" @@ -1632,11 +1637,11 @@ msgstr "略過 {appid}:關閉" msgid "Skipping {appid}: no builds specified" msgstr "略過 {appid}:無指定編譯" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify a local folder to sync the repo to" msgstr "指定要將軟體庫同步到本地的資料夾" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "Specify an identity file to provide to SSH for rsyncing" msgstr "指定一個身份檔案以提供給 SSH 進行 rsync" @@ -1699,7 +1704,7 @@ msgstr "寫入目錄的鏡像到" msgid "The file to be included in the repo (path or glob)" msgstr "包含在此軟體庫的檔案 (path 或 glob)" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "The only commands currently supported are 'init' and 'update'" msgstr "目前支援的命令僅 'init' 或 'update'" @@ -1711,7 +1716,7 @@ msgstr "軟體庫的指紋並不相符。" msgid "The repository's index could not be verified." msgstr "軟體庫的索引無法被驗證。" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "The root dir for local_copy_dir \"{path}\" does not exist!" msgstr "local_copy_dir \"{path}\" 根目錄不存在!" @@ -1729,14 +1734,10 @@ msgstr "" msgid "This repo already has local metadata: %s" msgstr "這個軟體庫已有本地的中介資料:%s" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!" msgstr "要使用 awsbucket, awssecretkey 與 awsaccesskeyid 必須在 config.py 進行設定!" -#: ../fdroidserver/lint.py -msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" -msgstr "UpdateCheckMode 已被設定但它似乎尚未曾執行更新檢查" - #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" msgstr "" @@ -1881,13 +1882,6 @@ msgstr "在 %s 未使用的檔案" msgid "Unused scanignore path: %s" msgstr "在 %s 未使用的檔案" -#. Translators: https://developer.android.com/studio/build/application-id -#: ../fdroidserver/lint.py -#, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" -msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "更新 Check Name 被設定成已知的應用 id - 它可以被移除" - #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" msgstr "為新的套件包更新軟體庫資訊" @@ -1919,18 +1913,27 @@ msgstr "UpdateCheckData 必須使用 HTTPS URL:{url}" msgid "UpdateCheckData not a valid URL: {url}" msgstr "UpdateCheckData 不是有效的 URL:{url}" +#: ../fdroidserver/lint.py +msgid "UpdateCheckMode is set but it looks like checkupdates hasn't been run yet" +msgstr "UpdateCheckMode 已被設定但它似乎尚未曾執行更新檢查" + +#. Translators: https://developer.android.com/studio/build/application-id +#: ../fdroidserver/lint.py +#, fuzzy +msgid "UpdateCheckName is set to the known application ID - it can be removed" +msgstr "更新 Check Name 被設定成已知的應用 id - 它可以被移除" + #: ../fdroidserver/lint.py #, fuzzy -#| msgid "Update Check Name is set to the known app id - it can be removed" msgid "UpdateCheckName is set to the known application ID, it can be removed" msgstr "更新 Check Name 被設定成已知的應用 id - 它可以被移除" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "Uploading {apkfilename} to virustotal" msgstr "從緩存讀取 {apkfilename}" @@ -1965,7 +1968,7 @@ msgstr "使用來自 APK 的日期,而不是新增之 APK 目前的時間" msgid "Use date from apk instead of current time for newly added apks" msgstr "新增的 apk 使用日期,來自 apk 而不是目前時間" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using \"{path}\" for configuring s3cmd." msgstr "使用 \"{path}\" 對 s3cmd 組態。" @@ -1992,7 +1995,7 @@ msgstr "使用從「{path}」而來的 androguard" msgid "Using existing keystore \"{path}\"" msgstr "使用現有的金鑰庫 \"{path}\"" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "Using s3cmd to sync with: {url}" msgstr "使用 s3cmd 來同步:{url}" @@ -2013,7 +2016,7 @@ msgstr "驗證下載套裝軟體的完整性" msgid "Verifying index signature:" msgstr "正在驗證索引簽名:" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" @@ -2074,7 +2077,6 @@ msgstr "" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py #, fuzzy -#| msgid "applicationId to check for updates" msgid "application ID of file to operate on" msgstr "以 applicationId 檢查更新" @@ -2082,7 +2084,6 @@ msgstr "以 applicationId 檢查更新" #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py #, fuzzy -#| msgid "applicationId with optional versionCode in the form APPID[:VERCODE]" msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "applicationId 具有任選的 versionCode 在此格式為 APPID [:VERCODE]" @@ -2151,7 +2152,7 @@ msgstr "無法發佈更新,是否正確地設定了佈署金鑰?" msgid "cloning {url}" msgstr "複製 {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "command to execute, either 'init' or 'update'" msgstr "命令執行,'init' 或 'update' 中的任何一個" @@ -2314,16 +2315,16 @@ msgstr "無效 conflict_resolution 值:%r" msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" msgstr "無效的選項字串 %(option)r:必須以字符 %(prefix_chars)r為起頭" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" msgstr "local_copy_dir 未以 \"fdroid\"結尾,也許你指示的是: \"{path}\"" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be an absolute path!" msgstr "local_copy_dir 必須為絕對路徑!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "local_copy_dir must be directory, not a file!" msgstr "local_copy_dir 為目錄,不是檔案!" @@ -2455,11 +2456,16 @@ msgstr "拒絕透過不安全的 HTTP 連線下載 (使用 HTTPS 或指明 --no- msgid "refuse downloading via insecure http connection (use https or specify --no-https-check): {apkfilename}" msgstr "拒絕透過不安全 http 連線下載 (使用 https 或指明 --no-https-check): {apkfilename}" +#: ../fdroidserver/index.py +#, python-format +msgid "repo_icon %s does not exist, generating placeholder." +msgstr "" + #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." msgstr "" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd 同步索引 {path} 到 {url} 並刪除" @@ -2547,15 +2553,19 @@ msgstr "使用: " msgid "usage: fdroid [-h|--help|--version] []" msgstr "用法:fdroid [-h|--help|--version] <命令> []" -#: ../fdroidserver/server.py ../fdroidserver/upload.py +#: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "using Apache libcloud to sync with {url}" msgstr "使用 Apache libcloud 來同步 {url}" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "" +#: ../fdroidserver/update.py +msgid "wiki support is deprecated and will be removed in the next release!" +msgstr "" + #: ../fdroidserver/publish.py #, python-brace-format msgid "{0} app, {1} key aliases" @@ -2579,7 +2589,6 @@ msgstr "{apkfilename} AndroidManifest.xml 有一個無效的日期: " #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} does not have a name! Using package name instead." msgid "{appid} does not have a name! Using application ID instead." msgstr "{appid}沒有名字! 使用套件名代替." @@ -2595,7 +2604,6 @@ msgstr "來自 {path} 的 {appid} 並不是一個有效的 android 套件名稱 #: ../fdroidserver/update.py #, fuzzy, python-brace-format -#| msgid "{appid} from {path} is not a valid Android Package Name!" msgid "{appid} from {path} is not a valid Android application ID!" msgstr "來自 {path} 的 {appid} 並不是一個有效的 android 套件名稱!" @@ -2670,7 +2678,7 @@ msgstr "{path} 有不正確的檔案簽章「{pattern}」,可能是 Janus 漏 msgid "{path} is zero size!" msgstr "{path} 為零尺寸!" -#: ../fdroidserver/server.py +#: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" msgstr "" @@ -2695,12 +2703,6 @@ msgid "{} build succeeded" msgid_plural "{} builds succeeded" msgstr[0] "{} 編譯成功" -#~ msgid "Cannot find a packageName for {path}!" -#~ msgstr "路徑 {path} 找不到套件名稱!" - -#~ msgid "Cannot find an appid for {path}!" -#~ msgstr "找不到 {path} 的 appid!" - #, fuzzy #~ msgid "Add PGP signatures for packages in repo using GnuPG" #~ msgstr "在軟體倉庫中加入套件包的 gpg 簽署" @@ -2708,6 +2710,12 @@ msgstr[0] "{} 編譯成功" #~ msgid "Add gpg signatures for packages in repo" #~ msgstr "在軟體倉庫中加入套件包的 gpg 簽署" +#~ msgid "Cannot find a packageName for {path}!" +#~ msgstr "路徑 {path} 找不到套件名稱!" + +#~ msgid "Cannot find an appid for {path}!" +#~ msgstr "找不到 {path} 的 appid!" + #~ msgid "Clean update - don't uses caches, reprocess all apks" #~ msgstr "清除更新 - 不使用快取,重新處理全部的 apk" From 48e11ea3f1bfd43917ce35e2f83b31e4dd29aab2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 12 Oct 2020 17:39:40 +0200 Subject: [PATCH 0592/2775] run-tests: exit with error if no test APKs are found There must be at least one APK available for this test suite to work, for example, this test: grep -F ' repo/$apk" ln "$f" $1/repo/$apk || \ rsync -axv "$f" $1/repo/$apk # rsync if hard link is not possible + touch $1/.found-apks fi done + if [ ! -e $1/.found-apks ]; then + echo "ERROR: The dir APKDIR must have APKs in it! $APKDIR does not." + exit 1 + fi set -x } From b5cd850abee421ebe65128fac2169ae09edb67d1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 14 Oct 2020 16:43:24 +0200 Subject: [PATCH 0593/2775] apksigner search should use MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION --- fdroidserver/common.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index ee093778..aefe50b0 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -423,7 +423,8 @@ def find_apksigner(): Returns the best version of apksigner following this algorithm: * use config['apksigner'] if set * try to find apksigner in path - * find apksigner in build-tools starting from newest installed going down to MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION + * find apksigner in build-tools starting from newest installed + going down to MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION :return: path to apksigner or None if no version is found """ if set_command_in_config('apksigner'): @@ -434,7 +435,7 @@ def find_apksigner(): for f in sorted(os.listdir(build_tools_path), reverse=True): if not os.path.isdir(os.path.join(build_tools_path, f)): continue - if LooseVersion(f) < LooseVersion(MINIMUM_AAPT_BUILD_TOOLS_VERSION): + if LooseVersion(f) < LooseVersion(MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION): return None if os.path.exists(os.path.join(build_tools_path, f, 'apksigner')): apksigner = os.path.join(build_tools_path, f, 'apksigner') From 27b90a13bff71651e47d95cb35b772842a849889 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 14 Oct 2020 16:49:00 +0200 Subject: [PATCH 0594/2775] remove aapt version of common.is_apk_and_debuggable() --- fdroidserver/common.py | 32 +++++++------------------------- tests/common.TestCase | 23 ++--------------------- 2 files changed, 9 insertions(+), 46 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index aefe50b0..32ca62bc 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2389,19 +2389,15 @@ def ensure_final_value(packageName, arsc, value): return '' -def is_apk_and_debuggable_aapt(apkfile): - p = SdkToolsPopen(['aapt', 'dump', 'xmltree', apkfile, 'AndroidManifest.xml'], - output=False) - if p.returncode != 0: - raise FDroidException(_("Failed to get APK manifest information")) - for line in p.output.splitlines(): - if 'android:debuggable' in line and not line.endswith('0x0'): - return True - return False +def is_apk_and_debuggable(apkfile): + """Returns True if the given file is an APK and is debuggable + Parse only from the APK. -def is_apk_and_debuggable_androguard(apkfile): - """Parse only from the APK""" + :param apkfile: full path to the apk to check""" + + if get_file_extension(apkfile) != 'apk': + return False from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG with ZipFile(apkfile) as apk: with apk.open('AndroidManifest.xml') as manifest: @@ -2423,20 +2419,6 @@ def is_apk_and_debuggable_androguard(apkfile): return False -def is_apk_and_debuggable(apkfile): - """Returns True if the given file is an APK and is debuggable - - :param apkfile: full path to the apk to check""" - - if get_file_extension(apkfile) != 'apk': - return False - - if use_androguard(): - return is_apk_and_debuggable_androguard(apkfile) - else: - return is_apk_and_debuggable_aapt(apkfile) - - def get_apk_id(apkfile): """Extract identification information from APK. diff --git a/tests/common.TestCase b/tests/common.TestCase index ca06de8b..99e10e08 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -148,11 +148,6 @@ class CommonTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config - self._set_build_tools() - try: - config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') - except fdroidserver.exception.FDroidException: - pass # aapt is not required if androguard is present # these are set debuggable testfiles = [] @@ -160,15 +155,8 @@ class CommonTest(unittest.TestCase): testfiles.append(os.path.join(self.basedir, 'urzip-badsig.apk')) testfiles.append(os.path.join(self.basedir, 'urzip-badcert.apk')) for apkfile in testfiles: - debuggable = fdroidserver.common.is_apk_and_debuggable(apkfile) - self.assertTrue(debuggable, + self.assertTrue(fdroidserver.common.is_apk_and_debuggable(apkfile), "debuggable APK state was not properly parsed!") - if 'aapt' in config: - self.assertTrue(fdroidserver.common.is_apk_and_debuggable_aapt(apkfile), - 'aapt parsing missed !') - if fdroidserver.common.use_androguard(): - self.assertTrue(fdroidserver.common.is_apk_and_debuggable_androguard(apkfile), - 'androguard missed !') # these are set NOT debuggable testfiles = [] @@ -176,15 +164,8 @@ class CommonTest(unittest.TestCase): testfiles.append(os.path.join(self.basedir, 'urzip-release-unsigned.apk')) testfiles.append(os.path.join(self.basedir, 'v2.only.sig_2.apk')) for apkfile in testfiles: - debuggable = fdroidserver.common.is_apk_and_debuggable(apkfile) - self.assertFalse(debuggable, + self.assertFalse(fdroidserver.common.is_apk_and_debuggable(apkfile), "debuggable APK state was not properly parsed!") - if 'aapt' in config: - self.assertFalse(fdroidserver.common.is_apk_and_debuggable_aapt(apkfile), - 'aapt parsing missed !') - if fdroidserver.common.use_androguard(): - self.assertFalse(fdroidserver.common.is_apk_and_debuggable_androguard(apkfile), - 'androguard missed !') VALID_STRICT_PACKAGE_NAMES = [ "An.stop", From 8fd7dcd425465806f5f6ad42a4fb496baffe560b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 14 Oct 2020 16:53:59 +0200 Subject: [PATCH 0595/2775] always use androguard version of common.get_apk_id() first This removes the need for common.use_androguard() --- fdroidserver/common.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 32ca62bc..ca88fee2 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2431,15 +2431,12 @@ def get_apk_id(apkfile): :returns: triplet (appid, version code, version name) """ - if use_androguard(): - try: - return get_apk_id_androguard(apkfile) - except zipfile.BadZipFile as e: - logging.error(apkfile + ': ' + str(e)) - if 'aapt' in config: - return get_apk_id_aapt(apkfile) - else: - return get_apk_id_aapt(apkfile) + try: + return get_apk_id_androguard(apkfile) + except zipfile.BadZipFile as e: + logging.error(apkfile + ': ' + str(e)) + if 'aapt' in config: + return get_apk_id_aapt(apkfile) def get_apk_id_androguard(apkfile): From 08931f45240f519f525e299a4b9ac8610e0c8088 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 14 Oct 2020 17:04:26 +0200 Subject: [PATCH 0596/2775] purge update.scan_apk_aapt() androguard v3.3.3+ properly extracts the app name, so this adds the names to the tests. --- fdroidserver/update.py | 85 +---------- .../apk/info.guardianproject.urzip.yaml | 1 + tests/metadata/apk/org.dyndns.fules.ck.yaml | 1 + tests/update.TestCase | 142 +++++++----------- 4 files changed, 60 insertions(+), 169 deletions(-) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 9a2f80d4..a2512db6 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -49,7 +49,6 @@ from . import _ from . import common from . import index from . import metadata -from .common import SdkToolsPopen from .exception import BuildException, FDroidException from PIL import Image, PngImagePlugin @@ -1350,10 +1349,7 @@ def scan_apk(apk_file): 'antiFeatures': set(), } - if common.use_androguard(): - scan_apk_androguard(apk, apk_file) - else: - scan_apk_aapt(apk, apk_file) + scan_apk_androguard(apk, apk_file) if not common.is_valid_package_name(apk['packageName']): raise BuildException(_("{appid} from {path} is not a valid Java Package Name!") @@ -1412,83 +1408,6 @@ def _get_apk_icons_src(apkfile, icon_name): return icons_src -def scan_apk_aapt(apk, apkfile): - p = SdkToolsPopen(['aapt', 'dump', 'badging', apkfile], output=False) - if p.returncode != 0: - if options.delete_unknown: - if os.path.exists(apkfile): - logging.error(_("Failed to get apk information, deleting {path}").format(path=apkfile)) - os.remove(apkfile) - else: - logging.error("Could not find {0} to remove it".format(apkfile)) - else: - logging.error(_("Failed to get apk information, skipping {path}").format(path=apkfile)) - raise BuildException(_("Invalid APK")) - icon_name = None - for line in p.output.splitlines(): - if line.startswith("package:"): - try: - apk['packageName'] = re.match(APK_NAME_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) - except Exception as e: - raise FDroidException("Package matching failed: " + str(e) + "\nLine was: " + line) - elif line.startswith("application:"): - m = re.match(APK_LABEL_ICON_PAT, line) - if m: - apk['name'] = m.group(1) - icon_name = os.path.splitext(os.path.basename(m.group(2)))[0] - elif not apk.get('name') and line.startswith("launchable-activity:"): - # Only use launchable-activity as fallback to application - apk['name'] = re.match(APK_LABEL_ICON_PAT, line).group(1) - elif line.startswith("sdkVersion:"): - m = re.match(APK_SDK_VERSION_PAT, line) - if m is None: - logging.error(line.replace('sdkVersion:', '') - + ' is not a valid minSdkVersion!') - else: - apk['minSdkVersion'] = int(m.group(1)) - elif line.startswith("targetSdkVersion:"): - m = re.match(APK_SDK_VERSION_PAT, line) - if m is None: - logging.error(line.replace('targetSdkVersion:', '') - + ' is not a valid targetSdkVersion!') - else: - apk['targetSdkVersion'] = int(m.group(1)) - elif line.startswith("maxSdkVersion:"): - apk['maxSdkVersion'] = int(re.match(APK_SDK_VERSION_PAT, line).group(1)) - elif line.startswith("native-code:"): - apk['nativecode'] = [] - for arch in line[13:].split(' '): - apk['nativecode'].append(arch[1:-1]) - elif line.startswith('uses-permission:'): - perm_match = re.match(APK_PERMISSION_PAT, line).groups() - permission = UsesPermission( - perm_match[0], # name - None if perm_match[1] is None else int(perm_match[1]), # maxSdkVersion - ) - apk['uses-permission'].append(permission) - - elif line.startswith('uses-permission-sdk-23:'): - perm_match = re.match(APK_PERMISSION_PAT, line).groups() - permission_sdk_23 = UsesPermissionSdk23( - perm_match[0], # name - None if perm_match[1] is None else int(perm_match[1]), # maxSdkVersion - ) - apk['uses-permission-sdk-23'].append(permission_sdk_23) - - elif line.startswith('uses-feature:'): - feature = re.match(APK_FEATURE_PAT, line).group(1) - # Filter out this, it's only added with the latest SDK tools and - # causes problems for lots of apps. - if feature != "android.hardware.screen.portrait" \ - and feature != "android.hardware.screen.landscape": - if feature.startswith("android.feature."): - feature = feature[16:] - apk['features'].add(feature) - apk['icons_src'] = _get_apk_icons_src(apkfile, icon_name) - - def _sanitize_sdk_version(value): """Sanitize the raw values from androguard to handle bad values @@ -1529,8 +1448,6 @@ def scan_apk_androguard(apk, apkfile): logging.error(_("Failed to get apk information, skipping {path}") .format(path=apkfile)) raise BuildException(_("Invalid APK")) - except ImportError: - raise FDroidException("androguard library is not installed and aapt not present") except FileNotFoundError: logging.error(_("Could not open apk file for analysis")) raise BuildException(_("Invalid APK")) diff --git a/tests/metadata/apk/info.guardianproject.urzip.yaml b/tests/metadata/apk/info.guardianproject.urzip.yaml index f2e17651..4632c314 100644 --- a/tests/metadata/apk/info.guardianproject.urzip.yaml +++ b/tests/metadata/apk/info.guardianproject.urzip.yaml @@ -10,6 +10,7 @@ icons_src: '-1': res/drawable/ic_launcher.png '160': res/drawable/ic_launcher.png minSdkVersion: 4 +name: urzip packageName: info.guardianproject.urzip sig: e0ecb5fc2d63088e4a07ae410a127722 signer: 7eabd8c15de883d1e82b5df2fd4f7f769e498078e9ad6dc901f0e96db77ceac3 diff --git a/tests/metadata/apk/org.dyndns.fules.ck.yaml b/tests/metadata/apk/org.dyndns.fules.ck.yaml index 76f7cacb..23a0325f 100644 --- a/tests/metadata/apk/org.dyndns.fules.ck.yaml +++ b/tests/metadata/apk/org.dyndns.fules.ck.yaml @@ -14,6 +14,7 @@ icons_src: '160': res/drawable-mdpi-v4/icon_launcher.png '240': res/drawable-hdpi-v4/icon_launcher.png minSdkVersion: 7 +name: Compass Keyboard nativecode: - arm64-v8a - armeabi diff --git a/tests/update.TestCase b/tests/update.TestCase index 4f9c3f3f..30a93f1f 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -458,98 +458,72 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.config = config fdroidserver.update.config = config os.chdir(os.path.join(localmodule, 'tests')) - try: - config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') - except fdroidserver.exception.FDroidException: - pass # aapt is not required if androguard is present - for use_androguard in (True, False): - if use_androguard: - try: - import androguard - androguard - - def func(): - return True - fdroidserver.common.use_androguard = func - except ImportError: - continue - else: - if 'aapt' in config: - def func(): - return False - fdroidserver.common.use_androguard = func - else: - continue - - print('USE_ANDROGUARD', use_androguard) - - apksigner = fdroidserver.common.find_apksigner() - if apksigner: - if use_androguard: # v2 parsing needs both - config['apksigner'] = apksigner - apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') - self.assertIsNone(apk_info.get('maxSdkVersion')) - self.assertEqual(apk_info.get('versionName'), 'v2-only') - self.assertEqual(apk_info.get('versionCode'), 2) - else: - print('WARNING: skipping v2-only test since apksigner cannot be found') - apk_info = fdroidserver.update.scan_apk('repo/v1.v2.sig_1020.apk') + apksigner = fdroidserver.common.find_apksigner() + if apksigner: + config['apksigner'] = apksigner + apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') self.assertIsNone(apk_info.get('maxSdkVersion')) - self.assertEqual(apk_info.get('versionName'), 'v1+2') - self.assertEqual(apk_info.get('versionCode'), 1020) + self.assertEqual(apk_info.get('versionName'), 'v2-only') + self.assertEqual(apk_info.get('versionCode'), 2) + else: + print('WARNING: skipping v2-only test since apksigner cannot be found') + apk_info = fdroidserver.update.scan_apk('repo/v1.v2.sig_1020.apk') + self.assertIsNone(apk_info.get('maxSdkVersion')) + self.assertEqual(apk_info.get('versionName'), 'v1+2') + self.assertEqual(apk_info.get('versionCode'), 1020) - apk_info = fdroidserver.update.scan_apk('repo/souch.smsbypass_9.apk') - self.assertIsNone(apk_info.get('maxSdkVersion')) - self.assertEqual(apk_info.get('versionName'), '0.9') + apk_info = fdroidserver.update.scan_apk('repo/souch.smsbypass_9.apk') + self.assertIsNone(apk_info.get('maxSdkVersion')) + self.assertEqual(apk_info.get('versionName'), '0.9') - apk_info = fdroidserver.update.scan_apk('repo/duplicate.permisssions_9999999.apk') - self.assertEqual(apk_info.get('versionName'), '') - self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_launcher.png', - '-1': 'res/drawable/ic_launcher.png'}) + apk_info = fdroidserver.update.scan_apk('repo/duplicate.permisssions_9999999.apk') + self.assertEqual(apk_info.get('versionName'), '') + self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_launcher.png', + '-1': 'res/drawable/ic_launcher.png'}) - apk_info = fdroidserver.update.scan_apk('org.dyndns.fules.ck_20.apk') - self.assertEqual(apk_info['icons_src'], {'240': 'res/drawable-hdpi-v4/icon_launcher.png', - '120': 'res/drawable-ldpi-v4/icon_launcher.png', - '160': 'res/drawable-mdpi-v4/icon_launcher.png', - '-1': 'res/drawable-mdpi-v4/icon_launcher.png'}) - self.assertEqual(apk_info['icons'], {}) - self.assertEqual(apk_info['features'], []) - self.assertEqual(apk_info['antiFeatures'], set()) - self.assertEqual(apk_info['versionName'], 'v1.6pre2') - self.assertEqual(apk_info['hash'], - '897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8') - self.assertEqual(apk_info['packageName'], 'org.dyndns.fules.ck') - self.assertEqual(apk_info['versionCode'], 20) - self.assertEqual(apk_info['size'], 132453) - self.assertEqual(apk_info['nativecode'], - ['arm64-v8a', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'x86', 'x86_64']) - self.assertEqual(apk_info['minSdkVersion'], 7) - self.assertEqual(apk_info['sig'], '9bf7a6a67f95688daec75eab4b1436ac') - self.assertEqual(apk_info['hashType'], 'sha256') - self.assertEqual(apk_info['targetSdkVersion'], 8) + apk_info = fdroidserver.update.scan_apk('org.dyndns.fules.ck_20.apk') + self.assertEqual(apk_info['icons_src'], {'240': 'res/drawable-hdpi-v4/icon_launcher.png', + '120': 'res/drawable-ldpi-v4/icon_launcher.png', + '160': 'res/drawable-mdpi-v4/icon_launcher.png', + '-1': 'res/drawable-mdpi-v4/icon_launcher.png'}) + self.assertEqual(apk_info['icons'], {}) + self.assertEqual(apk_info['features'], []) + self.assertEqual(apk_info['antiFeatures'], set()) + self.assertEqual(apk_info['versionName'], 'v1.6pre2') + self.assertEqual(apk_info['hash'], + '897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8') + self.assertEqual(apk_info['packageName'], 'org.dyndns.fules.ck') + self.assertEqual(apk_info['versionCode'], 20) + self.assertEqual(apk_info['size'], 132453) + self.assertEqual(apk_info['nativecode'], + ['arm64-v8a', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'x86', 'x86_64']) + self.assertEqual(apk_info['minSdkVersion'], 7) + self.assertEqual(apk_info['sig'], '9bf7a6a67f95688daec75eab4b1436ac') + self.assertEqual(apk_info['hashType'], 'sha256') + self.assertEqual(apk_info['targetSdkVersion'], 8) - apk_info = fdroidserver.update.scan_apk('org.bitbucket.tickytacky.mirrormirror_4.apk') - self.assertEqual(apk_info.get('versionName'), '1.0.3') - self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable-mdpi/mirror.png', - '-1': 'res/drawable-mdpi/mirror.png'}) + apk_info = fdroidserver.update.scan_apk('org.bitbucket.tickytacky.mirrormirror_4.apk') + self.assertEqual(apk_info.get('versionName'), '1.0.3') + self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable-mdpi/mirror.png', + '-1': 'res/drawable-mdpi/mirror.png'}) - apk_info = fdroidserver.update.scan_apk('repo/info.zwanenburg.caffeinetile_4.apk') - self.assertEqual(apk_info.get('versionName'), '1.3') - self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_coffee_on.xml', - '-1': 'res/drawable/ic_coffee_on.xml'}) + apk_info = fdroidserver.update.scan_apk('repo/info.zwanenburg.caffeinetile_4.apk') + self.assertEqual(apk_info.get('versionName'), '1.3') + self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_coffee_on.xml', + '-1': 'res/drawable/ic_coffee_on.xml'}) - apk_info = fdroidserver.update.scan_apk('repo/com.politedroid_6.apk') - self.assertEqual(apk_info.get('versionName'), '1.5') - self.assertEqual(apk_info['icons_src'], {'120': 'res/drawable-ldpi-v4/icon.png', - '160': 'res/drawable-mdpi-v4/icon.png', - '240': 'res/drawable-hdpi-v4/icon.png', - '320': 'res/drawable-xhdpi-v4/icon.png', - '-1': 'res/drawable-mdpi-v4/icon.png'}) + apk_info = fdroidserver.update.scan_apk('repo/com.politedroid_6.apk') + self.assertEqual(apk_info.get('versionName'), '1.5') + self.assertEqual(apk_info['icons_src'], {'120': 'res/drawable-ldpi-v4/icon.png', + '160': 'res/drawable-mdpi-v4/icon.png', + '240': 'res/drawable-hdpi-v4/icon.png', + '320': 'res/drawable-xhdpi-v4/icon.png', + '-1': 'res/drawable-mdpi-v4/icon.png'}) - apk_info = fdroidserver.update.scan_apk('SpeedoMeterApp.main_1.apk') - self.assertEqual(apk_info.get('versionName'), '1.0') - self.assertEqual(apk_info['icons_src'], {}) + apk_info = fdroidserver.update.scan_apk('SpeedoMeterApp.main_1.apk') + self.assertEqual(apk_info.get('versionName'), '1.0') + self.assertEqual(apk_info['icons_src'], {}) def test_scan_apk_no_min_target(self): config = dict() @@ -627,8 +601,6 @@ class UpdateTest(unittest.TestCase): # Don't care about the date added to the repo and relative apkName del apk['added'] del apk['apkName'] - # avoid AAPT application name bug - del apk['name'] # ensure that icons have been extracted properly if apkName == '../urzip.apk': From 501a33f117fd1fbefc5280bc692d4b949cb418a0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 14 Oct 2020 18:39:51 +0200 Subject: [PATCH 0597/2775] remove unused helper function --- tests/build.TestCase | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/build.TestCase b/tests/build.TestCase index decae7ab..ea1af963 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -43,13 +43,6 @@ class BuildTest(unittest.TestCase): print('no build-tools found: ' + build_tools) return False - def _find_all(self): - for cmd in ('aapt', 'adb', 'android', 'zipalign'): - path = fdroidserver.common.find_sdk_tools_cmd(cmd) - if path is not None: - self.assertTrue(os.path.exists(path)) - self.assertTrue(os.path.isfile(path)) - def setUp(self): logging.basicConfig(level=logging.DEBUG) self.basedir = os.path.join(localmodule, 'tests') From 989159ef09a928b98613055627b752231f55f077 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 14 Oct 2020 18:44:25 +0200 Subject: [PATCH 0598/2775] require build-tools that fully supports apksigner --- fdroidserver/common.py | 3 ++- tests/common.TestCase | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index ca88fee2..df9ffe25 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -114,7 +114,7 @@ default_config = { 'r16b': None, }, 'cachedir': os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), - 'build_tools': MINIMUM_AAPT_BUILD_TOOLS_VERSION, + 'build_tools': MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION, 'java_paths': None, 'scan_binary': False, 'ant': "ant", @@ -508,6 +508,7 @@ def test_aapt_version(aapt): def test_sdk_exists(thisconfig): if 'sdk_path' not in thisconfig: + # TODO convert this to apksigner once it is required if 'aapt' in thisconfig and os.path.isfile(thisconfig['aapt']): test_aapt_version(thisconfig['aapt']) return True diff --git a/tests/common.TestCase b/tests/common.TestCase index 99e10e08..4e887d3c 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -78,7 +78,7 @@ class CommonTest(unittest.TestCase): for f in sorted(os.listdir(build_tools), reverse=True): versioned = os.path.join(build_tools, f) if os.path.isdir(versioned) \ - and os.path.isfile(os.path.join(versioned, 'aapt')): + and os.path.isfile(os.path.join(versioned, 'apksigner')): fdroidserver.common.config['build_tools'] = versioned break return True From aa80662642ce6fb71db1ea7369b50f6fe149ffde Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 21 Oct 2020 15:16:12 +0200 Subject: [PATCH 0599/2775] init: enable apksigner by default so v2/v3 APK signatures validate Ultimately we want to get to using apksigner by default everywhere, this gets us closer to that by setting up all new repos to use apksigner by default in the config.py --- fdroidserver/init.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fdroidserver/init.py b/fdroidserver/init.py index 20596130..64f63f73 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -162,6 +162,10 @@ def main(): # now that we have a local config.py, read configuration... config = common.read_config(options) + # enable apksigner by default so v2/v3 APK signatures validate + if common.find_apksigner() is not None: + test_config['apksigner'] = common.find_apksigner() + # the NDK is optional and there may be multiple versions of it, so it's # left for the user to configure From fd41b70e2747d83b7e7437e8fca70eddf818cbf7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 21 Oct 2020 19:51:32 +0200 Subject: [PATCH 0600/2775] purge common.use_androguard, it is now used by default Up until now, the buildserver has not included androguard. Since a good version of androguard (v3.3.3+) is included in stretch-backports and the buildserver is already setup to use stretch-backports, this sets up the buildserver with androguard. closes #627 --- buildserver/provision-apt-get-install | 2 + fdroidserver/init.py | 97 ++++++++++----------------- tests/common.TestCase | 9 ++- 3 files changed, 41 insertions(+), 67 deletions(-) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index de8dd3fb..5ef8d1b3 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -49,6 +49,7 @@ apt-get upgrade --download-only apt-get upgrade packages=" + androguard/stretch-backports ant asn1c ant-contrib @@ -99,6 +100,7 @@ packages=" python-magic python-pip python-setuptools + python3-asn1crypto/stretch-backports python3-defusedxml python3-git python3-gitdb diff --git a/fdroidserver/init.py b/fdroidserver/init.py index 64f63f73..f53057a0 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -75,46 +75,44 @@ def main(): # in ANDROID_HOME if that exists, otherwise None if options.android_home is not None: test_config['sdk_path'] = options.android_home - elif common.use_androguard(): - pass elif not common.test_sdk_exists(test_config): - if os.path.isfile('/usr/bin/aapt'): - # remove sdk_path and build_tools, they are not required - test_config.pop('sdk_path', None) - test_config.pop('build_tools', None) - # make sure at least aapt is found, since this can't do anything without it - test_config['aapt'] = common.find_sdk_tools_cmd('aapt') + # if neither --android-home nor the default sdk_path + # exist, prompt the user using platform-specific default + # and if the user leaves it blank, ignore and move on. + default_sdk_path = '' + if sys.platform == 'win32' or sys.platform == 'cygwin': + p = os.path.join(os.getenv('USERPROFILE'), + 'AppData', 'Local', 'Android', 'android-sdk') + elif sys.platform == 'darwin': + # on OSX, Homebrew is common and has an easy path to detect + p = '/usr/local/opt/android-sdk' + elif os.path.isdir('/usr/lib/android-sdk'): + # if the Debian packages are installed, suggest them + p = '/usr/lib/android-sdk' else: - # if neither --android-home nor the default sdk_path - # exist, prompt the user using platform-specific default - default_sdk_path = '/opt/android-sdk' - if sys.platform == 'win32' or sys.platform == 'cygwin': - p = os.path.join(os.getenv('USERPROFILE'), - 'AppData', 'Local', 'Android', 'android-sdk') - elif sys.platform == 'darwin': - # on OSX, Homebrew is common and has an easy path to detect - p = '/usr/local/opt/android-sdk' - else: - # if the Debian packages are installed, suggest them - p = '/usr/lib/android-sdk' - if os.path.exists(p): - default_sdk_path = p + p = '/opt/android-sdk' + if os.path.exists(p): + default_sdk_path = p - while not options.no_prompt: - try: - s = input(_('Enter the path to the Android SDK (%s) here:\n> ') % default_sdk_path) - except KeyboardInterrupt: - print('') - sys.exit(1) - if re.match(r'^\s*$', s) is not None: - test_config['sdk_path'] = default_sdk_path - else: - test_config['sdk_path'] = s - if common.test_sdk_exists(test_config): - break - if (options.android_home is not None or not common.use_androguard()) \ - and not common.test_sdk_exists(test_config): - raise FDroidException("Android SDK not found.") + while not options.no_prompt: + try: + s = input(_('Enter the path to the Android SDK (%s) here:\n> ') % default_sdk_path) + except KeyboardInterrupt: + print('') + sys.exit(1) + if re.match(r'^\s*$', s) is not None: + test_config['sdk_path'] = default_sdk_path + else: + test_config['sdk_path'] = s + if not default_sdk_path: + del(test_config['sdk_path']) + break + if common.test_sdk_exists(test_config): + break + + if test_config.get('sdk_path') and not common.test_sdk_exists(test_config): + raise FDroidException(_("Android SDK not found at {path}!") + .format(path=test_config['sdk_path'])) if not os.path.exists('config.py'): # 'metadata' and 'tmp' are created in fdroid @@ -134,31 +132,6 @@ def main(): logging.info('Try running `fdroid init` in an empty directory.') raise FDroidException('Repository already exists.') - if common.use_androguard(): - pass - elif '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 - build_tools = os.path.join(test_config['sdk_path'], 'build-tools') - aaptdirs = [] - aaptdirs.append(os.path.join(build_tools, test_config['build_tools'])) - aaptdirs.append(build_tools) - for f in os.listdir(build_tools): - if os.path.isdir(os.path.join(build_tools, f)): - aaptdirs.append(os.path.join(build_tools, f)) - for d in sorted(aaptdirs, reverse=True): - if os.path.isfile(os.path.join(d, 'aapt')): - aapt = os.path.join(d, 'aapt') - break - if aapt and os.path.isfile(aapt): - dirname = os.path.basename(os.path.dirname(aapt)) - if dirname == 'build-tools': - # this is the old layout, before versioned build-tools - test_config['build_tools'] = '' - else: - test_config['build_tools'] = dirname - common.write_to_config(test_config, 'build_tools') - common.ensure_build_tools_exists(test_config) - # now that we have a local config.py, read configuration... config = common.read_config(options) diff --git a/tests/common.TestCase b/tests/common.TestCase index 4e887d3c..ff7befb1 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -746,16 +746,15 @@ class CommonTest(unittest.TestCase): ('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk', 'info.guardianproject.urzip', '100', '0.1'), ] for apkfilename, appid, versionCode, versionName in testcases: + a, vc, vn = fdroidserver.common.get_apk_id(apkfilename) + self.assertEqual(appid, a, 'androguard appid parsing failed for ' + apkfilename) + self.assertEqual(versionName, vn, 'androguard versionName parsing failed for ' + apkfilename) + self.assertEqual(versionCode, vc, 'androguard versionCode parsing failed for ' + apkfilename) if 'aapt' in config: a, vc, vn = fdroidserver.common.get_apk_id_aapt(apkfilename) self.assertEqual(appid, a, 'aapt appid parsing failed for ' + apkfilename) self.assertEqual(versionCode, vc, 'aapt versionCode parsing failed for ' + apkfilename) self.assertEqual(versionName, vn, 'aapt versionName parsing failed for ' + apkfilename) - if fdroidserver.common.use_androguard(): - a, vc, vn = fdroidserver.common.get_apk_id(apkfilename) - self.assertEqual(appid, a, 'androguard appid parsing failed for ' + apkfilename) - self.assertEqual(versionName, vn, 'androguard versionName parsing failed for ' + apkfilename) - self.assertEqual(versionCode, vc, 'androguard versionCode parsing failed for ' + apkfilename) with self.assertRaises(FDroidException): fdroidserver.common.get_apk_id('nope') From d3d48dba5eb3484eb17955f21a349225ad80597a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 4 Sep 2018 11:03:05 +0200 Subject: [PATCH 0601/2775] add config.yml as default config file format None of the config options in config.py require Python code. YAML is a common config data format, and it is also used for build metadata. It is also much safer to use since it can be pure data, without anything executable in it. This also reduces the attack surface of the fdroid process by eliminating a guaranteed place to write to get code executed. With config.py, any exploit that can get local write access can turn that into execute access by writing to the config.py, then cleaning up after itself once it has what it needs. Switching to YAML removes that vector entirely. Also, this removes the config_file argument. It is not used in either fdroidserver or repomaker. Also, it probably wouldn't work since so much of the code assumes that the current working dir is the root of the repo. --- fdroidserver/common.py | 36 +++++++++++++++++------ tests/common.TestCase | 65 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 8 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index df9ffe25..48434581 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -39,6 +39,7 @@ import socket import base64 import urllib.parse import urllib.request +import yaml import zipfile import tempfile import json @@ -284,14 +285,18 @@ def regsub_file(pattern, repl, path): f.write(text) -def read_config(opts, config_file='config.py'): +def read_config(opts): """Read the repository config The config is read from config_file, which is in the current directory when any of the repo management commands are used. If - there is a local metadata file in the git repo, then config.py is + there is a local metadata file in the git repo, then the config is not required, just use defaults. + config.yml is the preferred form because no code is executed when + reading it. config.py is deprecated and supported for backwards + compatibility. + """ global config, options @@ -301,12 +306,23 @@ def read_config(opts, config_file='config.py'): options = opts config = {} + config_file = 'config.yml' + old_config_file = 'config.py' - if os.path.isfile(config_file): + if os.path.exists(config_file) and os.path.exists(old_config_file): + logging.error(_("""Conflicting config files! Using {newfile}, ignoring {oldfile}!""") + .format(oldfile=old_config_file, newfile=config_file)) + + if os.path.exists(config_file): logging.debug(_("Reading '{config_file}'").format(config_file=config_file)) - with io.open(config_file, "rb") as f: - code = compile(f.read(), config_file, 'exec') - exec(code, None, config) # nosec TODO switch to YAML file + with open(config_file) as fp: + config = yaml.safe_load(fp) + elif os.path.exists(old_config_file): + logging.warning(_("""{oldfile} is deprecated, use {newfile}""") + .format(oldfile=old_config_file, newfile=config_file)) + with io.open(old_config_file, "rb") as fp: + code = compile(fp.read(), old_config_file, 'exec') + exec(code, None, config) # nosec TODO automatically migrate else: logging.warning(_("No 'config.py' found, using defaults.")) @@ -329,10 +345,14 @@ def read_config(opts, config_file='config.py'): '-providerArg', 'opensc-fdroid.cfg'] if any(k in config for k in ["keystore", "keystorepass", "keypass"]): - st = os.stat(config_file) + if os.path.exists(config_file): + f = config_file + elif os.path.exists(old_config_file): + f = old_config_file + st = os.stat(f) if st.st_mode & stat.S_IRWXG or st.st_mode & stat.S_IRWXO: logging.warning(_("unsafe permissions on '{config_file}' (should be 0600)!") - .format(config_file=config_file)) + .format(config_file=f)) fill_config_defaults(config) diff --git a/tests/common.TestCase b/tests/common.TestCase index ff7befb1..b49ba10e 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -47,6 +47,7 @@ class CommonTest(unittest.TestCase): if not os.path.exists(self.tmpdir): os.makedirs(self.tmpdir) os.chdir(self.basedir) + fdroidserver.common.config = None def test_parse_human_readable_size(self): for k, v in ((9827, 9827), (123.456, 123), ('123b', 123), ('1.2', 1), @@ -1409,6 +1410,70 @@ class CommonTest(unittest.TestCase): self.assertIsNotNone(result) self.assertNotEqual(result, '') + def test_with_no_config(self): + """It should set defaults if no config file is found""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + self.assertFalse(os.path.exists('config.yml')) + self.assertFalse(os.path.exists('config.py')) + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual(None, config.get('apksigner')) + self.assertIsNotNone(config.get('char_limits')) + + def test_with_config_yml(self): + """Make sure it is possible to use config.yml alone.""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + with open('config.yml', 'w') as fp: + fp.write('apksigner: yml') + self.assertTrue(os.path.exists('config.yml')) + self.assertFalse(os.path.exists('config.py')) + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual('yml', config.get('apksigner')) + + def test_with_config_py(self): + """Make sure it is still possible to use config.py alone.""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + with open('config.py', 'w') as fp: + fp.write('apksigner = "py"') + self.assertFalse(os.path.exists('config.yml')) + self.assertTrue(os.path.exists('config.py')) + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual("py", config.get('apksigner')) + + def test_config_perm_warning(self): + """Exercise the code path that issues a warning about unsafe permissions.""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + with open('config.yml', 'w') as fp: + fp.write('keystore: foo.jks') + self.assertTrue(os.path.exists(fp.name)) + os.chmod(fp.name, 0o666) + fdroidserver.common.read_config(fdroidserver.common.options) + os.remove(fp.name) + fdroidserver.common.config = None + + with open('config.py', 'w') as fp: + fp.write('keystore = "foo.jks"') + self.assertTrue(os.path.exists(fp.name)) + os.chmod(fp.name, 0o666) + fdroidserver.common.read_config(fdroidserver.common.options) + + def test_with_both_config_yml_py(self): + """If config.yml and config.py are present, config.py should be ignored.""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + with open('config.yml', 'w') as fp: + fp.write('apksigner: yml') + with open('config.py', 'w') as fp: + fp.write('apksigner = "py"') + self.assertTrue(os.path.exists('config.yml')) + self.assertTrue(os.path.exists('config.py')) + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual('yml', config.get('apksigner')) + + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) From 2d115135f7468f344f025fe10343435d3824a837 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 22 Oct 2020 19:08:08 +0200 Subject: [PATCH 0602/2775] support env vars in config.yml: awsaccesskeyid: {env: AWS_KEY} --- fdroidserver/common.py | 14 ++++++++++++++ tests/common.TestCase | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 48434581..9736edf2 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -388,6 +388,20 @@ def read_config(opts): limit = config['git_mirror_size_limit'] config['git_mirror_size_limit'] = parse_human_readable_size(limit) + for configname, dictvalue in config.items(): + if isinstance(dictvalue, dict) \ + and configname not in ('ndk_paths', 'java_paths', 'char_limits', 'keyaliases'): + for k, v in dictvalue.items(): + if k == 'env': + env = os.getenv(v) + config[configname] = env + if not env: + logging.error(_('Environment variable {var} from {configname} is not set!') + .format(var=k, configname=configname)) + else: + logging.error(_('Unknown entry {key} in {configname}') + .format(key=k, configname=configname)) + return config diff --git a/tests/common.TestCase b/tests/common.TestCase index b49ba10e..a12ec6a6 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1431,6 +1431,18 @@ class CommonTest(unittest.TestCase): config = fdroidserver.common.read_config(fdroidserver.common.options) self.assertEqual('yml', config.get('apksigner')) + def test_with_config_yml_with_env_var(self): + """Make sure it is possible to use config.yml alone.""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + os.environ['SECRET'] = 'mysecretpassword' + with open('config.yml', 'w') as fp: + fp.write("""keypass: {'env': 'SECRET'}""") + self.assertTrue(os.path.exists('config.yml')) + self.assertFalse(os.path.exists('config.py')) + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual(os.getenv('SECRET', 'fail'), config.get('keypass')) + def test_with_config_py(self): """Make sure it is still possible to use config.py alone.""" testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) From 4bbbf3551153ba8a7d6a36ab24390c0d946b5734 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 22 Oct 2020 23:00:58 +0200 Subject: [PATCH 0603/2775] support both config.py and config.yml in common.write_to_config() --- fdroidserver/common.py | 26 +++++++++++++++++++------- tests/common.TestCase | 31 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 9736edf2..74d0b987 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3552,19 +3552,24 @@ def load_stats_fdroid_signing_key_fingerprints(): def write_to_config(thisconfig, key, value=None, config_file=None): - '''write a key/value to the local config.py + '''write a key/value to the local config.yml or config.py NOTE: only supports writing string variables. :param thisconfig: config dictionary - :param key: variable name in config.py to be overwritten/added + :param key: variable name in config to be overwritten/added :param value: optional value to be written, instead of fetched from 'thisconfig' dictionary. ''' if value is None: origkey = key + '_orig' value = thisconfig[origkey] if origkey in thisconfig else thisconfig[key] - cfg = config_file if config_file else 'config.py' + if config_file: + cfg = config_file + elif os.path.exists('config.py') and not os.path.exists('config.yml'): + cfg = 'config.py' + else: + cfg = 'config.yml' # load config file, create one if it doesn't exist if not os.path.exists(cfg): @@ -3580,10 +3585,17 @@ def write_to_config(thisconfig, key, value=None, config_file=None): # regex for finding and replacing python string variable # definitions/initializations - pattern = re.compile(r'^[\s#]*' + key + r'\s*=\s*"[^"]*"') - repl = key + ' = "' + value + '"' - pattern2 = re.compile(r'^[\s#]*' + key + r"\s*=\s*'[^']*'") - repl2 = key + " = '" + value + "'" + if cfg.endswith('.py'): + pattern = re.compile(r'^[\s#]*' + key + r'\s*=\s*"[^"]*"') + repl = key + ' = "' + value + '"' + pattern2 = re.compile(r'^[\s#]*' + key + r"\s*=\s*'[^']*'") + repl2 = key + " = '" + value + "'" + else: + # assume .yml as default + pattern = re.compile(r'^[\s#]*' + key + r':.*') + repl = yaml.dump({key: value}, default_flow_style=False) + pattern2 = pattern + repl2 = repl # If we replaced this line once, we make sure won't be a # second instance of this line for this key in the document. diff --git a/tests/common.TestCase b/tests/common.TestCase index a12ec6a6..d8bc6c6b 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1485,6 +1485,37 @@ class CommonTest(unittest.TestCase): config = fdroidserver.common.read_config(fdroidserver.common.options) self.assertEqual('yml', config.get('apksigner')) + def test_write_to_config_yml(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + with open('config.yml', 'w') as fp: + fp.write('apksigner: yml') + self.assertTrue(os.path.exists(fp.name)) + self.assertFalse(os.path.exists('config.py')) + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertFalse('keypass' in config) + self.assertEqual('yml', config.get('apksigner')) + fdroidserver.common.write_to_config(config, 'keypass', 'mysecretpassword') + with open(fp.name) as fp: + print(fp.read()) + fdroidserver.common.config = None + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual('mysecretpassword', config['keypass']) + + def test_write_to_config_py(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + with open('config.py', 'w') as fp: + fp.write('apksigner = "py"') + self.assertTrue(os.path.exists(fp.name)) + self.assertFalse(os.path.exists('config.yml')) + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertFalse('keypass' in config) + self.assertEqual('py', config.get('apksigner')) + fdroidserver.common.write_to_config(config, 'keypass', 'mysecretpassword') + fdroidserver.common.config = None + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual('mysecretpassword', config['keypass']) if __name__ == "__main__": From a9fdb5b401593a1eeba9af604588f53a551b52d7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 22 Oct 2020 23:34:47 +0200 Subject: [PATCH 0604/2775] init: switch to config.yml as the default format --- .gitignore | 4 +- MANIFEST.in | 4 +- buildserver/config.buildserver.py | 19 --- buildserver/config.buildserver.yml | 19 +++ examples/{config.py => config.yml} | 249 +++++++++++++++-------------- fdroidserver/build.py | 4 +- fdroidserver/common.py | 29 ++-- fdroidserver/deploy.py | 4 +- fdroidserver/init.py | 27 ++-- hooks/pre-commit | 14 +- jenkins-build-all | 16 +- jenkins-setup-build-environment | 2 +- jenkins-test | 20 +-- setup.py | 2 +- tests/common.TestCase | 19 +++ tests/init.TestCase | 62 +++++++ tests/run-tests | 90 +++++------ 17 files changed, 344 insertions(+), 240 deletions(-) delete mode 100644 buildserver/config.buildserver.py create mode 100644 buildserver/config.buildserver.yml rename examples/{config.py => config.yml} (73%) create mode 100755 tests/init.TestCase diff --git a/.gitignore b/.gitignore index c192310b..223807b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -/config.py -/makebs.config.py *~ *.pyc *.class @@ -28,9 +26,11 @@ tmp/ # files used in manual testing /config.py +/config.yml /tmp/ /logs/ /metadata/ +/makebs.config.py makebuildserver.config.py /tests/.fdroid.keypass.txt /tests/.fdroid.keystorepass.txt diff --git a/MANIFEST.in b/MANIFEST.in index b3dcf59b..9f0d5f5d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include buildserver/config.buildserver.py +include buildserver/config.buildserver.yml include buildserver/provision-android-ndk include buildserver/provision-android-sdk include buildserver/provision-apt-get-install @@ -8,7 +8,7 @@ include buildserver/setup-env-vars include buildserver/Vagrantfile include CHANGELOG.md include completion/bash-completion -include examples/config.py +include examples/config.yml include examples/fdroid-icon.png include examples/makebuildserver.config.py include examples/opensc-fdroid.cfg diff --git a/buildserver/config.buildserver.py b/buildserver/config.buildserver.py deleted file mode 100644 index e09188ec..00000000 --- a/buildserver/config.buildserver.py +++ /dev/null @@ -1,19 +0,0 @@ -sdk_path = "/home/vagrant/android-sdk" -ndk_paths = { - 'r10e': "/home/vagrant/android-ndk/r10e", - 'r11c': "/home/vagrant/android-ndk/r11c", - 'r12b': "/home/vagrant/android-ndk/r12b", - 'r13b': "/home/vagrant/android-ndk/r13b", - 'r14b': "/home/vagrant/android-ndk/r14b", - 'r15c': "/home/vagrant/android-ndk/r15c", - 'r16b': "/home/vagrant/android-ndk/r16b", - 'r17c': "/home/vagrant/android-ndk/r17c", - 'r18b': "/home/vagrant/android-ndk/r18b", - 'r19c': "/home/vagrant/android-ndk/r19c", - 'r20b': "/home/vagrant/android-ndk/r20b", - 'r21d': "/home/vagrant/android-ndk/r21d", -} -java_paths = { - '8': "/usr/lib/jvm/java-8-openjdk-amd64", -} -gradle_version_dir = "/opt/gradle/versions" diff --git a/buildserver/config.buildserver.yml b/buildserver/config.buildserver.yml new file mode 100644 index 00000000..b94fc601 --- /dev/null +++ b/buildserver/config.buildserver.yml @@ -0,0 +1,19 @@ +sdk_path: /home/vagrant/android-sdk +ndk_paths: + r10e: /home/vagrant/android-ndk/r10e + r11c: /home/vagrant/android-ndk/r11c + r12b: /home/vagrant/android-ndk/r12b + r13b: /home/vagrant/android-ndk/r13b + r14b: /home/vagrant/android-ndk/r14b + r15c: /home/vagrant/android-ndk/r15c + r16b: /home/vagrant/android-ndk/r16b + r17c: /home/vagrant/android-ndk/r17c + r18b: /home/vagrant/android-ndk/r18b + r19c: /home/vagrant/android-ndk/r19c + r20b: /home/vagrant/android-ndk/r20b + r21d: /home/vagrant/android-ndk/r21d + +java_paths: + 8: /usr/lib/jvm/java-8-openjdk-amd64 + +gradle_version_dir: /opt/gradle/versions diff --git a/examples/config.py b/examples/config.yml similarity index 73% rename from examples/config.py rename to examples/config.yml index c9c1cbc1..555699fd 100644 --- a/examples/config.py +++ b/examples/config.yml @@ -1,82 +1,78 @@ -#!/usr/bin/env python3 - -# Copy this file to config.py, then amend the settings below according to +--- +# Copy this file to config.yml, then amend the settings below according to # your system configuration. # Custom path to the Android SDK, defaults to $ANDROID_HOME -# sdk_path = "$ANDROID_HOME" +# sdk_path: $ANDROID_HOME # Custom paths to various versions of the Android NDK, defaults to 'r12b' set # to $ANDROID_NDK. Most users will have the latest at $ANDROID_NDK, which is # used by default. If a version is missing or assigned to None, it is assumed # not installed. -# ndk_paths = { -# 'r10e': None, -# 'r11c': None, -# 'r12b': "$ANDROID_NDK", -# 'r13b': None, -# 'r14b': None, -# 'r15c': None, -# 'r16b': None, -# 'r17c': None, -# 'r18b': None, -# 'r19c': None, -# 'r20b': None, -# 'r21d': None, -# } +# ndk_paths: +# r10e: None +# r11c: None +# r12b: $ANDROID_NDK +# r13b: None +# r14b: None +# r15c: None +# r16b: None +# r17c: None +# r18b: None +# r19c: None +# r20b: None +# r21d: None # Directory to store downloaded tools in (i.e. gradle versions) # By default, these are stored in ~/.cache/fdroidserver -# cachedir = cache +# cachedir: cache -# java_paths = { -# '8': "/usr/lib/jvm/java-8-openjdk", -# } +# Specify paths to each major Java release that you want to support +# java_paths: +# 8: /usr/lib/jvm/java-8-openjdk # Build tools version to be used -# build_tools = "28.0.3" +# build_tools: 28.0.3 # Command or path to binary for running Ant -# ant = "ant" +# ant: ant # Command or path to binary for running maven 3 -# mvn3 = "mvn" +# mvn3: mvn # Command or path to binary for running Gradle # Defaults to using an internal gradle wrapper (gradlew-fdroid). -# gradle = "gradle" +# gradle: gradle # Always scan the APKs produced by `fdroid build` for known non-free classes -# scan_binary = True +# scan_binary: true # Set the maximum age (in days) of an index that a client should accept from # this repo. Setting it to 0 or not setting it at all disables this # functionality. If you do set this to a non-zero value, you need to ensure # that your index is updated much more frequently than the specified interval. # The same policy is applied to the archive repo, if there is one. -# repo_maxage = 0 +# repo_maxage: 0 -repo_url = "https://MyFirstFDroidRepo.org/fdroid/repo" -repo_name = "My First F-Droid Repo Demo" -repo_icon = "fdroid-icon.png" -repo_description = """ -This is a repository of apps to be used with F-Droid. Applications in this -repository are either official binaries built by the original application -developers, or are binaries built from source by the admin of f-droid.org -using the tools on https://gitlab.com/u/fdroid. -""" +repo_url: https://MyFirstFDroidRepo.org/fdroid/repo +repo_name: My First F-Droid Repo Demo +repo_icon: fdroid-icon.png +repo_description: | + This is a repository of apps to be used with F-Droid. Applications in this + repository are either official binaries built by the original application + developers, or are binaries built from source by the admin of f-droid.org + using the tools on https://gitlab.com/u/fdroid. # As above, but for the archive repo. # archive_older sets the number of versions kept in the main repo, with all # older ones going to the archive. Set it to 0, and there will be no archive # repository, and no need to define the other archive_ values. -archive_older = 3 -archive_url = "https://f-droid.org/archive" -archive_name = "My First F-Droid Archive Demo" -archive_icon = "fdroid-icon.png" -archive_description = """ -The repository of older versions of applications from the main demo repository. -""" +archive_older: 3 +archive_url: https://f-droid.org/archive +archive_name: My First F-Droid Archive Demo +archive_icon: fdroid-icon.png +archive_description: | + The repository of older versions of packages from the main demo repository. # This allows a specific kind of insecure APK to be included in the # 'repo' section. Since April 2017, APK signatures that use MD5 are @@ -85,77 +81,82 @@ The repository of older versions of applications from the main demo repository. # disabled signatures to the archive. This option stops that # behavior, and lets those APKs stay part of 'repo'. # -# allow_disabled_algorithms = True +# allow_disabled_algorithms: true # Normally, all apps are collected into a single app repository, like on # https://f-droid.org. For certain situations, it is better to make a repo # that is made up of APKs only from a single app. For example, an automated # build server that publishes nightly builds. -# per_app_repos = True +# per_app_repos: true # `fdroid update` will create a link to the current version of a given app. # This provides a static path to the current APK. To disable the creation of # this link, uncomment this: -# make_current_version_link = False +# make_current_version_link: false # By default, the "current version" link will be based on the "Name" of the # app from the metadata. You can change it to use a different field from the # metadata here: -# current_version_name_source = 'packageName' +# current_version_name_source: packageName # Optionally, override home directory for gpg -# gpghome = '/home/fdroid/somewhere/else/.gnupg' +# gpghome: /home/fdroid/somewhere/else/.gnupg # The ID of a GPG key for making detached signatures for apks. Optional. -# gpgkey = '1DBA2E89' +# gpgkey: 1DBA2E89 # The key (from the keystore defined below) to be used for signing the # repository itself. This is the same name you would give to keytool or # jarsigner using -alias. (Not needed in an unsigned repository). -# repo_keyalias = "fdroidrepo" +# repo_keyalias: fdroidrepo # Optionally, the public key for the key defined by repo_keyalias above can # be specified here. There is no need to do this, as the public key can and # will be retrieved from the keystore when needed. However, specifying it # manually can allow some processing to take place without access to the # keystore. -# repo_pubkey = "..." +# repo_pubkey: ... # The keystore to use for release keys when building. This needs to be # somewhere safe and secure, and backed up! The best way to manage these # sensitive keys is to use a "smartcard" (aka Hardware Security Module). To # configure F-Droid to use a smartcard, set the keystore file using the keyword -# "NONE" (i.e. keystore = "NONE"). That makes Java find the keystore on the +# "NONE" (i.e. keystore: "NONE"). That makes Java find the keystore on the # smartcard based on 'smartcardoptions' below. -# keystore = "~/.local/share/fdroidserver/keystore.jks" +# keystore: ~/.local/share/fdroidserver/keystore.jks # You should not need to change these at all, unless you have a very # customized setup for using smartcards in Java with keytool/jarsigner -# smartcardoptions = "-storetype PKCS11 -providerName SunPKCS11-OpenSC \ -# -providerClass sun.security.pkcs11.SunPKCS11 \ -# -providerArg opensc-fdroid.cfg" +# smartcardoptions: | +# -storetype PKCS11 -providerName SunPKCS11-OpenSC +# -providerClass sun.security.pkcs11.SunPKCS11 +# -providerArg opensc-fdroid.cfg # The password for the keystore (at least 6 characters). If this password is # different than the keypass below, it can be OK to store the password in this # file for real use. But in general, sensitive passwords should not be stored # in text files! -# keystorepass = "password1" +# keystorepass: password1 # The password for keys - the same is used for each auto-generated key as well # as for the repository key. You should not normally store this password in a # file since it is a sensitive password. -# keypass = "password2" +# keypass: password2 # The distinguished name used for all keys. -# keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US" +# keydname: CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US # Use this to override the auto-generated key aliases with specific ones # for particular applications. Normally, just leave it empty. -# keyaliases = {} -# keyaliases['com.example.app'] = 'example' +# +# keyaliases: +# com.example.app: example +# # You can also force an app to use the same key alias as another one, using # the @ prefix. -# keyaliases['com.example.another.plugin'] = '@com.example.another' +# +# keyaliases: +# com.example.another.plugin: "@com.example.another" # The full path to the root of the repository. It must be specified in @@ -166,11 +167,11 @@ The repository of older versions of applications from the main demo repository. # multiple servers to sync to by wrapping the whole thing in {} or [], and # including the serverwebroot strings in a comma-separated list. # -# serverwebroot = 'user@example:/var/www/fdroid' -# serverwebroot = { -# 'foo.com:/usr/share/nginx/www/fdroid', -# 'bar.info:/var/www/fdroid', -# } +# serverwebroot: user@example:/var/www/fdroid +# serverwebroot: +# - foo.com:/usr/share/nginx/www/fdroid +# - bar.info:/var/www/fdroid + # When running fdroid processes on a remote server, it is possible to # publish extra information about the status. Each fdroid sub-command @@ -181,25 +182,24 @@ The repository of older versions of applications from the main demo repository. # .../repo/$APPID_$VERCODE.log.gz. These files are also pushed to all # servers configured in 'serverwebroot'. # -# deploy_process_logs = True +# deploy_process_logs: true # The full URL to a git remote repository. You can include # multiple servers to mirror to by wrapping the whole thing in {} or [], and # including the servergitmirrors strings in a comma-separated list. # Servers listed here will also be automatically inserted in the mirrors list. # -# servergitmirrors = 'https://github.com/user/repo' -# servergitmirrors = { -# 'https://github.com/user/repo', -# 'https://gitlab.com/user/repo', -# } +# servergitmirrors: https://github.com/user/repo +# servergitmirrors: +# - https://github.com/user/repo +# - https://gitlab.com/user/repo # Most git hosting services have hard size limits for each git repo. # `fdroid deploy` will delete the git history when the git mirror repo # approaches this limit to ensure that the repo will still fit when # pushed. GitHub recommends 1GB, gitlab.com recommends 10GB. # -# git_mirror_size_limit = '10GB' +# git_mirror_size_limit: 10GB # Any mirrors of this repo, for example all of the servers declared in # serverwebroot and all the servers declared in servergitmirrors, @@ -210,14 +210,13 @@ The repository of older versions of applications from the main demo repository. # and the archive, if it is enabled. So these URLs should end in the # 'fdroid' base of the F-Droid part of the web server like serverwebroot. # -# mirrors = ( -# 'https://foo.bar/fdroid', -# 'http://foobarfoobarfoobar.onion/fdroid', -# ) +# mirrors: +# - https://foo.bar/fdroid +# - http://foobarfoobarfoobar.onion/fdroid # optionally specify which identity file to use when using rsync or git over SSH # -# identity_file = '~/.ssh/fdroid_id_rsa' +# identity_file: ~/.ssh/fdroid_id_rsa # If you are running the repo signing process on a completely offline machine, @@ -228,7 +227,7 @@ The repository of older versions of applications from the main demo repository. # standard folder called 'fdroid' as the specified folder is recommended, like # with serverwebroot. # -# local_copy_dir = '/media/MyUSBThumbDrive/fdroid' +# local_copy_dir: /media/MyUSBThumbDrive/fdroid # If you are using local_copy_dir on an offline build/signing server, once the @@ -236,19 +235,21 @@ The repository of older versions of applications from the main demo repository. # synced to the copy on the online machine. To make that happen # automatically, set sync_from_local_copy_dir to True: # -# sync_from_local_copy_dir = True +# sync_from_local_copy_dir: true # To upload the repo to an Amazon S3 bucket using `fdroid server # update`. Warning, this deletes and recreates the whole fdroid/ # directory each time. This prefers s3cmd, but can also use # apache-libcloud. To customize how s3cmd interacts with the cloud -# provider, create a 's3cfg' file next to this file (config.py), and +# provider, create a 's3cfg' file next to this file (config.yml), and # those settings will be used instead of any 'aws' variable below. +# Secrets can be fetched from environment variables to ensure that +# they are not leaked as part of this file. # -# awsbucket = 'myawsfdroid' -# awsaccesskeyid = 'SEE0CHAITHEIMAUR2USA' -# awssecretkey = 'yourverysecretkeywordpassphraserighthere' +# awsbucket: myawsfdroid +# awsaccesskeyid: SEE0CHAITHEIMAUR2USA +# awssecretkey: {env: awssecretkey} # If you want to force 'fdroid server' to use a non-standard serverwebroot. @@ -256,69 +257,72 @@ The repository of older versions of applications from the main demo repository. # '/fdroid'. (Please note that some client features expect repository URLs # to end in '/fdroid/repo'.) # -# nonstandardwebroot = False +# nonstandardwebroot: false # If you want to upload the release apk file to androidobservatory.org # -# androidobservatory = False +# androidobservatory: false # If you want to upload the release apk file to virustotal.com # You have to enter your profile apikey to enable the upload. # -# virustotal_apikey = "virustotal_apikey" +# virustotal_apikey: 9872987234982734 +# +# Or get it from an environment variable: +# +# virustotal_apikey: {env: virustotal_apikey} # The build logs can be posted to a mediawiki instance, like on f-droid.org. -# wiki_protocol = "http" -# wiki_server = "server" -# wiki_path = "/wiki/" -# wiki_user = "login" -# wiki_password = "1234" +# wiki_protocol: http +# wiki_server: server +# wiki_path: /wiki/ +# wiki_user: login +# wiki_password: 1234 # Keep a log of all generated index files in a git repo to provide a # "binary transparency" log for anyone to check the history of the # binaries that are published. This is in the form of a "git remote", # which this machine where `fdroid update` is run has already been # configured to allow push access (e.g. ssh key, username/password, etc) -# binary_transparency_remote = "git@gitlab.com:fdroid/binary-transparency-log.git" +# binary_transparency_remote: git@gitlab.com:fdroid/binary-transparency-log.git # Only set this to true when running a repository where you want to generate # stats, and only then on the master build servers, not a development # machine. If you want to keep the "added" and "last updated" dates for each # app and APK in your repo, then you should enable this. -# update_stats = True +# update_stats: true # When used with stats, this is a list of IP addresses that are ignored for # calculation purposes. -# stats_ignore = [] +# stats_ignore: [] # Server stats logs are retrieved from. Required when update_stats is True. -# stats_server = "example.com" +# stats_server: example.com # User stats logs are retrieved from. Required when update_stats is True. -# stats_user = "bob" +# stats_user: bob # Use the following to push stats to a Carbon instance: -# stats_to_carbon = False -# carbon_host = '0.0.0.0' -# carbon_port = 2003 +# stats_to_carbon: false +# carbon_host: 0.0.0.0 +# carbon_port: 2003 # Set this to true to always use a build server. This saves specifying the # --server option on dedicated secure build server hosts. -# build_server_always = True +# build_server_always: true # Limit in number of characters that fields can take up # Only the fields listed here are supported, defaults shown -# char_limits = { -# 'author': 256, -# 'name': 50, -# 'summary': 80, -# 'description': 4000, -# 'video': 256, -# 'whatsNew': 500, -# } +# char_limits: +# author: 256 +# name: 50 +# summary: 80 +# description: 4000 +# video: 256 +# whatsNew: 500 # It is possible for the server operator to specify lists of apps that # must be installed or uninstalled on the client (aka "push installs). @@ -327,16 +331,14 @@ The repository of older versions of applications from the main demo repository. # the packageNames listed. This is protected by the same signing key # as the app index metadata. # -# install_list = ( -# 'at.bitfire.davdroid', -# 'com.fsck.k9', -# 'us.replicant', -# ) +# install_list: +# - at.bitfire.davdroid +# - com.fsck.k9 +# - us.replicant # -# uninstall_list = ( -# 'com.facebook.orca', -# 'com.android.vending', -# ) +# uninstall_list: +# - com.facebook.orca +# - com.android.vending # `fdroid lint` checks licenses in metadata against a built white list. By # default we will require license metadata to be present and only allow @@ -350,7 +352,6 @@ The repository of older versions of applications from the main demo repository. # Just supply a custom list of licene names you would like to allow. Setting # this to `None` disables this lint check. # -# lint_licenses = ( -# 'Custom-License-A', -# 'Another-License', -# ) +# lint_licenses: +# - Custom-License-A +# - Another-License diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 96337813..bf23c9e5 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -141,8 +141,8 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): ftp.chdir(homedir) ftp.put(os.path.join(serverpath, '..', 'buildserver', - 'config.buildserver.py'), 'config.py') - ftp.chmod('config.py', 0o600) + 'config.buildserver.yml'), 'config.yml') + ftp.chmod('config.yml', 0o600) # Copy over the ID (head commit hash) of the fdroidserver in use... with open(os.path.join(os.getcwd(), 'tmp', 'fdroidserverid'), 'wb') as fp: diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 74d0b987..aa522da3 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -324,7 +324,7 @@ def read_config(opts): code = compile(fp.read(), old_config_file, 'exec') exec(code, None, config) # nosec TODO automatically migrate else: - logging.warning(_("No 'config.py' found, using defaults.")) + logging.warning(_("No config.yml found, using defaults.")) for k in ('mirrors', 'install_list', 'uninstall_list', 'serverwebroot', 'servergitroot'): if k in config: @@ -389,16 +389,25 @@ def read_config(opts): config['git_mirror_size_limit'] = parse_human_readable_size(limit) for configname, dictvalue in config.items(): - if isinstance(dictvalue, dict) \ - and configname not in ('ndk_paths', 'java_paths', 'char_limits', 'keyaliases'): + if configname == 'java_paths': + new = dict() + for k, v in dictvalue.items(): + new[str(k)] = v + config[configname] = new + elif configname in ('ndk_paths', 'java_paths', 'char_limits', 'keyaliases'): + continue + elif isinstance(dictvalue, dict): for k, v in dictvalue.items(): if k == 'env': env = os.getenv(v) - config[configname] = env - if not env: + if env: + config[configname] = env + else: + del(config[configname]) logging.error(_('Environment variable {var} from {configname} is not set!') .format(var=k, configname=configname)) else: + del(config[configname]) logging.error(_('Unknown entry {key} in {configname}') .format(key=k, configname=configname)) @@ -430,10 +439,10 @@ def assert_config_keystore(config): nosigningkey = False if 'repo_keyalias' not in config: nosigningkey = True - logging.critical(_("'repo_keyalias' not found in config.py!")) + logging.critical(_("'repo_keyalias' not found in config.yml!")) if 'keystore' not in config: nosigningkey = True - logging.critical(_("'keystore' not found in config.py!")) + logging.critical(_("'keystore' not found in config.yml!")) elif config['keystore'] == 'NONE': if not config.get('smartcardoptions'): nosigningkey = True @@ -443,10 +452,10 @@ def assert_config_keystore(config): logging.critical("'" + config['keystore'] + "' does not exist!") if 'keystorepass' not in config: nosigningkey = True - logging.critical(_("'keystorepass' not found in config.py!")) + logging.critical(_("'keystorepass' not found in config.yml!")) if 'keypass' not in config and config.get('keystore') != 'NONE': nosigningkey = True - logging.critical(_("'keypass' not found in config.py!")) + logging.critical(_("'keypass' not found in config.yml!")) if nosigningkey: raise FDroidException("This command requires a signing key, " + "you can create one using: fdroid update --create-key") @@ -547,7 +556,7 @@ def test_sdk_exists(thisconfig): test_aapt_version(thisconfig['aapt']) return True else: - logging.error(_("'sdk_path' not set in 'config.py'!")) + logging.error(_("'sdk_path' not set in config.yml!")) return False if thisconfig['sdk_path'] == default_config['sdk_path']: logging.error(_('No Android SDK found!')) diff --git a/fdroidserver/deploy.py b/fdroidserver/deploy.py index 724487d5..87dfce8b 100644 --- a/fdroidserver/deploy.py +++ b/fdroidserver/deploy.py @@ -52,7 +52,7 @@ def update_awsbucket(repo_section): subdirectories) to the AWS S3 "bucket". The contents of that subdir of the bucket will first be deleted. - Requires AWS credentials set in config.py: awsaccesskeyid, awssecretkey + Requires AWS credentials set in config.yml: awsaccesskeyid, awssecretkey ''' logging.debug('Syncing "' + repo_section + '" to Amazon S3 bucket "' @@ -160,7 +160,7 @@ def update_awsbucket_libcloud(repo_section): if not config.get('awsaccesskeyid') or not config.get('awssecretkey'): raise FDroidException( - _('To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.py!')) + _('To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.yml!')) awsbucket = config['awsbucket'] if os.path.exists(USER_S3CFG): diff --git a/fdroidserver/init.py b/fdroidserver/init.py index f53057a0..124555a3 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -36,13 +36,14 @@ options = None def disable_in_config(key, value): - '''write a key/value to the local config.py, then comment it out''' - with open('config.py', 'r') as f: + '''write a key/value to the local config.yml, then comment it out''' + import yaml + with open('config.yml') as f: data = f.read() - pattern = r'\n[\s#]*' + key + r'\s*=\s*"[^"]*"' - repl = '\n#' + key + ' = "' + value + '"' + pattern = r'\n[\s#]*' + key + r':.*' + repl = '\n#' + yaml.dump({key: value}, default_flow_style=False) data = re.sub(pattern, repl, data) - with open('config.py', 'w') as f: + with open('config.yml', 'w') as f: f.writelines(data) @@ -114,13 +115,13 @@ def main(): raise FDroidException(_("Android SDK not found at {path}!") .format(path=test_config['sdk_path'])) - if not os.path.exists('config.py'): + if not os.path.exists('config.yml') and not os.path.exists('config.py'): # 'metadata' and 'tmp' are created in fdroid if not os.path.exists('repo'): os.mkdir('repo') shutil.copy(os.path.join(examplesdir, 'fdroid-icon.png'), fdroiddir) - shutil.copyfile(os.path.join(examplesdir, 'config.py'), 'config.py') - os.chmod('config.py', 0o0600) + shutil.copyfile(os.path.join(examplesdir, 'config.yml'), 'config.yml') + os.chmod('config.yml', 0o0600) # If android_home is None, test_config['sdk_path'] will be used and # "$ANDROID_HOME" may be used if the env var is set up correctly. # If android_home is not None, the path given from the command line @@ -132,7 +133,7 @@ def main(): logging.info('Try running `fdroid init` in an empty directory.') raise FDroidException('Repository already exists.') - # now that we have a local config.py, read configuration... + # now that we have a local config.yml, read configuration... config = common.read_config(options) # enable apksigner by default so v2/v3 APK signatures validate @@ -143,7 +144,7 @@ def main(): # left for the user to configure # find or generate the keystore for the repo signing key. First try the - # path written in the default config.py. Then check if the user has + # path written in the default config.yml. Then check if the user has # specified a path from the command line, which will trump all others. # Otherwise, create ~/.local/share/fdroidserver and stick it in there. If # keystore is set to NONE, that means that Java will look for keys in a @@ -192,7 +193,7 @@ def main(): f.write('name = OpenSC\nlibrary = ') f.write(opensc_so) f.write('\n') - logging.info("Repo setup using a smartcard HSM. Please edit keystorepass and repo_keyalias in config.py.") + logging.info("Repo setup using a smartcard HSM. Please edit keystorepass and repo_keyalias in config.yml.") logging.info("If you want to generate a new repo signing key in the HSM you can do that with 'fdroid update " "--create-key'.") elif os.path.exists(keystore): @@ -202,7 +203,7 @@ def main(): if keydname: to_set.remove('keydname') logging.warning('\n' + _('Using existing keystore "{path}"').format(path=keystore) - + '\n' + _('Now set these in config.py:') + ' ' + + '\n' + _('Now set these in config.yml:') + ' ' + ', '.join(to_set) + '\n') else: password = common.genpassword() @@ -228,7 +229,7 @@ def main(): msg += '\n Alias for key in store:\t' + repo_keyalias msg += '\n\n' + '''To complete the setup, add your APKs to "%s" then run "fdroid update -c; fdroid update". You might also want to edit -"config.py" to set the URL, repo name, and more. You should also set up +"config.yml" to set the URL, repo name, and more. You should also set up a signing key (a temporary one might have been automatically generated). For more info: https://f-droid.org/docs/Setup_an_F-Droid_App_Repo diff --git a/hooks/pre-commit b/hooks/pre-commit index 94c55888..a197559d 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -8,11 +8,12 @@ exec 1>&2 files=`git diff-index --cached HEAD 2>&1 | sed 's/^:.* //' | uniq | cut -b100-500` if [ -z "$files" ]; then - PY_FILES="fdroid makebuildserver setup.py examples/*.py buildserver/*.py fdroidserver/*.py" + PY_FILES="fdroid makebuildserver setup.py fdroidserver/*.py" PY_TEST_FILES="tests/*.TestCase" SH_FILES="hooks/pre-commit" BASH_FILES="gradlew-fdroid jenkins-build-all jenkins-setup-build-environment jenkins-test completion/bash-completion buildserver/provision-*" RB_FILES="buildserver/Vagrantfile" + YML_FILES="buildserver/*.yml examples/*.yml" else # if actually committing right now, then only run on the files # that are going to be committed at this moment @@ -21,6 +22,7 @@ else SH_FILES= BASH_FILES= RB_FILES= + YML_FILES= for f in $files; do test -e $f || continue @@ -34,6 +36,9 @@ else *.rb) RB_FILES+=" $f" ;; + *.yml) + YML_FILES+=" $f" + ;; *) if head -1 $f | grep '^#!/bin/sh' > /dev/null 2>&1; then SH_FILES+=" $f" @@ -89,6 +94,7 @@ DASH=$(find_command dash) PYFLAKES=$(find_command pyflakes) PEP8=$(find_command pycodestyle pep8) RUBY=$(find_command ruby) +YAMLLINT=$(find_command yamllint) if [ "$PY_FILES $PY_TEST_FILES" != " " ]; then if ! $PYFLAKES $PY_FILES $PY_TEST_FILES; then @@ -129,6 +135,12 @@ for f in $RB_FILES; do fi done +for f in $YML_FILES; do + if ! $YAMLLINT $f 1>/dev/null; then + err ".yml tests failed on $f!" + fi +done + if grep -C 3 'shell=True' fdroidserver/[a-ce-z]*.py; then err "shell=True is too dangerous, there are unfiltered user inputs!" fi diff --git a/jenkins-build-all b/jenkins-build-all index 34b6dfd7..6ae96767 100755 --- a/jenkins-build-all +++ b/jenkins-build-all @@ -81,18 +81,18 @@ else cd fdroiddata fi -echo "build_server_always = True" > config.py -echo "deploy_process_logs = True" >> config.py +echo "build_server_always: true" > config.yml +echo "deploy_process_logs: true" >> config.yml # if the local mediawiki is available, then use it if nc -z -w1 localhost 32445; then wikiflag="--wiki" - echo "wiki_protocol = 'http'" >> config.py - echo "wiki_server = 'localhost:32445'" >> config.py - echo "wiki_path = '/mediawiki/'" >> config.py - echo "wiki_user = 'fdroid'" >> config.py - echo "wiki_password = 'update.TestCase'" >> config.py + echo "wiki_protocol: http" >> config.yml + echo "wiki_server: localhost:32445" >> config.yml + echo "wiki_path: /mediawiki/" >> config.yml + echo "wiki_user: fdroid" >> config.yml + echo "wiki_password: update.TestCase" >> config.yml else - sed -i '/^wiki_/d' config.py + sed -i '/^wiki_/d' config.yml fi $WORKSPACE/fdroid build --verbose --latest --no-tarball --all $wikiflag diff --git a/jenkins-setup-build-environment b/jenkins-setup-build-environment index c47359b0..489717b2 100755 --- a/jenkins-setup-build-environment +++ b/jenkins-setup-build-environment @@ -98,7 +98,7 @@ else fi cd fdroiddata -echo "build_server_always = True" > config.py +echo "build_server_always: true" > config.yml if [ -z $ANDROID_HOME ]; then if [ -e ~/.android/bashrc ]; then diff --git a/jenkins-test b/jenkins-test index 2790a1fe..4ea8702b 100755 --- a/jenkins-test +++ b/jenkins-test @@ -44,7 +44,7 @@ fi # this is set up and managed by jenkins-build-all cd $WORKSPACE/fdroiddata -rm -f config.py keystore.jks keystore.p12 +rm -f config.py config.yml keystore.jks keystore.p12 ../fdroid init --verbose export GNUPGHOME=$WORKSPACE/tests/gnupghome @@ -54,13 +54,13 @@ if [ ! -e $GNUPGHOME/private-keys-v1.d ]; then fi gpg --import $GNUPGHOME/secring.gpg -echo "build_server_always = True" >> config.py -echo "deploy_process_logs = True" >> config.py -echo "make_current_version_link = False" >> config.py -echo "gpghome = '$GNUPGHOME'" >> config.py -echo "gpgkey = 'CE71F7FB'" >> config.py -chmod 0600 config.py -sed -i '/\s*repo_key_sha256\s*=.*/d' config.py +echo "build_server_always: true" >> config.yml +echo "deploy_process_logs: true" >> config.yml +echo "make_current_version_link: false" >> config.yml +echo "gpghome: $GNUPGHOME" >> config.yml +echo "gpgkey: CE71F7FB" >> config.yml +chmod 0600 config.yml +sed -i '/\s*repo_key_sha256:.*/d' config.yml # publish process when building and signing are on separate machines test -d repo || mkdir repo @@ -71,9 +71,9 @@ test -d archive || mkdir archive ../fdroid gpgsign # when everything is copied over to run on BUILD machine, # which does not have a keyring, only a cached pubkey -echo "repo_pubkey = '308204e1308202c9a003020102020434597643300d06092a864886f70d01010b050030213110300e060355040b1307462d44726f6964310d300b06035504031304736f7661301e170d3136303931333230313930395a170d3434303133303230313930395a30213110300e060355040b1307462d44726f6964310d300b06035504031304736f766130820222300d06092a864886f70d01010105000382020f003082020a028202010086ef94b5aacf2ba4f38c875f4194b44f5644392e3715575d7c92828577e692c352b567172823851c8c72347fbc9d99684cd7ca3e1db3e4cca126382c53f2a5869fb4c19bdec989b2930501af3e758ff40588915fe96b10076ce3346a193a0277d79e83e30fd8657c20e35260dd085aa32eac7c4b85786ffefbf1555cafe2bc928443430cdbba48cfbe701e12ae86e676477932730d4fc7c00af820aef85038a5b4df084cf6470d110dc4c49ea1b749b80b34709d199b3db516b223625c5de4501e861f7d261b3838f8f616aa78831d618d41d25872dc810c9b2087b5a9e146ca95be740316dcdbcb77314e23ab87d4487913b800b1113c0603ea2294188b71d3e49875df097b56f9151211fc6832f9790c5c83d17481f14ad37915fd164f4fd713f6732a15f4245714b84cd665bdbd085660ea33ad7d7095dcc414f09e3903604a40facc2314a115c0045bb50e9df38efb57e1b8e7cc105f340a26eeb46aba0fa6672953eee7f1f92dcb408e561909bbd4bdf4a4948c4d57c467d21aa238c34ba43be050398be963191fa2b49828bc1e4eeed224b40dbe9dc3e570890a71a974a2f4527edb1b07105071755105edcb2af2f269facfb89180903a572a99b46456e80d4a01685a80b233278805f2c876678e731f4ec4f52075aeef6b2b023efbb8a3637ef507c4c37c27e428152ec1817fcba640ad601cb09f72f0fbe2d274a2410203010001a321301f301d0603551d0e04160414c28bf33dd5a9a17338e5b1d1a6edd8c7d141ed0b300d06092a864886f70d01010b0500038202010084e20458b2aafd7fc27146b0986f9324f4260f244920417a77c9bf15e2e2d22d2725bdd8093ec261c3779c3ca03312516506f9410075b90595b41345956d8eb2786fb5994f195611382c2b99dba13381b0100a30bc9e6e47248bf4325e2f6eec9d789216dc7536e753bf1f4be603d9fa2e6f5e192b4eb988b8cdb0bb1e8668a9225426f7d4636479f73ed24ad1d2657c31e63c93d9679b9080171b3bd1bf10a3b92b80bd790fbf62d3644900cd08eae8b9bf9c2567be98dc8cdd2ae19a8d57a3e3e2de899f81f1279f578989e6af906f80c8c2b67651730ee7e568c1af5bcb845b6d685dc55332a9984aeceaea3b7e883447edf1c76b155d95253e39b9710eaa22efa6c81468829702b5dce7126538f3ca70c2f0ad9a5795435fdb1f715f20d60359ef9a9926c7050116e802df651727447848827815f70bd82af3cedd08783156102d2d8ce995c4c43b8e47e91a3e6927f3505a5d395e6bebb84542c570903eeab4382a1c2151f1471c7a06a34dc4d268d8fa72e93bdcd2dccc4302ecac47b9e7e3d8bc9b46d21cd097874a24d529548018dc190ff568c6aa428f0a5eedff1a347730931c74f19277538e49647a4ad7254f4c1ec7d4da12cce9e1fad9607534e66ab40a56b473d9d7e3d563fd03cad2052bad365c5a29f8ae54f09b60dbca3ea768d7767cbe1c133ca08ce725c1c1370f4aab8e5b6e286f52dc0be8d0982b5a'" >> config.py +echo "repo_pubkey: 308204e1308202c9a003020102020434597643300d06092a864886f70d01010b050030213110300e060355040b1307462d44726f6964310d300b06035504031304736f7661301e170d3136303931333230313930395a170d3434303133303230313930395a30213110300e060355040b1307462d44726f6964310d300b06035504031304736f766130820222300d06092a864886f70d01010105000382020f003082020a028202010086ef94b5aacf2ba4f38c875f4194b44f5644392e3715575d7c92828577e692c352b567172823851c8c72347fbc9d99684cd7ca3e1db3e4cca126382c53f2a5869fb4c19bdec989b2930501af3e758ff40588915fe96b10076ce3346a193a0277d79e83e30fd8657c20e35260dd085aa32eac7c4b85786ffefbf1555cafe2bc928443430cdbba48cfbe701e12ae86e676477932730d4fc7c00af820aef85038a5b4df084cf6470d110dc4c49ea1b749b80b34709d199b3db516b223625c5de4501e861f7d261b3838f8f616aa78831d618d41d25872dc810c9b2087b5a9e146ca95be740316dcdbcb77314e23ab87d4487913b800b1113c0603ea2294188b71d3e49875df097b56f9151211fc6832f9790c5c83d17481f14ad37915fd164f4fd713f6732a15f4245714b84cd665bdbd085660ea33ad7d7095dcc414f09e3903604a40facc2314a115c0045bb50e9df38efb57e1b8e7cc105f340a26eeb46aba0fa6672953eee7f1f92dcb408e561909bbd4bdf4a4948c4d57c467d21aa238c34ba43be050398be963191fa2b49828bc1e4eeed224b40dbe9dc3e570890a71a974a2f4527edb1b07105071755105edcb2af2f269facfb89180903a572a99b46456e80d4a01685a80b233278805f2c876678e731f4ec4f52075aeef6b2b023efbb8a3637ef507c4c37c27e428152ec1817fcba640ad601cb09f72f0fbe2d274a2410203010001a321301f301d0603551d0e04160414c28bf33dd5a9a17338e5b1d1a6edd8c7d141ed0b300d06092a864886f70d01010b0500038202010084e20458b2aafd7fc27146b0986f9324f4260f244920417a77c9bf15e2e2d22d2725bdd8093ec261c3779c3ca03312516506f9410075b90595b41345956d8eb2786fb5994f195611382c2b99dba13381b0100a30bc9e6e47248bf4325e2f6eec9d789216dc7536e753bf1f4be603d9fa2e6f5e192b4eb988b8cdb0bb1e8668a9225426f7d4636479f73ed24ad1d2657c31e63c93d9679b9080171b3bd1bf10a3b92b80bd790fbf62d3644900cd08eae8b9bf9c2567be98dc8cdd2ae19a8d57a3e3e2de899f81f1279f578989e6af906f80c8c2b67651730ee7e568c1af5bcb845b6d685dc55332a9984aeceaea3b7e883447edf1c76b155d95253e39b9710eaa22efa6c81468829702b5dce7126538f3ca70c2f0ad9a5795435fdb1f715f20d60359ef9a9926c7050116e802df651727447848827815f70bd82af3cedd08783156102d2d8ce995c4c43b8e47e91a3e6927f3505a5d395e6bebb84542c570903eeab4382a1c2151f1471c7a06a34dc4d268d8fa72e93bdcd2dccc4302ecac47b9e7e3d8bc9b46d21cd097874a24d529548018dc190ff568c6aa428f0a5eedff1a347730931c74f19277538e49647a4ad7254f4c1ec7d4da12cce9e1fad9607534e66ab40a56b473d9d7e3d563fd03cad2052bad365c5a29f8ae54f09b60dbca3ea768d7767cbe1c133ca08ce725c1c1370f4aab8e5b6e286f52dc0be8d0982b5a" >> config.yml ../fdroid update --nosign -sed -i '/^repo_pubkey = /d' config.py +sed -i '/^repo_pubkey: /d' config.yml # when everything is copied over to run on SIGN machine ../fdroid signindex --verbose diff --git a/setup.py b/setup.py index 363f686a..26722299 100755 --- a/setup.py +++ b/setup.py @@ -40,7 +40,7 @@ def get_data_files(): data = fp.read() data_files.append((data_prefix + '/share/doc/fdroidserver/examples', - ['buildserver/config.buildserver.py', ] + ['buildserver/config.buildserver.yml', ] + re.findall(r'include (examples/.*)', data))) for f in re.findall(r'include (locale/[a-z][a-z][a-zA-Z_]*/LC_MESSAGES/fdroidserver.mo)', data): diff --git a/tests/common.TestCase b/tests/common.TestCase index d8bc6c6b..eff088d6 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1517,6 +1517,25 @@ class CommonTest(unittest.TestCase): config = fdroidserver.common.read_config(fdroidserver.common.options) self.assertEqual('mysecretpassword', config['keypass']) + def test_config_dict_with_int_keys(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + with open('config.yml', 'w') as fp: + fp.write('java_paths:\n 8: /usr/lib/jvm/java-8-openjdk\n') + self.assertTrue(os.path.exists(fp.name)) + self.assertFalse(os.path.exists('config.py')) + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual('/usr/lib/jvm/java-8-openjdk', config.get('java_paths', {}).get('8')) + + def test_loading_config_buildserver_yml(self): + """Smoke check to make sure this file is properly parsed""" + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + shutil.copy(os.path.join(self.basedir, '..', 'buildserver', 'config.buildserver.yml'), + 'config.yml') + self.assertFalse(os.path.exists('config.py')) + fdroidserver.common.read_config(fdroidserver.common.options) + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) diff --git a/tests/init.TestCase b/tests/init.TestCase new file mode 100755 index 00000000..f080ff74 --- /dev/null +++ b/tests/init.TestCase @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 + +import inspect +import logging +import os +import optparse +import sys +import tempfile +import unittest + + +localmodule = os.path.realpath( + os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) +print('localmodule: ' + localmodule) +if localmodule not in sys.path: + sys.path.insert(0, localmodule) + +import fdroidserver.init + + +class InitTest(unittest.TestCase): + '''fdroidserver/init.py''' + + def setUp(self): + logging.basicConfig(level=logging.DEBUG) + self.basedir = os.path.join(localmodule, 'tests') + self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) + if not os.path.exists(self.tmpdir): + os.makedirs(self.tmpdir) + os.chdir(self.basedir) + fdroidserver.init.config = None + + def test_disable_in_config(self): + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + with open('config.yml', 'w') as fp: + fp.write('keystore: NONE\n') + fp.write('keypass: mysupersecrets\n') + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertEqual('NONE', config['keystore']) + self.assertEqual('mysupersecrets', config['keypass']) + fdroidserver.init.disable_in_config('keypass', 'comment') + with open(fp.name) as fp: + self.assertTrue('#keypass:' in fp.read()) + fdroidserver.common.config = None + config = fdroidserver.common.read_config(fdroidserver.common.options) + self.assertIsNone(config.get('keypass')) + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + + parser = optparse.OptionParser() + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="Spew out even more information than normal") + (fdroidserver.init.options, args) = parser.parse_args(['--verbose']) + + newSuite = unittest.TestSuite() + newSuite.addTest(unittest.makeSuite(InitTest)) + unittest.main(failfast=False) diff --git a/tests/run-tests b/tests/run-tests index 282b8e70..8645a366 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -61,8 +61,8 @@ fdroid_init_with_prebuilt_keystore() { keystore="$1" fi $fdroid init --keystore $keystore --repo-keyalias=sova - echo 'keystorepass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py - echo 'keypass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py + echo 'keystorepass: r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' >> config.yml + echo 'keypass: r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' >> config.yml } # the < is reverse since 0 means success in exit codes @@ -170,10 +170,10 @@ if which zipalign || ls -1 $ANDROID_HOME/build-tools/*/zipalign; then cd $REPOROOT cp $WORKSPACE/tests/keystore.jks $REPOROOT/ $fdroid init --keystore keystore.jks --repo-keyalias=sova - echo 'make_current_version_link = True' >> config.py - echo 'keystorepass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py - echo 'keypass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py - echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py + echo 'make_current_version_link: true' >> config.yml + echo 'keystorepass: r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' >> config.yml + echo 'keypass: r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' >> config.yml + echo 'keydname: "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.yml test -d archive || mkdir archive test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/info.guardianproject.urzip.yml metadata/ @@ -199,8 +199,8 @@ REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -$sed -i.tmp 's,^ *repo_description.*,repo_description = """获取已安装在您的设备上的应用的,' config.py -echo "mirrors = ('https://foo.bar/fdroid', 'http://secret.onion/fdroid')" >> config.py +$sed -i.tmp 's,^ *repo_description.*,repo_description: |\n 获取已安装在您的设备上的应用的,' config.yml +echo "mirrors: ['https://foo.bar/fdroid', 'http://secret.onion/fdroid']" >> config.yml mkdir metadata cp $WORKSPACE/tests/urzip.apk $WORKSPACE/tests/bad-unicode*.apk repo/ cp $WORKSPACE/tests/metadata/info.guardianproject.urzip.yml metadata/ @@ -258,11 +258,11 @@ fdroid_init_with_prebuilt_keystore cp -a $WORKSPACE/tests/metadata $WORKSPACE/tests/repo $WORKSPACE/tests/stats $REPOROOT/ cp -a $WORKSPACE/tests/gnupghome $GNUPGHOME chmod 0700 $GNUPGHOME -echo "install_list = 'org.adaway'" >> config.py -echo "uninstall_list = ('com.android.vending', 'com.facebook.orca',)" >> config.py -echo "gpghome = '$GNUPGHOME'" >> config.py -echo "gpgkey = 'CE71F7FB'" >> config.py -echo "mirrors = ('http://foobarfoobarfoobar.onion/fdroid','https://foo.bar/fdroid',)" >> config.py +echo "install_list: org.adaway" >> config.yml +echo "uninstall_list: [com.android.vending, com.facebook.orca]" >> config.yml +echo "gpghome: $GNUPGHOME" >> config.yml +echo "gpgkey: CE71F7FB" >> config.yml +echo "mirrors: ['http://foobarfoobarfoobar.onion/fdroid', 'https://foo.bar/fdroid']" >> config.yml $fdroid update --verbose --pretty test -e repo/index.xml test -e repo/index.jar @@ -298,7 +298,7 @@ echo_header 'test moving lots of APKs to the archive' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -$sed -i.tmp '/allow_disabled_algorithms/d' config.py +$sed -i.tmp '/allow_disabled_algorithms/d' config.yml test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/*.yml metadata/ echo 'Summary: good test version of urzip' > metadata/info.guardianproject.urzip.yml @@ -310,7 +310,7 @@ cp $WORKSPACE/tests/urzip.apk \ $WORKSPACE/tests/repo/com.politedroid_[0-9].apk \ $WORKSPACE/tests/repo/obb.main.twoversions_110161[357].apk \ repo/ -$sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py +$sed -i.tmp 's,archive_older: [0-9],archive_older: 3,' config.yml $fdroid update --pretty --nosign if which apksigner; then @@ -333,7 +333,7 @@ if ! which apksigner; then cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ test -d repo || mkdir repo cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ - $sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py + $sed -i.tmp 's,archive_older: [0-9],archive_older: 3,' config.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 0 @@ -419,7 +419,7 @@ cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ $sed -i.tmp '/ArchivePolicy:/d' metadata/com.politedroid.yml test -d repo || mkdir repo cp $WORKSPACE/tests/repo/com.politedroid_[0-9].apk repo/ -$sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py +$sed -i.tmp 's,archive_older: [0-9],archive_older: 3,' config.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 1 @@ -433,7 +433,7 @@ test -e repo/com.politedroid_4.apk test -e repo/com.politedroid_5.apk test -e repo/com.politedroid_6.apk -$sed -i.tmp 's,archive_older = 3,archive_older = 1,' config.py +$sed -i.tmp 's,archive_older: 3,archive_older: 1,' config.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 3 test `grep '' repo/index.xml | wc -l` -eq 1 @@ -494,8 +494,8 @@ echo_header 'test allowing disabled signatures in repo and archive' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo 'allow_disabled_algorithms = True' >> config.py -$sed -i.tmp 's,archive_older = [0-9],archive_older = 3,' config.py +echo 'allow_disabled_algorithms: true' >> config.yml +$sed -i.tmp 's,archive_older: [0-9],archive_older: 3,' config.yml test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ echo 'Summary: good test version of urzip' > metadata/info.guardianproject.urzip.yml @@ -531,7 +531,7 @@ test -e repo/org.bitbucket.tickytacky.mirrormirror_4.apk test -e archive/urzip-badsig.apk if ! which apksigner; then - $sed -i.tmp '/allow_disabled_algorithms/d' config.py + $sed -i.tmp '/allow_disabled_algorithms/d' config.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 5 test `grep '' repo/index.xml | wc -l` -eq 3 @@ -557,7 +557,7 @@ if ! which apksigner; then fi # test unarchiving when disabled_algorithms are allowed again -echo 'allow_disabled_algorithms = True' >> config.py +echo 'allow_disabled_algorithms: true' >> config.yml $fdroid update --pretty --nosign test `grep '' archive/index.xml | wc -l` -eq 2 test `grep '' repo/index.xml | wc -l` -eq 6 @@ -587,7 +587,7 @@ echo_header 'rename apks with `fdroid update --rename-apks`, --nosign for speed' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py +echo 'keydname: "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.yml test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/info.guardianproject.urzip.yml metadata/ test -d repo || mkdir repo @@ -684,11 +684,11 @@ echo "Description: |" >> metadata/fake.yml echo " this is fake" >> metadata/fake.yml # fake that no JDKs are available -echo 'java_paths = {}' > config.py +echo 'java_paths: {}' > config.yml LOCAL_COPY_DIR=`create_test_dir`/fdroid mkdir -p $LOCAL_COPY_DIR/repo -echo "local_copy_dir = '$LOCAL_COPY_DIR'" >> config.py +echo "local_copy_dir: $LOCAL_COPY_DIR" >> config.yml $fdroid checkupdates --allow-dirty which gpg && $fdroid gpgsign @@ -775,7 +775,7 @@ $fdroid deploy --local-copy-dir=$LOCALCOPYDIR NEWREPOROOT=`create_test_dir` cd $NEWREPOROOT fdroid_init_with_prebuilt_keystore -echo "sync_from_local_copy_dir = True" >> config.py +echo "sync_from_local_copy_dir: true" >> config.yml $fdroid deploy --local-copy-dir=$LOCALCOPYDIR @@ -844,7 +844,7 @@ KEYSTORE=$REPOROOT/keystore.p12 cd $REPOROOT $fdroid init --keystore $KEYSTORE --android-home $FAKE_ANDROID_HOME set +e -grep $FAKE_ANDROID_HOME $REPOROOT/config.py +grep $FAKE_ANDROID_HOME $REPOROOT/config.yml if [ $? -ne 0 ]; then echo "the value set in --android-home '$FAKE_ANDROID_HOME' should override ANDROID_HOME '$ANDROID_HOME'" exit 1 @@ -1023,10 +1023,10 @@ set -e # now set up fake, non-working keystore setup touch $KEYSTORE -echo "keystore = \"$KEYSTORE\"" >> config.py -echo 'repo_keyalias = "foo"' >> config.py -echo 'keystorepass = "foo"' >> config.py -echo 'keypass = "foo"' >> config.py +echo "keystore: $KEYSTORE" >> config.yml +echo 'repo_keyalias: foo' >> config.yml +echo 'keystorepass: foo' >> config.yml +echo 'keypass: foo' >> config.yml set +e $fdroid update --create-metadata --verbose if [ $? -eq 0 ]; then @@ -1047,7 +1047,7 @@ GNUPGHOME=$REPOROOT/gnupghome cd $REPOROOT fdroid_init_with_prebuilt_keystore cp -a $WORKSPACE/tests/metadata $WORKSPACE/tests/repo $WORKSPACE/tests/stats $REPOROOT/ -echo "binary_transparency_remote = '$GIT_REMOTE'" >> config.py +echo "binary_transparency_remote: $GIT_REMOTE" >> config.yml $fdroid update --verbose if have_git_2_3; then $fdroid deploy --verbose @@ -1084,7 +1084,7 @@ test -e tmp/apkcache.json grep -F '> config.py +echo "servergitmirrors: $SERVER_GIT_MIRROR" >> config.yml cp $WORKSPACE/tests/repo/com.politedroid_[345].apk repo/ $fdroid update --create-metadata @@ -1155,7 +1155,7 @@ test -e $SERVER_GIT_MIRROR/fdroid/repo/com.politedroid_5.apk test -e $SERVER_GIT_MIRROR/fdroid/repo/com.politedroid_6.apk before=`du -s --bytes $GIT_MIRROR/.git/ | awk '{print $1}'` -echo "git_mirror_size_limit = '60kb'" >> config.py +echo "git_mirror_size_limit: 60kb" >> config.yml $fdroid update $fdroid deploy test -e $REPOROOT/archive/com.politedroid_3.apk @@ -1197,9 +1197,9 @@ if have_git_2_3; then fdroid_init_with_prebuilt_keystore cp -a $WORKSPACE/tests/metadata $WORKSPACE/tests/repo $WORKSPACE/tests/stats $OFFLINE_ROOT/ - echo "mirrors = ['http://foo.bar/fdroid', 'http://asdflkdsfjafdsdfhkjh.onion/fdroid']" >> config.py - echo "servergitmirrors = '$SERVER_GIT_MIRROR'" >> config.py - echo "local_copy_dir = '$LOCAL_COPY_DIR'" >> config.py + echo "mirrors: ['http://foo.bar/fdroid', 'http://asdflkdsfjafdsdfhkjh.onion/fdroid']" >> config.yml + echo "servergitmirrors: $SERVER_GIT_MIRROR" >> config.yml + echo "local_copy_dir: $LOCAL_COPY_DIR" >> config.yml $fdroid update --pretty grep -F '' repo/index.xml @@ -1212,12 +1212,12 @@ if have_git_2_3; then $fdroid deploy --verbose grep -F '> config.py - echo "sync_from_local_copy_dir = True" >> config.py - echo "serverwebroots = '$SERVERWEBROOT'" >> config.py - echo "servergitmirrors = '$SERVER_GIT_MIRROR'" >> config.py - echo "local_copy_dir = '$LOCAL_COPY_DIR'" >> config.py - echo "binary_transparency_remote = '$BINARY_TRANSPARENCY_REMOTE'" >> config.py + echo "local_copy_dir: $LOCAL_COPY_DIR" >> config.yml + echo "sync_from_local_copy_dir: True" >> config.yml + echo "serverwebroots: $SERVERWEBROOT" >> config.yml + echo "servergitmirrors: $SERVER_GIT_MIRROR" >> config.yml + echo "local_copy_dir: $LOCAL_COPY_DIR" >> config.yml + echo "binary_transparency_remote: $BINARY_TRANSPARENCY_REMOTE" >> config.yml $fdroid deploy --verbose cd $BINARY_TRANSPARENCY_REMOTE [ `git rev-list --count HEAD` == "1" ] @@ -1232,7 +1232,7 @@ echo_header 'test extracting and publishing with developer signature' REPOROOT=`create_test_dir` cd $REPOROOT fdroid_init_with_prebuilt_keystore -echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py +echo 'keydname: "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.yml test -d metadata || mkdir metadata cp $WORKSPACE/tests/metadata/com.politedroid.yml metadata/ test -d repo || mkdir repo From f430c58d0184a06355e9a194a77ea0cc0e5602f0 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 23 Oct 2020 13:22:57 +0200 Subject: [PATCH 0605/2775] make examples/template.yml pass yamllint --- examples/template.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/template.yml b/examples/template.yml index 72d584aa..c9e565f6 100644 --- a/examples/template.yml +++ b/examples/template.yml @@ -6,7 +6,7 @@ Donate: null License: Unknown Categories: -- Internet + - Internet IssueTracker: '' SourceCode: '' @@ -15,7 +15,7 @@ Changelog: '' Name: . Summary: . Description: | - . + . ArchivePolicy: 2 versions -RequiresRoot: No +RequiresRoot: false From 5485869e3f6610f674979597f131c2d93b224838 Mon Sep 17 00:00:00 2001 From: mimi89999 Date: Sat, 31 Oct 2020 10:55:14 +0100 Subject: [PATCH 0606/2775] build: destroy vm after each build --- fdroidserver/build.py | 5 +++-- fdroidserver/vmtools.py | 25 ++++--------------------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 96337813..02d4e5d6 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -74,7 +74,7 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): else: logging.getLogger("paramiko").setLevel(logging.WARN) - sshinfo = vmtools.get_clean_builder('builder', options.reset_server) + sshinfo = vmtools.get_clean_builder('builder') output = None try: @@ -295,7 +295,8 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): finally: # Suspend the build server. vm = vmtools.get_build_vm('builder') - vm.suspend() + logging.info('destroying buildserver after build') + vm.destroy() # deploy logfile to repository web server if output: diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index b32502f0..c231aacc 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -33,7 +33,7 @@ import threading lock = threading.Lock() -def get_clean_builder(serverdir, reset=False): +def get_clean_builder(serverdir): if not os.path.isdir(serverdir): if os.path.islink(serverdir): os.unlink(serverdir) @@ -51,26 +51,9 @@ def get_clean_builder(serverdir, reset=False): end """)) vm = get_build_vm(serverdir) - if reset: - logging.info('resetting buildserver by request') - elif not vm.vagrant_uuid_okay(): - logging.info('resetting buildserver, because vagrant vm is not okay.') - reset = True - elif not vm.snapshot_exists('fdroidclean'): - logging.info("resetting buildserver, because snapshot 'fdroidclean' is not present.") - reset = True - - if reset: - vm.destroy() - vm.up() - vm.suspend() - - if reset: - logging.info('buildserver recreated: taking a clean snapshot') - vm.snapshot_create('fdroidclean') - else: - logging.info('builserver ok: reverting to clean snapshot') - vm.snapshot_revert('fdroidclean') + logging.info('destroying buildserver before build') + vm.destroy() + logging.info('starting buildserver') vm.up() try: From 2fc0178972a1c2e10e47833d0d6d93094103199c Mon Sep 17 00:00:00 2001 From: licaon-kter Date: Sun, 1 Nov 2020 14:02:48 +0200 Subject: [PATCH 0607/2775] Use newer gpg from sloppy --- buildserver/provision-apt-get-install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index de8dd3fb..8a84c631 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -71,7 +71,7 @@ packages=" git-core git-svn gperf - gpg/stretch-backports + gpg/stretch-backports-sloppy javacc libarchive-zip-perl libexpat1-dev From b2b6e62b8d2e6ce6cf555b12ae7404984e90eb7d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 2 Nov 2020 15:20:23 +0100 Subject: [PATCH 0608/2775] gitlab-ci: fix fedora test failing on Python setup Avoid having to compile matplotlib and its C dependencies. --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 29422aaf..0249be78 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -195,6 +195,7 @@ fedora_latest: java-1.8.0-openjdk-devel python3 python3-babel + python3-matplotlib python3-pip rsync unzip From ce46978099326e9a3fe003b020faa324b1675c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonhard=20K=C3=BCnzler?= Date: Mon, 9 Nov 2020 08:24:39 +0000 Subject: [PATCH 0609/2775] Add platform 30 --- makebuildserver | 2 ++ 1 file changed, 2 insertions(+) diff --git a/makebuildserver b/makebuildserver index bc192229..62f4c255 100755 --- a/makebuildserver +++ b/makebuildserver @@ -213,6 +213,8 @@ CACHE_FILES = [ '8452dbbf9668a428abb243c4f02a943b7aa83af3cca627629a15c4c09f28e7bd'), ('https://dl.google.com/android/repository/platform-29_r05.zip', '951da8bf175254da74626824f919bd28def64f8828f29dd3b124a535cf4049d8'), + ('https://dl.google.com/android/repository/platform-30_r03.zip', + 'f3f5b75744dbf6ee6ed3e8174a71e513bfee502d0bc3463ea97e517bff68d84e'), ('https://dl.google.com/android/repository/build-tools_r19.1-linux.zip', '3833b409f78c002a83244e220be380ea6fa44d604e0d47de4b7e5daefe7cd3f4'), ('https://dl.google.com/android/repository/build-tools_r20-linux.zip', From e927ed02a868ebf2bcdfefa94591b2d7a84fd303 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 9 Nov 2020 14:37:33 +0100 Subject: [PATCH 0610/2775] provision-apt-get-install: fix gpg from stretch-backports-sloppy !822 The gpg dependencies are complicated. The previous setup was always failing with: The following information may help to resolve the situation: The following packages have unmet dependencies: gpg : Depends: gpgconf (= 2.2.20-1~bpo9+1) Depends: libassuan0 (>= 2.5.0) but 2.4.3-2 is to be installed Depends: libgpg-error0 (>= 1.35) but 1.26-2 is to be installed Thanks to @izzysoft to spotting this. --- buildserver/provision-apt-get-install | 3 +++ 1 file changed, 3 insertions(+) diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index 14540571..7619a314 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -73,6 +73,9 @@ packages=" git-svn gperf gpg/stretch-backports-sloppy + gpgconf/stretch-backports-sloppy + libassuan0/stretch-backports + libgpg-error0/stretch-backports javacc libarchive-zip-perl libexpat1-dev From 10d5aa6bc40cb8cf2acff9fe56a3808cd87524a9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 9 Nov 2020 14:46:25 +0100 Subject: [PATCH 0611/2775] gitlab-ci: test 'fdroid build' CI job setup --- .gitlab-ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0249be78..21ff21d9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -243,3 +243,19 @@ gradle: - python3 -m ensurepip - $pip install beautifulsoup4 requests - ./tests/gradle-release-checksums.py + +# this tests the basic setup of the 'fdroid build' CI job in fdroiddata +fdroiddata fdroid build: + image: registry.gitlab.com/fdroid/ci-images-client:latest + only: + changes: + - buildserver/provision-apt-get-install + script: + - bash buildserver/provision-apt-get-install http://deb.debian.org/debian + - apt-get dist-upgrade + - apt-get install -t stretch-backports + fdroidserver + python3-asn1crypto + python3-ruamel.yaml + yamllint + - apt-get purge fdroidserver From 767573f2ecf3674a31d6ca4c7c7e05c4ea52f07e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 10 Nov 2020 09:55:46 +0100 Subject: [PATCH 0612/2775] init: fix init with Debian Android SDK packages If the auto-detected SDK path passes test_sdk_exists(), then just use it without prompting. fixes !821 --- fdroidserver/init.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/fdroidserver/init.py b/fdroidserver/init.py index 124555a3..53eac796 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -94,22 +94,23 @@ def main(): p = '/opt/android-sdk' if os.path.exists(p): default_sdk_path = p + test_config['sdk_path'] = default_sdk_path - while not options.no_prompt: - try: - s = input(_('Enter the path to the Android SDK (%s) here:\n> ') % default_sdk_path) - except KeyboardInterrupt: - print('') - sys.exit(1) - if re.match(r'^\s*$', s) is not None: - test_config['sdk_path'] = default_sdk_path - else: - test_config['sdk_path'] = s - if not default_sdk_path: - del(test_config['sdk_path']) - break - if common.test_sdk_exists(test_config): - break + if not common.test_sdk_exists(test_config): + del(test_config['sdk_path']) + while not options.no_prompt: + try: + s = input(_('Enter the path to the Android SDK (%s) here:\n> ') % default_sdk_path) + except KeyboardInterrupt: + print('') + sys.exit(1) + if re.match(r'^\s*$', s) is not None: + test_config['sdk_path'] = default_sdk_path + else: + test_config['sdk_path'] = s + if common.test_sdk_exists(test_config): + break + default_sdk_path = '' if test_config.get('sdk_path') and not common.test_sdk_exists(test_config): raise FDroidException(_("Android SDK not found at {path}!") From a1df5ef86a05ebe405d0ccb3686826f92d912220 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 10 Nov 2020 16:53:00 +0100 Subject: [PATCH 0613/2775] gitlab-ci: try rules:changes: to limit "fdroiddata fdroid build" runs https://docs.gitlab.com/ee/ci/yaml/#using-onlychanges-with-pipelines-for-merge-requests --- .gitlab-ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 21ff21d9..2adbfc76 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -247,9 +247,13 @@ gradle: # this tests the basic setup of the 'fdroid build' CI job in fdroiddata fdroiddata fdroid build: image: registry.gitlab.com/fdroid/ci-images-client:latest - only: - changes: - - buildserver/provision-apt-get-install + rules: + - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH + changes: + - buildserver/provision-apt-get-install + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + changes: + - buildserver/provision-apt-get-install script: - bash buildserver/provision-apt-get-install http://deb.debian.org/debian - apt-get dist-upgrade From 9442a9e614c1fd5ec98ff0f8f364b52ebd97cc10 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 10 Nov 2020 16:24:19 +0100 Subject: [PATCH 0614/2775] do not assume `app` is an App instance, support API usage When using fdroidserver methods as an API, the full setup might not have taken place. `app` instances can always just be a dict, the App class is mostly just a typing shortcut. This is incremental, it only affects a couple of functions in fdroidserver/update.py. --- fdroidserver/update.py | 14 ++--- ...n-islands-british_centralamerica_2.obf.zip | Bin 0 -> 916622 bytes tests/update.TestCase | 58 ++++++++++++++++++ 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 tests/Virgin-islands-british_centralamerica_2.obf.zip diff --git a/fdroidserver/update.py b/fdroidserver/update.py index a2512db6..bcd8865b 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1891,7 +1891,7 @@ def apply_info_from_latest_apk(apps, apks): bestver = apk['versionCode'] bestapk = apk - if app['NoSourceSince']: + if app.get('NoSourceSince'): apk['antiFeatures'].add('NoSourceSince') if not app['added']: @@ -1901,12 +1901,12 @@ def apply_info_from_latest_apk(apps, apks): if bestver == UNSET_VERSION_CODE: - if app['Name'] is None: + if app.get('Name') is None: app['Name'] = app['AutoName'] or appid app['icon'] = None logging.debug("Application " + appid + " has no packages") else: - if app['Name'] is None: + if app.get('Name') is None: app['Name'] = bestapk['name'] app['icon'] = bestapk['icon'] if 'icon' in bestapk else None if app['CurrentVersionCode'] is None: @@ -2095,10 +2095,10 @@ def read_added_date_from_all_apks(apps, apks): for apk in apks: if apk['packageName'] == appid: if 'added' in apk: - if not app.added or apk['added'] < app.added: - app.added = apk['added'] - if not app.lastUpdated or apk['added'] > app.lastUpdated: - app.lastUpdated = apk['added'] + if not app.get('added') or apk['added'] < app['added']: + app['added'] = apk['added'] + if not app.get('lastUpdated') or apk['added'] > app['lastUpdated']: + app['lastUpdated'] = apk['added'] def read_names_from_apks(apps, apks): diff --git a/tests/Virgin-islands-british_centralamerica_2.obf.zip b/tests/Virgin-islands-british_centralamerica_2.obf.zip new file mode 100644 index 0000000000000000000000000000000000000000..d2a334afcbbf6f2c738ed13fc1c3d3812027cde9 GIT binary patch literal 916622 zcmV()90Ze(*U zVsdG8X>({_V`Xl1a$#&?ZDn$4V_{!1E^lIH?7eqbRM*-!JZn$ev!}2b+Ay?56%i4! zqcOIqNj%ZSB&Op4gAkFy8Bp<@B%`9(#g4s;ioJn-u$L%cZ?P-(-s^X-J!>;V&Uw#w zUGMe&dH#7GXaCk+*1hh!_6~<-3X$D$V$_kirV`!4NPXnD8P;AIS@kn)nWn5%Tm58f zMoxw;Jt@VUm18w!n);Zn87ZbPjgd{x&B#p6$m-SEBh1^VOwZ_*-rtlLqqLc={W4O_ zoz-ESQI-YkJ2TywFoSD_+G@6CqyoDPQzonmH5x3oJ|HWJE=bDA$}#r>v3W75VP|zW zBrvk%m^*8Lk*AR*|4zy=^@@?^nQfgl|D8i)frH-2!h)nerc`r`EIY$&?W_&+Gb(Ml z)-+R!IfhNKWTjZmAVMcBuF+Kvdrs*MTKc*cD|555P5sQN!rK2TJ6@1YXDtBkJWaOjbW>)Iz|+$uUzTmkNrx@^yB=wBvr;lmHd{to2IwGYmSxJxg|mrK zrC3b1oXm_Yb7xfROwuft93oXs_9m{D_c!H$A!K1%@~n?Ju}^Q|sJvW98zWD*(1O2-Nj;F;UsfaFD5liz+O@ zsDw>rk%Q2I*|U1Xev+J9=7`pr<_xgDIYyqHk&{AfY;fB*mtyGyo}NNn^gnLCv9Nhw z)JzVVnR9@#(ZyJ6>z~o550RQ}v1E4Ek=0g9ZVs$YGh0DNmP7^F5SX}jRH)#hmgwyB;CJNJ&aDWs=Rs$dYsWWOwGn)JAz)#(+M~ zDAgNP!VmW_^>fMNU`IJ7aD}WK*pTRd<}AVgJdCm&OJ=5%Oa+R9Ev)9uj9wX*EO7C3 zYlaOhktKvm0GP>=D;#-@7Q73Vm@<=yRXQtb_@-F}zTU2Ile+@g)8&=2{uWCr(7{5J z*=iBoH^(#}gG7#oghfpXk>^3u20t@kHw(}PD~Mv-IA%E};~=pp7%roJjQ3;o<(wrtQUzEa{LCDuc&+F z!se31s^LS!Lv70i_k=9c+e`x9Jv9rdFbNz3P6g7N22@gkg_ANf`ViwL#K#Lcz|Z9p zTn737#Db)K;9b0+s(}0d_mbR5D9Jq4O92%tHzyB>)Xu{s9_w zfwo!XAUwo+02!=*794z((P%T9$i@?sb1krrgn%hC(Uxuk*O%Gg0D&ihoc`~AAnOks z72F`$s1dmcA)|5UetMA{u|XE}tF2l#X^a}x2v zRI8;AO+>7-yUQ@;nBd=x@b46pMfkU`%VSkFWME`pBX3GgwI&KqmX+Hl86@yRXXwi0 z*^q98z;HdXnxSD(xHS{$rasP^9c>KwkB0=?gp-Jo_X5%^;h5Z=EgP)o0h!mCX~k6N zZoU+&1==*B1OysuehCen1)6DM#8ja`d%GD|VM|FT?Sco%4Im>Eau(#SEN6f#p==77 zNau>JbW?^k6><$E8=&%a1*588hPi*X1-u`YyO$g2U~JA#O7NW&3mlR;_1{ZFimjIa zXJyigy?p~BXj{Z4#t^s$e9ZcsU__#kwE=O;jB3| z)djlBtX`RB;p}MyD*I(*W}14Lg?_wtC2uO^&i@*gFaV?qLFw%}Ql$+F8}TqfP4OuQ z;__%6BOV~0Ge>Gt1_Wh4XG8oSTsVQcFiRS6NN~MfU3GA+YN#O|XocNpi0!pcEgWi- zSS;P947W<=Q9E&_T1^?ms6MVhVQY#cX;GYq!l#;{gyazCCYjnwqJwo}0>_%rQDj>( z$yDx9tGVi%YqAPK=DxBf0l7zBvIz>D5I*7~b+W~j13gYwj-b8!MCBZsNyqQntExZr zxME*mbn6W@L~rl{7!?E&`kKg9WSaWt2}#XWuT8y4R&eVqAeHt5g@mdnWIs_q6|{cl z>~t80oZe6~d!(4GF17t?yg`)$M*$VaYO5XcX|;notM<>@2_d<5!c3_hrzv^0ex}w& z&9$T0T)X#3tGzfaqt?$}wb5R+GeCOn#p$(m&Pc8Ov-TEx|1H%d*Z%ppywtDO&px%) z=u=y6R&7gW)n;X_{nJ)EiP>s%w$+wv>tE|9v2>Ro6Uh)9OeczTGh}$DSMlNqN>XoD&fmu~fjp_dIWyBe z;rAg8osgH(Gf0qTq(DQLn~`O6wi7jhmXZ#8fT%JHeY8B;N;(T7)%}KnPI)y=?WKBdo$ml25pG;!N#FTUssdi?ki-a1z{|5hCyBPUjyMHMhm9Pwk z^PJqQEOVx-1A`vR1SvNavKOtVq^U8windm~FLRC_>e{|!HRqTzGKGBTddj9-Y=UKl zJnmM71ck-a>|s=qjgSF?}~YvvnUO+QZu`50-R zT<824XjEmIO=-@2q6WQ9sqmZJfN7j*r6!cqOfbEtk+fC2dq@E<%Sid#4Ob4Fxmh^B z|Jsl@6`aO(M`5!-!LE7$HFmL1~i49+{ zTd4i}JuAtAE*zYgjD&=yCOPx{;Y`fV4DC$bT5=;=gR5!swpe?^j$vnzKa z7yZ!#`aohu*b7u7q3v_Onaa*c0nSOb4B}tJ>BVqT(aYsrVm|kXf+}V1>{-j@Gc%yN z3F*cCD!`P}M`&u@uKor6#8O92g?c}mY_ge?orTp$e8|B=$WQb!FFuy{ff+PI=m=`x z|H%7W&Cp*)oAF1Qj+C- zcarHW9W|gj1qMLqiy+WboyDf64`Io4kOwCR&%^)2MTVB#DpCYtuH7-rkxH|>p({!gi*CVK%2&JbxSo2el~e!8d6(IZn7yUHKU*S@`9FTnh?yjCBy%%9pyQBR^dU-KKhx!SD@_^$5S6#ePg&( z@**cQ)5+0Sd`#0oMhdwhCw%C04QwXI0x3M(c?5b9P-bU3F9F?|%P>z-{=iq zZnnZP=a{qpHf@u)PEH=;n?BL5Li@#~n@yQH>7?b3QNzE?)-2KYy=sB&;l(*vSq;ES~B6WGXno6 z6KWvY(%)o)GdT-Ztx+CMDo5;G-MNGNnq8se%D&<&+0Gtu60XbdtS|3jxOb^~FN4pQ zu06m+FJG|dfHb~re8nMYYl)=p1J<9H82qpVe#ly~5`O&rHH^XW_#VO~6J8*AD)EA+ z>n?US*stmF#rG%!FcQz% zCe44{wiJ0bi0`-uN*bQgnTZx}A#ssgB64u#%4Lww2P zFAVngA$ZeC0)5L;XzFvs4;|OdV1J46xYufce(X=7B`*+v>d!6)`;kz*WecI|`G%@- z9-uu30D2XQFCOFo>J=tZy+-`Lr=a1Da6IS*3s7b>r5gDT_B9h^{S}5k2>a?AL8)ex zGyK%?J_bi+7``=53Q)g+6q>b@;ZHpZGT4{Z!z&&T3l5q@8Eyb*!@(ef<53hII)_jd z0^og&*Q4xbz^#o*69A!5YkPn4^2K%hK z_|;nmpy?Z^5+eYrUgK}DZ;8gQ%8A|Qeomn?hX8uyZE)-g!K=!NEfzka(BmTvKWDdx z!SN;(FMUKTSki{dnot2$cHZDP6N0a<&;YbHo_HO&+StH5;;NhQO- z+W^4xI=K28*>BZ*DrhZ08+Lja>>GkG&;oS&Af*~}g5gU?stk?|q4;_w+0=#0lxikG zr>?OE`=BWNVktS`>-2yf#Q;?os0{Y~5%|R=qWPVFQO&mjR5b*kjdk&Z_JBOn(4)F? zn&A&!kr^CU>f-TPfIR=1DzWPf!;d;7GuZb<;33zQ0KIGP20gm~(3?oSYAyH+k{+SZ zO@L0l0BCG5E*S-uMO+1iW}apEMGNF0Dhw}J1iM0>=cwwh09thyv?#BO%ZG!PAwwjk za-3uMJzHghFD-Zt7DPcjwff2P4CDs;zA$|FFag3EQFgN~GW@xbkR~eY;)*pyzvya` zKmK4HyYu)_k5(dseZojaNGiZc!k1S4%iwtBkDu)xLsrK{5x@fg38app6`Am?TM2pQ z$2wlL;m>^7h767|N?g2p30eQcMki*!k;+d#w%v)1dAFQk$)N<(gX^0GZqJU-B#$!| zlg9?uv9kd2Z)WWPn)h+|Q1wv)X1Ac=(bi*DZncQC1FYD;wjA@y7@_@-_wUEJggf#e_1yF+Q;MI0476qTq<- zh#zreHBcUDfcI@YMZl@E+`tXXwg5Q4A+9J9z}X!scn-ij2MFc!`gqKOvjkk&mx31o zJoIiAfX8C-rkjGc%M28}4B)sbLisulA3i03YgBZfV^$#k!QeHZ?Ti>)aqb)eOTVSy zA^`7fTkT}~XqzC@@fBse4Zu;mHvy%+Auc~CXuEG11swpc+Pf7fUp2&Uo}3`y;hhxR z4d9DCgzbR_`0BaS1U%+V!My<9yR(@bSpr^EDwyvKm1$qH67f@q1EswR_E{lld$F2= zqt}YI-BuS@zY+F%!zP|5fY%3+ef}AP?>s+G!23J}FRuf`A0w1kWALoM{vzPhmK0pN z1@Suy=K^JAJ^UbFpnTn(`sA{$h`+UYw(~q^Ed5uUgki)JTMpRNjf8MfEMBvNSdUR3 zqg+b?9D05Z5I(MtFWw_IVD#H5B>`UzT?F8w2KZdL0Q#p;$~oH+UpiqSu$>l<-xLU7 z$k!BH1K_;l^MLYvJgyo`4uy$|rRiwYE-2Vj#slT<`XrMwv1&@T{}AHGFP{oz!|LHf zc49iF5%qTav_BEQZ5{!q)Wa8V5~DMTNfcZUV0keC2gl-BBZ+mGHe=kui2&M9#Nw(A z0%ga~=q48&NBo$XlK^~G7gr4yD7%RMv-bqzPb>n^Q5K8G?-nS#&!FJFbBKR8*AA3B zLUF;M83g?P8$FoU0*sz748*)p*=qzJNa({5*LW54wqqzy+2 zgD1a%yvY1om*&MI^Pm@b`MJTd*&i}P5I}=z&9<*x1OYP++LV`m_|1@LfJQ8%(D`D- zUmejF%7-sLwLKi5art8314*HJR67WVAUtLe259OnvFHFaWMl_OYexL)T_ixWbrf0* z(5Wfy4UTnz`0#GRaA7c&wGE&_6~J&)0G@L*0-&WWDYPCUXu-pF2KzgVhb|2UXqA#e zw^t*6#k5w?NCn_`YXSjUpGsvdBmr`^B^;F>zP^eu-0~Bp+FJ(kIYPRf`+0x-=5QE5`=(NclefVsT~B~UDgb}jN*EqKN}=fh&3lnxa2z$@>RojJ zIx&tyy8&ADKHlJX7l>ahCtE((kILE)(5xz;+KTa=CjkIm78|KsgyB1YCK>SMk>pUS z9b%IJ5i#okKnwiwt0E%nZWg5~BauYZm}JB!PDTOrShRdOKvkyzx)_L06%gfL_*3X8 zK!06Bl>0G)XV&?$fX;y5srvS}3B zS&sOEiUtP9Sp$Am0vbwnb10O*6Es{3(2P*LXB`}+)LXRt2!M{2GyrD{!KLfKqon?o z6e4L{`Xt(b)jn1yqh>fw<~0m{%HkjZ!TFXwh1rS{Z~(4iPA}K82PO zs+|DMHsD<+iG~RZ%5V)pn^pj{B7n+j)`3FnM5x4w56l4bNfbOjUs4^Jec}t)l8dHX&cO!lxP&syBXaz$6O1eVQNMC0fc`*?jd)!h4}+E{@a$kg+%4(k4u)?02?%wCb2y* zBvl=J4Ri|zBm8JeT>uMmDN_QLEGL9-e!~x@3;=A*bjtKEz)swJ1B8xT{NdRjfKB*? zViy6Ma|JN_!+v=DG=fd3OL<-*bi)bHz5Vf^!@mJGy*0&d0k&x7d(zP4;TMCUj7jGn zq1YY3)*K@8)&kv~-vL`3NE7^hz~)sGdAIEd&zMVgxcnEoLjoS&PCz?=AKvEzxaJ1s z`VhcJ`R{=1?g6-XG0|q@QcCy~u)nH^#1lDq>DEDz-=$lvbc^%$f>-S!T(A6&U)cKt zR{kAjy72(0I`bJ|%X0CqH)Q+!7|QelU?VD@0@KnQJZQ4O^v_=@_zJ*P!+_ASA_rH^ z7Qm`h%5~R4#Gku!3cxeJ<5Ali0Cw^Rimf^f8G6BD{eE{0b z>W>e+BSyX3jP7DOU{j~v0J_nA@vD6Vd$fYm?F4MpUzdUInhj4}Nlf#i6{Y)71^IRu zp<6T%AKE$)u(y*bb`1*ZAcEO%{1ca6&Wn@C&|b=O>q*34zIGF^;lJTg&p}U_;wYti ze*wDLvljr{Xu}6K!vV|GXDBxLB80(_i=^TDC*E`OAAotzpga!)cIY6XThtGaSP#~g z`7NZ_Yrt-u0?aX?KYnzb@C*(So#qOh#J0ZxySW76TUR>+7~YM7h1bDL$DRYGYas9r zA87?(^cSKU>lwgY^@DH*hJ)YJ4zLOJ(%IQO_)o@ zk?{!csQePZZ|hKSUm?txLxuz4bO`QQ!(dF8rFNuQ=l(W^FTMja(Qzx@v=O30W|5Pu z6965=bcTO)b_O&rr)MyD$NVaxdGUn2vua&K$UFyD!zd=}_uSdOI3COSQ)gh%UdNK0 zB>UquZS<~t@CCEl8|*Lq@Q!jVAVVqQsP^DX7jys$1D3L`&l`o{*xAp@?ONNDCtDRL@^A3vlCj6iz4 zV5KJ@i>6ZD#)t6bPoS`_H-;L>;)~OuS&;1vrpU|~zTip> z=%&ICHW~rh{{`iCpdMeaFb4V@H6AyGXi$;oLUtSgq)Lk)y;TEpawbJq#PNgH`55e% zwD{_In7d`?-#ceg`=dD0TxQ{Od&uJ(W2pE+jrehw!UXX{mU{v6sDiRu)|fxBHp1W- zZ@^pD5_7(aq{!yR{G3VQ2FE=PkH2XEF~wrz)db2PUY-s%1@ja z0d>?5FC7BMCg=K7np;izQ|EzZj1L}C$^*i0pvdE<{G<7RT+-uxM+oBk4dwQtDgWd> zXi)8g*R1ydB(Rv$ylBDi853-9yzs=kM#E9d!x1V#Cp2}{6uFkj zkJ}A2bJh63Vc3tn{$CWik;q@X77A&~7jKwHv~Dz=YH%}=UwQ&)iahaR|uz2WWW^@AVlPy>rxE> zDJctqxu3`5iwMmZ7K%Jc!yxF7I6UJH+0XaX*&O99 z`A6eIpgd^tv|@rJiKpi06I#& z4&`TzmKyBKo4DnUHc7&VqbislE_)J)P=kN zZuT*dr4A8p8y8V-rIGxB@gV1xAD(xZm}kpqij+n2uT}xK%RYGBO`==57>b)B`4c5T zQ{;!=ts-*vcB67OM)4C@f}CaEc-1_}Z1O|@5W_c$e{m4Fo$r!zs;^DE`2F z;5I{#_Y5cDd;B^@_SEBxSM`BP2m4t~G&oByfE^F(@#CIk8SI1gxOyF-x!8yzFYEEI z>^7)Kp7_ZqqTBWMl-uii{L->qA+_APL3Vm4nIcnT`HPRU4fY|Pc-8{q?hoTBawwLc zR|aybJ@JS`#6h2VQRHMZ{>~vYgglR{UXq=@Zc8;dn#jM}V}^0i8~?Qzc@~SO=bv_`o{qUl}aB>PhU#wPu zj7)*F=Y>a|C)|9yQaP*J@t02n%_u$IQ3YBn0%?V_m$%~&6{NsOr^l18g54CMI?C-{ z2fp}VlEG2tiK|9}-4u~GDb2J`_)$-PGT0aT;#=>C2K5RkQkup;m?JYd-g@Cx;|RC- z?G!nm#;@B7kx;3_W7ZIEO~0hb+cbVtA<(S!#*d1@4-~BeXv|g3fu4`t?9TMW2W}Fz z+a9OT!-X(JjDm11_QI2&f+r|CWzjp@`HK*_qXp-=RX}LEkX$JXff9EG`j7X^AW-j( zWbmos&yjc;TQFe=Jgt!9>eWz{6kl$mCTP#EJ429NO8jiO0+1eJk$(V_RUw4jJq3QS zh8)k&VrW0$_!rwO2K#k6KCq4;DH4jj=kU^F zM7Obl6gd>Y|8*I-?c?y|Vj^dv*k-H=;qM(w5p%`g< z%0GAlZhefyyCxEvHQ!M=t3vrr_kiXI*m??~*{G#7TSNJh=Rh-@!*9kDWQ&+w_J{HZ z{sfx49KLs+*kH#4N;4;%KeXXHgJZoMKYLBI-jhaY3L^Mdx4(z+h{dON6K;nblxAcE zKkMT6FaW9WjwwX9$`ceB8^M2=1ISV(UbKk#&Pn>x#4#g+KeiLNT~^{lBMEX&tcyD$ z_-DY)v4f?yzN8hkj^O9a{SKl>fe)RB_Dpeo2u03E@+Zx6A9w~n93ME1O_=sQ(F~y+6dUCGWd}Aeg%*ZlOYuU zV)31$a)2V}s}x7^5EAc>_Z%**gtJlBrA5iU7JxZ_K>wk@S7*Tfm2rzHvI&qUCWB+F z0#{uoNF$OwWIsZxh8(eD_fSYI>s#XL=hd{tO8ARcmw@!LDuiEbh3-Sy>;*w|tfQTH z`=R_Ok4{K-8UJkad@?szAbhSA`fO!)4?3+am+=>m5v<@i!l$l5cdq>I0L7+p{ETPh z?sxZLgs+be1nlQ4l;=W@U$c24U>}ac1bB+jrQD&|Y=3^+O>*;lVhzF{CWHW%ae?yO z=FiU=GaBT*{1f4IM}qo=bAykg`_1?*uZ!pF`80XA4e zu`L1o)s2MbOu#mcCh`hqQEX)pf3<+nRc}Ig+`TZs#stwu=}9m@>%>5V!W{Hv)j3LOVoQ{R!(*(=@?u5HB6ngq}&kacP+ zf&N@7UVt~|pUnp7HTc3hLBnGS6dKcnuigst*p7V&UtSds(CN06;m|~W&Bb(R8g?T{ z6VU)&q@N2o<|pzSP6JgXP(4~01<-Z+k%9d{YktJI9tQhR2f`O;)dT3Z7+e=V=F6W# z;=8;H;dhr}0D6q6edj~0R;+^IXB}`X`7;8r=gld06tEE$Fq&0?sm^R6>c5*uv9o|} zni>VE8P0m#<{QoxqNw)af|6SM3fO7{S;>#HLTj#9uLl><*!>qW6K z5VaQzqYRF1V99d_!4Fu^`;=!PU=P*+&na*Kubva0ex;OdF<=!_fX)H#y5<#x02|n! zVz&XCJOk)1KzI}kA$o>>EXvDA{G#JPw|XJMOW%Su*{CEcZw_GFih-^Scpf0{6WDr- z#n)eejhha1<01UFor3US8^)0Q@(Jr$TOk$l#rWsL7;#G3cTNXS&b(|13!C((S?!_+ zUvQ}a9D8RBNiOVHMdGzh6hH24J^&Nz;sZm-%Ukw)M6t3ueCfquWPZ7f@L!9Fg?i4R z8c&Vp3)Yh;IuwNupCRv#*j@`LHY zSAYYv<2}WzwPyUYB9dCRorR#C6%W`ne~O)N#*f%QSl+k+HlG5%$j;VNEWZVR>@nGS zX*I(477=X0S5(WnAMx)VL(4t^$cnd+<5)UU)Uq|dXI(FYW6)I*S~Z1I9dFI=7z=&R z*qaEi5*)aczP7O6ZOxxqmus-EY>q4TlQ-n-Hi`It=VQL)XokUlvJSpieu+RkJt@_s zHvFmOKSSA1#Kq-;vG$3Hv9c{crvOHjOOS_09jp(~VPDGdbO-+OvAzb!@^c99I8AJI ztP6$ScHpZQLjUy`4(8o_;-2Sj(Yf>dXQU*aX^gjAA58OUr@VbCTTNHwUP? zQv3?#3;x9>D{KlJ`qVk%i!VjZ-+aM8duTN{PE?9i?+Pen@5&##2AV&FkesomMVv$> zr{Bpqu6N^?PV8l{-v;$6$g3`urZc5_-i?2905l&3(9*ee0Md)uvgl|2RMi&-$6het z;0s_Sm0u6a@a)h0vGbo8?Dy;As{Bd<1&yK5zF+tg<-Zsl!{CTFR6({>Mf4Uw5BY`v z@akuS;~>bow*}l+71K{V{UqUt?bUF^$BGG6{3tOq_k;nk3!F$RJZ9Y?A}f9sW%#To zKl%07&5xjW?8M7-nbVFI-o zLZPK8{IUFR4EEKn@T<$jF;pF=QD{{fe{UQxJlYb!yCy)NlQ$63&sqD$i&B2ZY-rU= zA=VFUdy4+{GDh{K_=bBt%kNs<-e7-g#3kE&0kP>RQpEE2ZvO*1v1mN63I;jVKfk7( z*dCUz*aXPZIxsZD0IV9M7W+DuU-0I0gZ)5L{A`yDkYRnq8#Iu_gh(DS(bw zHR=XM#;N#;8~$Oip9{xJ#~1(^Pdj+WO%=akQ#VN44RCdd29PO_Tu5;hoWPxUJhcdV zG}X*FQI3jVarO)0tF0khVZu|*OK~A@&VlnhjfQR<#!uDapDA(|kR{}UxcYc}0oiFu zFS?(5D*p0n*y)8Ryyphl>FNgJZJ3I`_z<`quZKsRhmlpaL7aS^sQ6cBU_Te@;!|YI zRc)Ff4(BSqbRTdV5rdzQ8#L8+I!oH$feqGwW^lZSz$2cLQ`r3xr5VrhOP2$;>c)8d z8t7nE2Yz(TlDifHvNaN~SWIXt=w*YW#FsyC56-mO3s1ZXU61OxxYG@O{Nxq!!rZZD zR2(2@X%A~3X5bf9HGoM@imS(9KrV{5o^If`&29)iv>MNv3prPHyPY^k8Tjg>^`Q!> z@q^otm{bo$yR9ZUbMj3}_Z>aP?cF!5eWZt2FSXCXz*Vs1}@}jd%@V;P;J-g95F^`xeClqP|a&QE~j?3;vKA z)%fB&=vp|>+f>eiIKK2RZ|7vX9`?ieiL=L=IKE`L0kS%WS5y)?LB@fvwB4$wj(k5A zCI7+MBu9JA_1NV<)_%`JW2&;q>x_J~R{=BD zdk@;{dk_uRt(A_|T|$Y>a`Y7=mGqP(N9%pd7AsaZ&PQE8J%&c13bYUPpU&KsC8F=z zF&gG8Nza#mZn$2KlGifaT;|3uHotBCkDIjZ+M?~pJzART|FeF*$hO_bqu#l>{@V7+ zB*{6(ZvkpM3Nf<&~fYE0ER}IT5w&{$;PL=%eu79(@%XP}3c# z=?E0_W6T(oJp^TGkxGf=s2oYPDz#dvmTDzhS&zn_dw)QlrZCnJTLQL%DP$}yU#F5c}>2fsG;#v+diNWKtBb|cnX!}A(%MFa{{El2-o91`o7 zp!|vp));*CMtyTxE04wju^x>jP5H*({Zxnsjz;s*4|7rM5|qGb*hJ(BR$Ef=Y5|vA zhx55Gn4QqnL*m6T5qi$R@LCk6362hF<16^K&Uwzx zXN#HyBF3PQFu|cRX)~v69u_?uDT>&f&n{~k!ysG-NkW_=2p9Wek<0R-?CmBJE`Vq`rMyp#%0IpTtZMXZ!8nl3B~=Ctc~v)3Bw zb)MdyTD_OBKtjYU8Tk^9B!JVc-pwv<9Hnl<3`S8Mq7spsfRo92feMdzv*#Q0!F3Ft zK{0-b=quO+3wY726C?^+aCNpHVW-E-A|$Pq9aP?4#t_{&l#qulni-5w57tK$+PH3V zvo?N-2~0D&(-rK;E3Z2h+q{om)`as4=2hN79c3I4v=E^|d?B(|GtNtl(7&g@;D& zJWqzGTll2vx^uzPKiT^Ye6=!#4=+`^_EY#mTwp)UKK~CKik?+bi#&w|@hBn)G2y|C z%Vo-*zYuoGuRg*aZ}?g4z{Y=~z&4sF-l^j0w<7)g3U+Y3g7ehLm3rqcC1jVU^PTkC zuOsGs=$K`QlM+qLq`E0CUiy9z*9g=upDN^%D(fnhDu#P8syu3@S>BGs- zRq5FvmK|f4C;WsGrRsHL$CpkE6wSHF#V6T?jRvDSjk`-)LlF?{JjRIReBm`iOQ+4q>_Pz=^_XLLQlPoL!cX8U00EbMJOqr@Yl02a})z z3#`5eDIyUW!2(Rr>2nw7S9lC;$a!|piNjx~Tl$!6_*3Dpy>RM|mH~M-{Ix0BV&Odg zVaiG&|8bJpoQd0+@&+FF>NcmSaAt{V5Z4FKPS(7!E9hgNDrYA(h78d8MsE;{{?dz4UtVmhtLvc7V4CU zy0numlddJ%rfB(8A}4~=&t4*3+qZwKP($l3OVCy{3=ME5cw+FIM@z^maPpZ;q_49x zqw9Y5bKO8-R0r~rhAcQPE;znKy1cJKZO|xnK3Z3p*iVTIUN4nS%3(ac8Kn0@t}v;r z5EtBCB`wTj8Hr9MVcddw$>Qarh}F{f0|FUoV}HanaxM`3cZs;*>1yfxJc-gEktqBa zmkvb>#0Ae+OPA+KXG)nK>twTrbGDPLY)nr917x27P zIw{*n78x88Ec?Z?vpiNZurAX~7a7~$T9dzqueBzW^lH5yWFl{nR#yn-CA)4DcAdBuw{J+dW~$@$Is?nG z9W(~DLBVOfB}VT733^T=<@CPlXjOzxBaPxYeKe=jx0V^?zVUv+iAboXljae*9k_(y z)za-2O>}eLj$tv~;!<@Ty<>t=>;7y?^G4B4vU3yag{p0;eW<-f)ht?>=$F_YGRx2H z7(){haBud|?O(Vl9hMg;kwgSZm~dC>dU@zJHQ@c5($#sqM56bQNIYE~MN#G5t-zrv z7d`B*^kvqUt-k-Y{_jlZh`9M^HR{=AKAM6I!Mec4+Yvtub>7WrIwT@5;;$=(lWD?* z9=$Ey**C~r*ClP>B$Ral{JsboH6f2sN;%3i_5S8JlG9P$b@vOQ#G-WOgAThfG+%?(QmMvOlLD{zy6{FMcpuk0PC^@$^=K z=T(L~#9SFJ`!nZ0s$v{y1*qO@A=7>_YBm?O|3z!nFGn6rP(UV|iQ9CUjXs;nBo0Rb zzxLHNQ6~8`Sip2|;@>OdFlxC4@#9dyJ?1bPfxbV5I^9DpfA$)Ox}HH@ucC}`sQzC_ z{=I4o3T<1j{{jZ}GGyRy5}JIg&2ALcLp})A>G5U5f2yvdsEn|osFi=T0te#c1cipt zN%bn(&;Fi_oKwV0+Q~E{QEP?9Gs;U5p#8Mr$I@?fBN%Q6itdr{QFD*a46QDpohUGd zjrVJ9jz5K(?n5|_J;1a-hdwf+I`OLEs9pNEU97E-ps-d0i{hIDZarsE{Ysr@QNl)~=-DG8HxUK3la)))GGEE0QXg5*)90V8%SyidKP&$~wz8gDS<-X&(<_@+ zEh6<(dGoRKLLL|6bnu%SZaZUw&3`6+X&sFEIiHu6h{1H>ne=tlCBtm^x7nn)$?j(!U38;@60;)3j^b62wkK zO(K)J=W%sArYP!mO_8+3{@;3KE5D14@QSIc2^@?(qaaX-ar4C3P zhQgwnHxXJGX`gi@o5*|KEZAF;mE4g_csO6Sr1!^H7%0|1{2Fl^1tw=tLI+VP+5|nt zfN5v}3i2F-`Z67dpiuKDp{T90u2!i=T84;bBwBLvBNt7C&SV4PT7Hw2kz-E9-O1k`v0+OZ zZtMJW*f_d9`A_1L&895e-E6`+X81+^gJ4r87XFiXTU}1wE;l(jGY@yOSTZ?9JK+ym zao$}r$bUhPKeO0!@V7wSA+NWY3#pu0xw>)-t{h&uy=qX^U|hKtes9B-lPXtN6;*EL zRGrA5Y{BhKc^uarI=ejFJv$?Z^QxRzxuJ4f<@(Ap4FB9wSynZ8;8b z@oJ|3h&C*{ONO5lBH+>mbU_yC=^Yuydqq2^58?z5tA`R+uwds!bY2>$)&vJ|>Ht@e z4L_Jq7C=`#;SyR8V_qkrm3Zx#bAP8l(0RViXO_#p2}Oo)v%db?fF*k8RK9=d>>*Cc z!-g`mWeN`?r{w)qu6FFw3SmJV&ZlxHgt3sypOB9(?=Z6-~F6id%S!6*d=QVdevzA$o7BasVqS5Gw)68(GbIHR)MPx~R zF63k}b5v&zwl!aYx+nr#*ZXV)O8vuuPM~i;_xjwco^$!jrNgLIW-em#;RG~+;XJj9 zLgjeU(6g-`AQ_dN{PhVUm^+6NF>e<8j%+J^kHEkaC*6zxh?Zm>%+V>UZJjo zDl0Fd247Ol4CC}j#(T=7o~{L#4hkF~r`;%KE=jx52Bh-J5US$CVrBy8D?!0NhzW2t zS#v8y$tRaEi`A?uSTEOvc)5&GRw+mh=R9XFWsWOaG{WKivO=RiY9@2`x?y_Kzi$)O zd%A>KsMh!!ICY?(+I8`<|G2OK)Em2$c`UbP)Bb3WNC(X4vw=Q(Ly)hBpUaOP?iUu+ z<@`1;V;(BK0(?ECYJ*zFMtSkUABB19T}vJ7gr(4ijV)p9%8({MwICKGVwOA*tuU#C zS+CT{b-r3w?dNuxP%6;IaE9H>nJMg26ofkb&@>{jn@$oG;=?vng$SLtQb|;*d`>Mk zvxJ$h)TjcniVJePY;tU>F~)M{q)Hd;tJVhjXk2Gy-z(aD<_hMeN~dIX9;{sJnpIZs zr-vyoTg!}8h{Ni#LxWyISb`CYN}03LFfFaMJD(1Ap3v4(X1z2)CF6YMioj2KrPCGF z!nMzSVG#@)r%Rce($s-pcloKyz%CPz)!Fo4n*Nr$YEc=pR~qIeSMf>(r;sYx7GY9n zz-mZNxw-u*Reog|b6%>EvwF2m=^QsKZijY|%zS|1HZXGy zqg!)1{`8$paS&iBGfEkA9};o z8-d0lzXixL4mIiik50B;1x%+EjN!++gV4wS@UKEX1*k{YkZI_TJc~ZG>u+t%>=5)@ zU=f`_4ww8juX(QX}Q7izkHuC0x>^+UBUd&x9KNeeHs|~kEtk0{=?6~3(&XW z(_z#IOk-MfTZZD9oNi%_iqLmo^wUWeqn=+dKeY_gK1W|E8YX}7%W%Y7qucfT>9fTs zy<_wEgrGK`CiL(!$~oFGS?l=eV*c;)kU9Ojg)_W|s5>Bi#DL>PUpW-AUqN z9?OklR~|(7)TYMur&gSmjRW6x(-bm==E)Mg6L3s?!^p=%6rJ z_Au1*tF18AY)8@kB&$)Q`_gAH--Pr2ighS_1Zvx>PKrl&{YP0(kgT5a%YZqk&Un=8 z5Rz&Ye$u)!Pwyu4Q3c`}d4@`S-lB6-9G>9Q%JU0tg7nwm=4>X{5tSiTG&3AU6fqrq zx!->nkQy8x)H7*1@@&iuFwRD8b|dIT9UjQG?J0LMbhOcW2W@`OUx&gsM%R`8D*_N0U0emZ=h`3!Yf=|Kj;loHS`Fm7Z4y1 zk~K7RZQX$Lm$a|*3cWy|_xflYs`H!i^Urd7Hp@poM-hH3m0yr{av<3f6tNfmtBW0Z zXZm!MwJ|hL?64PYMDu0)rDM?qbQTRpo0%@dnFI%#ffggxew2cL3%B$igu-Va?IENy zN2g3cCCtE0h|LZ9sP7=;-=G*(DL&1chCZ3WNU9ND#0;<`4noS`8um!KipEG&{wPK% zQ&FdjXe#>tn9>)W`?5h-!`DnJAEGX zy>gM>9VerhT@3Rj zyADMbAf|V>PVwJ&Fs1j819ItKXb)nyp}1W23nq6I3Q1|%XB*SEQ735u(*2`uF{p8Z znTi^!=13=?2IwjpiauwCpnpw9=|fP&GZfjq{zUWu_4xT5`uG&+*ik-k;GYP6@lCt$ z^&{jR-k~_EB+Lfr~b~J)yWM(h5yrc6RN)g zeLNY}Pr*NS>l-`^twn~-%wTi_#mz@tvUWev?ne`)U3V~{E0E8}Jts5u)-WSr7fmiQ z0pl5Y1!AgD(>YA57bvp|h3B>k9SnKw8ZyNVMRDCnBmEC{6g84*`jj~$4eQta>tV=& z+Woef*$pBh<|BO(iu<8o@?vl=-cSy;M zkF;mmo>EQn-2df>|K*7P<%s{~h?*RscjgFaH6|V`+zqY9V8mrFIfpI;K10KpzFDJW z579dGg*oh_=(cU@CA4j7j_={UkCB{0es56QHPWuPki??@Bf3v)e_b`>aTtYcVwyBS zp-lhi9~EAlS|``XE=2Kn5w{-crXvkD8orBpjT+xzqP}JZ$cvcHdr?!@M*%m>g~_)O zhl_5YE1|{c%Th+)<9GdT1l>`iDa?6U=q_}J!P5|VjU;U|MYunoyMf*btiOVmhfCOS zM%pk!%CON=SyWx;yBsZ9`0~tpI>{Zqg7$|QP@qvCNIxdnv0j|5uAtpfzKDtPl1Rhd z=GoyTWI+(;vHB`n8|7P1{-YFPr2siccE_AGN3I~E!}+V|c$6n2_18-oE=I1v^%TfC zg6V{J?Ds@LC$FOO5y4227{W+fIEOeg#hk7d7refTmV`&Bb+Mruk9y9*S-2gzA}+9B zLvO>3WbkJsKCUtF^k!i}A{V>*8oCtfAJ(p&Opo+R-Ve*Y8DE{Rj@RgA-jXbthShMa zM)nw~6X|CWFAoT`5uAP|Ft3wn?%3(Gj}AgA^KTXEJSMWLaKfG^L!GnQHMBZH6Xu~% zhx1a`D0cd~sN>da=x(?UF~J@ZiQDx+*c^?> zUq|^75ebS^r!zQqi0g>7E_i+3 zjD_f%x#*A1-v<^T?=^^-jC{Y0`=mpov}P_oWo+^%T(iA(2TWqV{8rUZ_eIzZ^uwR1 z^>pOBn_;brj{J7?!)cj=!G^e|iIvEhIjWez*eCu*bq?kL4qopNFG> zR1H)xXAqS|BpW%+-e#K>8XwH7d_&zn1X>l99KdOAHXAKB>U`n?w1)bw!+!Cce50Xx z+pJPy)Ca}-dj>nhMnaK1l|o-ITO@iu|@W{dR-olNenl`GuCY=S@xD%%rp{0HJw{RrdH ziKCrb={(%7rx4*~<57`Z9v&-~MbuTe?tfn%yk8D%8gd~;)6h<7F(bXq z%$G*B+ABSYdM;%aqrm8QXdGG~^b5>CyO7E<@d+UbgcLgoy;UfDFemp7ao78h^OL{H zXsbM0B8jRaald=NxlfQtzUG^Z$`lc-JTP3Ta4&7^#RU_lp#5@*)?32p+`kwZzE@nZ zcM6)Wh~wme^;HVD&;1_m78gvKiXO{j;{%NK8V35gUUC+e3kw3E1(=FP%e$d()lI!S ztDMEzzCi$?6}dYV%~p8pwK}y*tx>6TTA7S)s zt|&tB4ye0pQ9{QUeGKEuEQJ~(Zud0wTox;l#MGBCbzRldK2{Lt$8k#*p+DvIIs{!n z!fO|DRb8eV*p7?*w4W&pGI94D^1tPUJ6g@;?%0Z<7~rpJ{^v3||Muw_S>&%U!_sfE z$X}?&9n7|jURkz*1?p~7OWrD7y2oX1kOy2C$Zi#DeonfxqYcr zJpa6$fC+DvdYRPQQz~=obxH{s$Z3wF*=%ztz%9fAENrTHkrQ1a%V&iW>ETOXgc0;Z zF`y8JgH?mMP*06tm|ksg=0$Sr{^0OE5{7`USDjbs1AKL!f$pDRo!WDU;;&WnIq(o) ztlm1y0+JerM1CCVI-wV(0#7}s zxKaP1Qkm?G^AE@O%E_~x4IU~34RNC|LJmD$U z>*hDw%z8@0mmob8u?RAVsvYC?9Z3+61fzka7dCpXtbYwTzYltNe%gu?LKP`$e4nzD z^&C0D$&TaiH-4*B1vm82H}hqc#z0n3*@MJ$_4&QRKJPXzWD{Xr6JFR)zq{&6wV>V3 zChJ)zJ7}x!3s0jt!^);BSAgXsYgt2 zwv5$rD!qqF<5o^yOce0CoOfBX+p6qt#?SyST)$DcPjHA|ctRp$CJQ+b#r8aPS+HXu zDcVz1Mowk$S93ltRu3wj`rmC{#6}oBjp6=!e^+jKFzha+&TlbA1+nJqrP8=j&mj&4 z=*h&_O1;5P@9A&wa8vX0QF*c#r#PLsSqY7b5S>L^tM(X^Gr1ohW=S+SI;vxI;x8T3 zVq?FJO*igD$u}80a~74M=nk~<~BS9c&5Ro7v;@4e$?{p_7Z{GKNzu%MR`Tc>&JyoZw zPF0=#RD;@ipz3`%4Rp#Y&l}VJp|bw6mGyjT#g%7W&`N7@HeBfRVD!L~;C0cc8 zS;naRVajaASi$6nPq2zB>~XjwPBY=!fS&q#E{5)(xDFx3Df14OWF`1+UH1jPP6sAV zLN4CCVk=+$0#oGZ#5G7^IZfht)#5-~*L-2z8*cGq^HEPhtjI{@*T0}AZUBhycYV*; zP~%a0#P=9Ce!{4+<8vnj)@J$Ut{=Z+%%4nKlH%(F%LdC1_KQ}xrg!TyV&4Su#25*-xf3QX76z|;6?0-Ql8G(UGVmL)AFKqkV6UuFtW#rE z;SA`Z8K0Y>ZCqsMIi2+sq0pYf`7lI_Ludke{0!;l3BEEx16ra;`&s*HGv+ym3y(q5 z03t>nF)zNMJ{Bz_^=l0=D>^ej%f1#DH$W!fqzqSqm4v_ckLIyGTzmk=2to@(V3P!g zcAL=F;`Pu)5CJDa_^mDc(%_dm^m6eQG6q3j6hK=}_c!n9ebdObq+}CBkYI0N$cmd; z=w!2Yb%eug@spRIV2x|nSh9qK!D}fH8c15%r9Zryz5km^_LDHITd2+f3)oKXnw(C-U{oFCe-R{qm9r2yZe@DWFTk2HQW%<-4quwp z#--DVu(50di3kubBVmjssG@R)EHw#faL%=tvWu8jzMu5z0@)3q+amNgADc3!rTiF~ zl^eUC%QE^&6?@1a%|-JNpC^zoqe~mNX=#QdpRU+WIy%OAr9%Q?C~ZvclP#DZ8h9&q z=|p)93y^Jpe*c+`g~mDBQE^5;N1IIXaOB(9=9=f|Sj8ezVc3AGn>4l~`JqY4!xi(X zyp^Er84!5P^5Crf{!C_p$13KKl%z1UEYTL1U-^;QyQy*&)KybNN9qJibKLr;&oiQ9 zcjYpeNmyk@?tczF|7%h2Q9GITr;NcWi~Zog~^pu_D=1@;EfNJR1bUT3x_g!1NFI z<6|_r{ZW!rBMPqsZEDNf6DD+T`{ghdaO#r7<+m)wQzuR6(e|^TLdyvUBgL(2a_Y1R z-O^zb=^?q4o5|!mV6yJ~)P%0&F1#|fB255^z7L|PB?gYoy9UJfJcZsJyP@Y1Kgo+cRwM%m2WsE(A50dNTj8-Uyh ztC|4X1A?BBZ$ssIP`DE2>;%+bpkpUMO4!J+CKog5OjSe}3HMLq2tg*G=&)H@bEa-M zaELUn`z$b%1I0Q&RXsXSMFdgQ$>cf+8IGiPUz*zpjf>X^F19I+GhS@jx;0?jf)o0$ zL{RS;%Gz<*@7#uc8a%>k0HTDh3aAh&IRr3`4zn`q%yI*}ep?#gem3JrfFtL=kVQX} zJk7#LAqB!kCZi>BI?Dyz%}}(+ODrKN1R*AC%Psw=aY1%b zhskMNmP@UFK0E3%Y9?DvLSH)u_-#3AC*H^`s);(vx&Xn30HI4y=<7sf+hMQYliAT% z(Df{l&>3|+L0AP!O8Wp7-O>9v8`lj)_i zx@WSzTA6y*dy7i?Zq`gamo&Do=~$Lhb6qPqpX`iyC0E$yb$tiVr5CE47T6$bluPh< zLzUy#g06#R>MFqsoh$7CZ-V9Iv*e>cec)$RBMNTQZsQ!Hpz-Zl%Wi3|Uzr)EIkABA zDBgtI;fq_ttXs0@!$U^;FEcZzm2uX#hfbU%_CB7S2T_xAt}yM%X<#(wmYY6%_wlnn zW3BrN7I9`S7CUlT%f9m`RD3Ebb}?nL+PzfLx>=@w(^r^638b#7+Q8KOBv@S@=u|CS zPi+Tn`GYN+vJ+iad6e-f;R3H3$+f)mlNw&iz~@&rvmQ>$bF*@;wU9~gZ#DL|KdRew z8^KnGde(I9U0dAsb+8D$0e(JaWbsXd?kS2~uTBF!?jUCX&$wSt2aCwgiF#1ck?x$> z3|B$RVR-oK?>;z$>tlA^+QJN>3i4`y-u?P?S6hp-xJ4bxJ3jt0H#E5r_@@JAtr1*t z_KyB)M34Aw`5%DFo5`1e!%3=w;INeru6g%VFJmRgCLCbPL*CqqpwCQHrE%`wv=y0^ zZl17-i;*xA&N}ijo1C*2Q=$O*E>1Yik$w&kbciH44nT#}Rg)ab(x}({K8x$hgH2qT z0I?(>Y`E%|FEXf>K+2Yfj&}flvtikL z`du+1FO$F)PS*k>x)vC=U9pdiWlY?rtMqM|amX|1{xPuu<9=@WI(m;Ed*6M?HT3Q= z*t=m!i?Me;7#n)`xCfA{pYiRh`wTD1{iAfnf9T!%f03*AnDGyef9MX(;dPVXZmgY$ zjl}5NM@=vi?$WWLcK1Gk&}Q*U^bK$asAsIKR3# z{yu1|7yj(zgo#Vg;6syUeWfe-J|s}fX$_JQm85K15TPp*fd%jq^tbo=!djfGOy^Vy z{XkkyyR?XyiTBJ}^Lxx*R)JP355Pz+1YwKSy}5MuHdEtW0uN9n5QK^eXoLT7cuoes zA6}(gdVlxd#k#h(X5p9M9#V@q+KmGHDhewy7_&NG0Tm%MGloeg0i-Xnt9c*+8a5ai+1n zT2!ziMZlY!1Ntrlo$k4HGKddh2mEXY7;!%>0~yM?Ezik}{y$`%nsL;8ILnw=Oy?ts z-DJ2T>Wq}fGNrT>7QLtDVbbV|#-7A-x=T0{Or4*hXH#MdEe1& zZckhwMTS=d8re+q!*dG^CTd{3qbS2f-(UK)IS|)Ub_DjnQ_9qcHePV+XI_jLm0VEXN~Qy){rrwVzQB4+uB{l3|CR5~$;{?##WXr3tEr%* zB`s#T?=#*2p1f;6#ko^5>q-ii1N8k@Dn{p{$jN)_;WNPb8Aydf`@kJzbX`rVp&W^l zK4o`PF>@Cd{@D z#51PfhA}3zwyDCP?SgwQQa3@6xPi<>>kziC7G_to_nsM4SCNc#6PQd5xY2p~s*2GX zVh`TaKu!TLGqW9~Mr>r=z2_*7guKA=3=~m@^I>)WB|M#3zc@-#GD`q~0Tx?4blhP8 z*Z*P*$pw;#^`~sk$M;(?aQnl{$h07)azw#asQ2ZcF|huZGfA0cWCugq+)ST*<`|uW zJWC#Jfe%*`2dKW}T@$8);k`yogP%fdF9_JC{Xia_hrGLg-9V>$$&v>kYQRriK$Zee z0GGGzAbhzPAA}@woqVK)RDBXJN))B|WhBVJT#R7k%TK@P7#&C2*+-6(08nlbQnZ59 zP$sH@Pv_dN@vN6TdKe}YA(C{+HcjJ`(+-1_^^eUUi_`9)%Yo#O8_8x0g2A?DpK%zo zxcul9ir}1(OzP}{)Bm`fraH=Er|Oq@h!c-))(sFU;?9aJ(<$~j2A+F#KCKW?a}dDh z!};W_VV|el-AtQ}w{J85Ar4*Pnowz&g+bA{AOS zHNZOs1aCBbnZ)R>sB|0k0L6=RwOkLXZYkRaW`X74*Y}Mq>sdD55pWiI^KX4px9=uA z58njO!KVN&di(+W(co#P_G3wTk-Y*uvfy$HcF$bnpSN!_BTmP;MexTFr-gm+x!`BO z9|x7D&w)nA1^g!X{bCEmL z$&4K$>?pm*Sju^Hg!F~W(%wj^X%2D*tg!)yu@cC=URVSBR3#Fj3ay`r6hdaNT?^W( zde@bV_9OA2FoW_Ag{rGEEwzE>M2&eJ5av@Q0Cq1XfX(6YO(UN4OlbiffFR}vFls6I zTmOQAtEIh^F8D$!unWFVp29+LjxvdK6;SQni(uP;`@C3(RpwA05pRtxJmNBWK&IcJnf4?`9I zqhA8udUWjn6nM0M<#n}Q%qU}qM{CmLNg3K+eQ+_Q5x}DY=(IRTYwJ~G6r(!qp)Hii zFa(1DLsKjXNGGe?Suo?rLdKeA{}Nj$4;`R1kw&V(@D`?qsb^Nr!t*`&&@#%AqAUDL z#sTrk)eQYNJT#fqgo-|@Sl-(bPFsiLc=1C`q^!uipgKg03WvAgwI-13?9ZF23YU}; zNLmZ?oRcSI^MEpjQ{_v^z;WT{3n<0MGY&7Jt(jeV`5S%wiNwUSXz7WH{)K>`v}7)qw&wf;WpwZwyTd!ZoOz3u)G#^WHJ7s)=pBq!!5B1?p6 z;D%eeWQxQm?>Y005yzJYAC+e5>@lyh_TJ8KTb!V|Rwsb)>-}QPt@)xp)n9Px9A~LbV&%`0uYmMp1w(7Q zv<=zX-ay+zT|hr(BC|K++kAxDE$G0AKWi&s3B7f;;kMu|=s@}bXZtpUmjXtgi_~H< zA_|ePAlmwTa{(hyZvn0^my6;ae?(2Q)%+6Bc{1#N1`JsZu5Sgg20+Jzh%+!7-0?Zs2*%wx58Uxv z&~rMh{Q%T{4g$Y&kLY&Y&_95?ro!GIf>9sCU;YJ-dI1hv2!HVgcm});X6sUK=(q5F z@ICwzJONLEZ^0q((9_^$@G{K#+1O73-wD=*`d|CYqT4Oo_0XX&Rvp1%#QJ!P@GNL& z{=9E$L-wY|4ho7OyBxA)3%NGdH)N#e(QA&09$pN%kzhMTTiY2NVOH;%5mE0j!$b&PKQm`zz;RH{y zE{^1!HdSEKhnW-!@!Spjc}6Pm&|0NsgGm*1wp=b!EgX$s>s_w=6gA##BN!S;VGnT zxM`InFsuX7ysELTgv!}6Kvrk5tiS1!sPUeZD!T2tF00yBbkiD11B9j$_9V@wrCIo~ zo6d_7)s+e>nd(wZ=+-e5Eeb zEmWR}M#%1=iaSFJmvnaOc6+zs-a(Gx;kshJn^swrB;FP97078V5TRmf zD$K;`s8eVsCB4C*THMYVW}{r(qo(O9t|->$+LBmWD`I;VC)6}q1QNPvbcFpm?r^bM zD1_Z&-Iv@#`d#=Od;@fQiToBk1tO0OaLxtQtKpCvA2rcRT?W19C`hE0{y7 zwZ+4p26_4Y;@7Zc;dJqO@Ywhs+rd1L$no@*YP|hp{yyQd4#3&l?{|9(iDE6RPn*5p zHyCXIEaMlvd|Y;yI73V*5Qrt@pC~0_L>?e-0nR(TqBA}&9_--nqIL@Ad-Dg;b*?U{ zy0X#=KHw?|6oHQJvZ$6T6yMvsrqe?&f&65tl&eaEw3>pxd4-*$i{PlA*M;KO{IaZ* zhl91n_gwdrpLP8RKI-)e6-vR#(FJ`1oztEK?+OYz{yJwRQ5eW+?Qk7IqKO9I`4_*u^CWDI6N>3u~FDOhzYq_e?1FCek@n|AY;X=IN59b8yKsooA zvo74lKZ@>K*sG?8qn*%S>i~OI_T@@r&NQe{Y6FRcR^(3iE%AqhG%WFSz5b>^zrdZS zk2VZ-4ppb*S~~3yh4aD*J`Yrgd7dIzAq~qR{eym1R~pS_>H_V!cFr;W{G_{BCr`K6 zK~80%KcDcr{GlAO)LEWCu>Yvx*A47j)2&lH$tRKEVLQr2LJag&LNT@|M=WH+fb+z( z&IQ+0KU#7W+&!$Kq^kWLRSh7oXDVIMRq04qsny;JsjNMy?M^MEpF~(8sX*~r?#-@8 z26Y-V^eHgnq0;_LJ1wUqyabdk2EC_&x`+R03DBLZuD;rg&9fP<^(vPL(0tO%*(CU^ zEPS!+3l*0c2i?emzdtt%Z+11Rx+>{X3A-x!+*-)vKseFT859}c*^XTal69+{T3V!tq=4F z7Z--(jyRtKb2*1XYgB=&$`vDGd_WyANMuD)CSuyU z4JfRx!sOTfto^|1%G&&i1H0ym4$cV#Qt-QP&A&G%Ob1~Q4b5{BD$h#Lam{Vl55K#^ z5nZzz5PVoF;?kb=;L+-$h~@%{1M;wo*rj$Mh!s~A?*_lfO9na&dzRG7^So8UVE(53 zyl90~>pcK|Dyy86a0~t2qbi`GqXtcX+Ukp6ts_VO>HjB7GqcRW$eC|0dUMiY?1B}S zlXfL`ttck2qaXW+oI{mKv#uiespfN zzoZyCdEQO;my($X^3Dr*g@#^Ka7G@$!dPF9w0R%jU!9%p<${Y!MM*eOSWfc4bhJ${LVsWhIZd#dKgZDl4;J|ak-=xN4S>+X^nN`mInNkH4|wxv5? ze#N9kW7!l(M;=wziGpoUPHn?*ot`r)kE>lBD3#>6SddeDml~IZY@cse}W2@j%2 z`u=p(T}A@L*!yFn#*Y~l8#^KP)3Fmq-8c5G`^Vf-66^8M`0-=ze=v5(s0T;I@UK5L z{(1X2{pZ^sjEx>OVay$|arei14<3r!l*D?Dy=&})qwec{-?-6ZVt0?45F2eg5H$Aw zJI9UxsnPb%*n@YE(TADv(3lbwxpwUBR!;btY2BrL|T~v3TA=sGr@rBSU;sK65uMR zA)q5`9RyHq;QowpDXin3XCDjJ_9N0|d zOI)x>=0g_v^g9N)9K{xpr(qpM2yqHHodocw0Kw;xFu)Lm7y&S1v9Wc3$Y5-R7pYPb zhRY~mf=L71y2St+?|;JkD&Vz*^)T$TXE)@I&OxrdPfaRjjmt6$G$pleh&dA`% z`&x|tAtbbtKYT8^)Vzx?I7Y9r!wg}DlfV~_N?pvb^3MG>v%CgsE=dP#1tw4w(~wj|{L*p_%kK z(2pEK4U-GJ2|5BIXgt-n#20trCFcI~W)-BIjZ=PeBD>NB^d%|{$-Ly>Bz50?i7+?=#jtOVMjmU~^ytV&@>d^rt9hWwc(eMqG zQ^9StvkknIHb$KyE}=RzKvMzXDJH30E9-I6Mgwgw@|+Rpl79U+6$%0<^#SNh0T?r- zHLewTW!X~P@POC=-IA!1Kz6!hhE|X}=A^83)UPud>g!l6Z>Gv9vaFnBN-Zzcq-JA4 z{SNPvFMw5mg^5=HN0@u3;gh#rZ!qz(|FC?Rcv%?y+$+nzF|!-AeX3f}J?6^o5x2ra z#OOj4ti7Tr0iM%R9$4mfAo6ki*xNVWUXfO7A4Zjt8q1-&v6vzxAkB6kLwPi1WJ&gJ?b&tt_1}C5{y!VX;{I=bxasjnu{WMRClgA9 zARJ-B_8i-nm=Y)HR+&hJAWUW-dB-o|{{;h^m}5Gba8DcX+$juP$JFx-(s-74Aj|XE zG|6oMH!|yaAa87YLwLx~rhgw3P+6`tNq_5uf85dfTFXwAL#vN4FKnY)Y} zoC;NPc#Td?4v1O-H`qL0=dPG*XD=X8Q3S!^u)TXW=Q0K!U@xIi$nWz9eO_Dg-$m8n zKgZaOq7-2e2NQf=G*M`7iTMQHk`=*!)}-xpEPr9u>px&$@i4<_zLX$xHiVApa;+Tz!{4w}#-Qll!Weh07l6s!2`Ql{^A=?L#j)~3Cw8XL=L z`l|`OBCS(=TCyUn7L;2~pncz&(4*3Rsw(I!stkDxZDIKXCUllOpGnZlol#1?-5l3= zC;jvnCbj0uGgL$nj6gtJq<7BA9rS;m`Ja&nul#JWq5OA5mAhblIGXFODV_&}c9dUq zb`B3K@7^KROY4G0@Vo?nISce}KQQ)4s$D|YoTmUKoz?YqDYy=t^oV&bTF7-WmKUyR z=ToMz{{rmrM6OK;;em0{iVhuq?uObh%uBd6R^t@bmML~RGssbLaS-qtfSgKMJJ~XI?Me)8qMAG)QUGB% z-_A0(8FSDteiPN|VPYjLP*n(|ut_8uGmouClYXdn0li20`2$5t=k_J(n^J@GhNS92 z&udCjWuEK%Z35}MJfD^jONe3l<6+1bD9Vcz1VWul?uc0x7oV)1XXtfqL>;3Wd=>hB zf%f{(=g;qZWlJFYbC%_-|LmD_PrS{IZif;Z*fnmyLxMo5?#xugZ(;6CweNSmJQx&- zWr<;-2Vi@<^7tekZYD2)C*gDCR>+peZ>`t={u}%bybnUTw{8X1V(jaEHF)+fIRxsVCrN@CQKgXF=cCbod%n=D?LCdLK-IzaZWQy*~hVz6l?AoUGc+ zE`amlHc(F;AXmW9eDVtr>fB*Dxe=Tp59svD574B)?o(di5<>10L zC3}If7~Qa+7C7RgyE}BNsC0NvsgQL3DtcG4S4~~JWCwR0(@wMUS{v6I7=uV|^qliV zK#1`LL=UB8YBQTN#98E>=G8R}nGXn}gW!2Was{pGxz(#M&b7mtH!KN$b2EIq$A+0BJPgIcHW6XW`J!Is74;%N3G2paMFi ztg!3)Kkl7nxU1*PefhPIjQl6xjmK%3ioujL1*kr{Pcp%$X`ke?4BD3G*X(@QSmYHj zizo9-NGh*5V~67x($^Yb{p25k7buWZOTv(gfT3cFP}~rrd^)4)v&?C_3c?f%84pPji8_MM5dlFu z0O6zrSLT}HdXiUGZ#VMe!}V;@EKu8L0Ox`l>FWEF+`Ds{0DBKiGbJvYXZ+koWB3Ge z?O_j75h#-~+j(eFI33r*z7FOrnx2?{W}cCnq|D-W2!((sW(b&*CcyR9$HFcxebuDz z9PSEVOOgHRNGJ&e;gpGt*UM#4WL<+XT0ZhE=UPcR9|8TW(v-#lUAc!;ppdcZn)WR> zb}Xh7kJ~M}+Ijkhx+Rhdq&Pa3A5?PD(2*cbuu^)& zQ1hh$oUHi#6Wj3_StTqY$zV0h1Zt4QVp^Zh9HANF0Xip@PN$N|9NWhg=4N`&5nK6` z?CqG8e70{dv@AEkMJRIAv5JW+?L2j8LIo{Ck)rxVIDHF9?ibfQ*43nXQ$3!09V%L- zv+?%wfS(@#dDlnU7q!2pXI_<UP*E58g1Dyd)P`pI{JuM5%1VfJl!b?MQu*pDgh zrTIihO^kO^E!opF-*N>25Gt=L|KMO zb3V)Qy|p3SdihS}!XNCtQ=;76=2sc+J|ll7zD2X)x)IZO7->)x{>whZ)1p)|aP zjldA{X_2(d$U2VzQkQ{+Ik%S9mAczGeiiIrT*teC7y4b!?8ojh1D)|~A!EE&8%1i3 z%@laY7|3wpd-qd_l@*?oY*{{Y)@6F{@~$UK1lNtlit}bG^mzKUOz)Y2(?}iAS=Rb@ zk}MN&(#%Zn1Hoy0q@;6xxVTe+Wx1Yv{^~Z92B9;&BbAWlWTrL-o0q2>b?|@Q8e1a_ ze!JzjAKz`H#SvH7!LUGB0Pk7`qIU~6#R?aqrp~asO-b>Pu-TN2M?T%sXoQBN>!~wL zU&rr2aunNFj1sIWO5Kw~dQ?Y|Ti|b&ZP=P$KlS^kjTZ-n>lf2(w2#EZddW6_?(rWs zn&oIS;Q_i^gmrcga+*~{(E9wsw@kS435gt;b*ClHV+s>&94*emuY&Wmho?9v%6x*( zRCfM^r)(rs!y}X;a7dDQ+nZDSKFGpP!nqvluacNRxonBSb01~rH;Y_F`9irVZ!j-u z?QG-TEPM)in(iFb@;ZgoTuYs4-Is;0A+NH)-w{Ax2g)Yxj$ycwEkZRhj?#86)_Z4C zDRVHKFKV(h*+|H({}8teA)$fU!afeff%GUVU@~dz@4ne>)@G557{Z~;LPfBpj5i<3 zu5vkL%%Ya20(Ca0duwZUmUHP%tdx@yhSkoT9k-e2I?@TdvzYv8dach_bpzCVDmWcJ> z?uP?a5lSRwfqBGLC}v)iT90Rvhdd4ZCa%0ha!)83wVY_06|6ca3n*CMo^c9Jm52#*|b5XrggYq4^*+)bCH)im3J92UAOn% z0+qdL9;zHsnEwOV3T`jn3hHk6_h)-Cy+8;5RPY3d3N^H;0GjzTjeB@};>EdC`-r!w zChW<)_h^XI<`+JHqtU4I;4exm==_`~K#i4Dynn%4Cagg|!XyVy2amPE8s1-!xhX5; zV~kejMryf-wJO9K8ZcfXOHy9J#CW-Vl#}f2buotPC-sPSj6zis1*sg4uhd9_j?tF- zf9}aFo^{$rIzpqWFvC|`c9k_)RQca*a^(^c)Gk;=MQ*w%ka7XJnJ0-_+rlyt}6wjl|YKv6wobM_yNyyPVlM>6$uFV0~k0a*LVQaxd4T>`}Q+p zi7!&(t3p09KzT%$;_E4jw|Gi2&p*srw`1X3aH98Lg!U(H;RnCH?1^tL8KGDwv4m7| zy9OKuUKV+sEbDTcyB8rb)Ak|cOH~M{s9fZ2FKw>%7&_r{P)|hxER7LB(IC)tb<^}< z@|eldM#y9iI1Lp7cywjjR^`;nj&>omADjm+hgb@Gn1|^T-HE}YW20F_^btg$|XQej1Z$w&z%iuoBA7e;gl(by^yJj6{ zjTdekAW_6f!}4j-)c&BMwC@x~r;u+qxe*F}w=?X>@skoI3@Z(|Wi`!bbjmlcU<6lT zs=F+7>?UO%7scg0TNPvAIn-#vA0miA&{llYI71&;pYaTOI|B-@Ct=ZWlUpNf6s2+1 z7QL9H!bJ=jDWokP+EQRRV^7d?A*DqTttM;*gmWfO#g$nX>D44m4xm7)zb(h7KHuoM zgxyWXXf6?DSX<^){iLY|V?-CZnWTXFa@VCY(aOzN@I2@98%dR)A41;L0A;8Rnd~3ztdRT@jLelh?-5}eN%&NP@M?s$J4-(@p=X4HREffRiXEKWR;YT>gnl9HB7MlXb&TzL%>LAb zPLWPhqC24ozPPREY3H{lv|e67@ntmvDy$-LpKD z+aoV15|$aca_xL0WB!yl_{k?f&^6AEsPyhe5MX5|;ch1tgCKMWvHU#$Eskl%quTAa zgN~cPknttMJfp=jU(ag?47R8Gbp0Rq&U!??ShIA^$Lr0yH82^tAV|4^{jHAXH)pIh z+4*X?8W^9+OS?P+l#E;sP=U3=rJpRm*lZ|CKW@~vkR8)cZJmN2#GEOtq6*sugXPiw z(Z_*0*7;EMSAGlG+S3?W`d>6`L%3`zMrc(0F-M`#BgtN;Y%5@IdK%AM*W8XWQ%J={ zGnyhPImwK$t$VqbEp26 zfwyvvlt*)VoKDSlf-af;LkL~v*TEsaWS`>OY>)P=!cd*FOhaeLX`pM{{%mia`u1l) z7h+k673@8H;^;+PmDTm$)w(w4&l%YN-l?D_>8R`2Ej5njB?3@X?)2*ddjyvzTMk%USp)w1lq;g{v#WkxEM;YgnFzuS4gNs49rpRNh_>o2CCgbW~8n zA=wcNI&2??{T9RZJv=Eb=L*A}+6}#H;7efOLSTiJR-VOYHvZ!_ZR9xdME1BY5oW%*4aXvNS#}HYh1~s3hqL7F$Z`rO&fxtVQ}l zi7HYs=8!{HS>>*?S@)Q-*&T_y19V&BGlUinMd%k3J2UNIA*~>i+1{LZ8 zas(Wqj;kEg<2i8MYvi}!u?|~7@3FmayV=`LtMSxm{o6WUe0!(fSzq)taut_WJ!LtX zyVN=te}39rwBFz>xsOVyzKXcwEwv8j2Mf==nrX0`KEahpQfaX$S6Hrtd2`w@%w?wW zJ|R*aWc;=~w%6yG4RVlnQ8>?(cDk-Z-!4N3=JxG1{D$i+4)OMq{Xe|_gdrpUNwc=) zod4S^3;XGsk9u4<$%x%i!j;#(-(v9KEw$E8&zo#wivN>VZHTU1F%ab<*Bo&XO)}7> zlxZrT%%tHguD}HqiA%Wt+uiv_s~QLqQ^`ThJtwWs0OIiWX%> zB1u_bd6E(YNU}6TJ9RO_;+P=DviWlZOOO8>EZNB7yj|vm3z2W1w3;gmAT^}8^PB=J zCfy9LX5XI0>iXA*_T$afugx;KmCDIw9EzZU5|>4Qub(jSMgFl#+tRmVO6n-~$a^Ta z#wv;@6?EI8nXlA;^!dU`hJzV>A#Xucl=nu%*2aHVZ;lYKgWIq#`_8~#iDFmfZ46>1 z)#H>EM2a%Yi89YI9Lq=!NzA<8fRnXj9O=-)G&@7iX9RF8^=zYTLIOxnbvdC=BEsFy;-W*3XPq6&meXDAHggJ;~D(v15D!n zsBRj&8pH~QbT_hRDF=6N>NfzvWpPuC`Kg^4a}Y@v_#K>E zejN}_M#^LbO=>!8tXQ{x8o9}Q8A+vbAz)b|^HM3!ernPK;)!=AVJc}0ordd@LkIdtmXf%Ig6X)5nkDiN6-zX)o3HH?+2hm zA_OSLK%OHgw*yd4Cjb-+EJs)K3S*RZ|D7(Z`6!<;(kXMKFcJ=<2dikRppqeNAHmqy z-0-@|EG7wicsk8M;0i&4Rv;B80aOb~E1{=xL1wT1byF5M#RGr30}t#&=(KQ>9{{?m z)i84v&5ep8?XonB8$7%TjOluN)vrSNwM%WrEY1}9af7x)`Q{5*msE>#6;x4l*GiJ< zVmTBhy^dGrN8Dm{4sfP~8*ORcpBpQ&f!eT6KZ<7^LqdyMQN^*{D`~EWxpkRax^^FK zQGooL)F$$tXFfwLe)=F90cT}I$e_rlwl?T7F0I3NT{1=}Hg` zwQ}Xtn_kK{-rhON90mWJV*<=EjYpF3i25q7FmuUhwc%=3IErSdKrv5~NMa2G#4`Y2kIL0AU49~ed44ug1Xo`|~n$=AwuPnrKX@<=NbMU8}PU2xY{ZIO`xGx@h z(r@w5g~&fkJPJMr9q)qev>wc@DijKYG9C!MoYs;~J&VUG_%9l_t!c?Yj5vj~bL?4C z<2i$}9E}`Q=20NL2Q4og|7yA+U28Y-=SW6YIWZEESe?<6JVOJXB}hr-9SlwL6k({) z3<^r5dI7q6Ug# zVqveBU`dh&1REy^#!V3I6+)L81R=UI!6QRw{oxFzLEV41AB+3pAuqj)*Bj88xv+;4 z{Hott@6xw0TE7Kro9Vi}xSQd(7td3wyH_2_!>HAD<;%Eh`0wFu-Pi2L-78RRhIo|p z)4K2_*_f`rh#^MvAf94;UWY(sy$0s@-oC&n+x>U?u(%H%YKytRA`~=uZjZ52j{gJT z{h9Crm<|34*cxi!jUNF^4?aD|*yI1Yb=xw|x8iM2BiC-}B&jMi$udrNBJA?$?1Zrj zYYZF^Y>nMKbA@RsMwH#B8#Zgo3s0og|*G(VB3Bya$KgW6{)D5L$-aO zbK%DszWfhx7Q-=$^}jPv{O2X;RblW)GxugC=prUfb5*$vZOh&;@(kEpRxtgD`&|~B znzQoKr#>5`t>)~TufH~SDPTn3HZiO(A#&cht)TKtEK<*b%Z$RxA&GO?UfJ768n6ps z2GgGB(j5?;V<~?PV00OZ&WD?rdVp?m-jqAIW=P+jx6TAN|NQnF^RHEh#AkxG8?$Ha zsiVdYmH*owmJT=j$rF3m;rQnoY8M?VDTzjli(}RsA?vn0hfA~eQioX&i(+n$xA}@s zZ#AKtxCNw3^#q)X+ZL&4dc}mcaC^v*)0gtQ{7DPC@3rNmQ8!)B*ONEi+_r{SKErG9 zWdXK_wCCZe>RryF?Qrl=>q+{imyK;{1GM3K=K|i92$IhV%UCVsl_j2+BDNQJ8#kL% zyecl|QY2HGgmgRW5VSm{Lw|w>91I<3Wuu0m8p=gE3NC)ZtPtzfhT~aYOP)Vs*y!? z>;GH)ZHu4&?iqv87opH)`2fczi&!QWp_z!AqC_u6Ivo_L3Z_F$z)xY$#-xz1Dqk>N zghHxR>y#EUhFkrIhdzE6dw(}Nw!l6GYDDFEEv#~aS8(N6A+W{z+2DR~*yi>b^yhb^{8dRz}LXOIvVgZI*VBu5#oK zyt!MqaJ$@mn+oy6GJHJZKW@`TlGi`QXG@nD$FwC5e`Rr(y7EW5SST7!{9#4VsJp(X z%y-;U7Vn(n6#bP!mw9SqBCgHdYJ6|mby!_P%N!&4WI>ZTccMHRFzG-Wtqwo)oN=j< zF-*RKPH;u@LTV)6W=k(!YGPmFULr*NiM((iZo|IQfJSue z-epq%+#u~B9EeoJOghi5kBo!#pBDfJg~7ky+IrCx0G{p8T^kWS?ZT234JPpOtzZ$U zMO?fZb&8h9dYAF(M|2v_qF@e+5|Sl7_r14zLGbT^ZQ;~szj|uz517+lfM1YuNr)AS z!<-H4zIkx;^{D4LVH3|4R`u0Q4}s=c{x_g9C`IWoEEI2Nc7mLNg`L{<9n>Yams%Pg zdi&6uqn*ecF~8$bE=l*GyvW(7M@gNf5l-LK^zLamdiehvylsnlabLq*OYmZLlk-X5 z7ZH&+Y?F7*XXhCbk6TVHCgc5xdn^)txnjX?Q^Cl>+K~R{neUD3nTLG)s7aItp%f-b z9}h?^#83{Fpv>)IjT_eZ`+3-tx0`CFl+KCTvVxds+lTGOKKui?ZJckv%8e)f}jW zJFj0LO;W5h%`PQnNRjq-d7+lHtxFInpU;V>$btdEIb- zYlj_YU?~?>oIXDll${>qfhHUZc*#KO)y0b3Ohv{JK{l8HtTX@yOLiRTh-a$F>2R~|&Hi$P|eLx!I^`0JUvpb;6~r*X(lK~Xm@A*u2t!`jk;x6WT^ zFvqfg)11Z4jnjYScUP_$JTn)04#QTdFXtEBPKTQhvgQ1f!24{QI(X&x=P=Xzmkn)6 zS8p3^$@tt9+<}yUgdG0NYs#1{ee(@w;PHQiTh6R2ho1P}w1-2h;a(I9DGrwAc%J82 z#BnUgiBiyCS&dPuxN`2a$;mY1K1`e0Y8*r*7 zPIJ@nhqlj{*Q=F0FD4R!U_9;*Svu3MT_&`Nnt?ouC+v2(Beo}=PRzrhqb*buGCrc~ z6*yat;MU0tGmHLvIE&$U(NiDCi#Bc$H5bJKn$FB=&g3L8mCLK2cBDYk4RMUreJ zX_DHqW!HaC%l+*4f5&h5_xm5mdmQ5EIj`}&uj`zybHI-=go{QoStR+mmvNS{_e&GI z24N@3aEV&Qx>Qlp6hY2Pi}EK6x}QG4;fVxb$vB?nShd%JPGEL(NGt*n4rXWlF*xS6 zY|rCf#2?9PUvjm6vm$7ydM@N&O`6uPB85MWwV9wUF;~gRmklygEfC&YZC2~(jH!u6qiTE=#VRv7gQ*VXtQSCj`J2t zJ}4JJ%yyQil&I4zZqy9U?eckCUOWGQNvFqsJ!Slc-KJm761c$nOVf#1Q9;rP z5c>2xt3e4H+KQg%%c@${IGc5ueNFR3-wf z!0Mb-rcPkWX=k#V}qKx-2{YxMu(UdAkj#&xZHZ@1&v%P4RQRsN0nL@CUgm5WIoA zl}3a%NuN6+#fTATdu2V`L%T7rB5+s-}@NqDIS^dan>?NZO-|XqJ6dFfvuYabf2#>#d8hR@yA`F+VFrLs{y~ykD&b z37xGx1l*#uEua&ct~s$B{1H_`$kOA(maB%#t2# zND?{t<;9MB#agW1eU`i&0*t3L$ZKVe_W#b_%j37mlcZuCYf}Vxqa(zhIA<+VKdUR; zN2oG*_@2@IUWDs%;{F1z3?6X330$4GqSwQM=2&-MTD0!h_0|>NB>#lR2;9XYsE0#Q z(T`(_f?{47z9NWT=o;>5 zCs{r*&jKV_*9F&MDyVBPZnax8Jh~DZV%_X`z$qLtb}7j*P1yoTvw6-|md z5%bvZ!LM$5?N=Kui?oe&3PIb)5hG=p$BqCRx7unDXT|Td)0pfl<_N#n8%;YY-QF30 zd5kr#8C;<#mK1P8u{nn681?l!t3d(lJMKD+=d(ma#4(qEQ0Wc=8TQ~}quJQJi?2?y z8v9sgtLqyIzZ;uiJ57B0(&cZw%{3WhZ*fQnl!Tpy{IY4m`TrKrAFKJM=RerKm^WNM zki}H(1lR+!(Q?e&YEVZE8tgacI8AvNqgI>UmseMOVpfkm z24iWdHr1K#inS5jI@ZtTWmBe}GbqcyXmNRpsZT80Jl2%NFTi#xgW;K69LtJwIXiBh zF@?UqshGZmNa-NtvN!YQ1y<)!Hqe=St2K8O8#|6&q=LMf&!A!~#DTsO#!CX@CQw2U zXs~z)ScGu%?yn|I-)BA~{>R-eTUVB^`fRybsdhTImMTV(Vh%wfNkHoe1QAFC!LsuG z%`)2-{d;X4*Qd=pPnyfoN#a~?F?H=9B9x=Lwahbj=yzb3Q8R0TiJBOz&gK`9Xj|%T z`4Mg^gpLFIkYg^KHq3O_;kPr6XH9Fc-PsNHoI=5PJ&pZ)3Z4e;Ka+5M}#w zjlsHxZdtJ|Uc*1@-)nn$aoe9Y&sADi@c1)$hUV&XDO_VwlwlA%Be_VKLH6bn^8T%M zl-bT4a>n;2nj%I};tEtz+ysaCdFL=}eAYx&_#feyS9IiY6J18JHenUY(IiXYyvkD~ z?Gm)Gz+!~+0T(^d`T_s#wpkzW@Q6weSF@Q)MMzOZJm53NbV`(e; z{_VDu+18wStaTmrnGcIdh^7KTiuOC$o3z6mE%qHol@5u8zP2)jF)>D~ zC{Zo^*c;qqwTk~Mt-x%h)3QIAQyEFE#Tne7=U~j^XyG3&qiFVmlS@B0F`Nx{?#H5E z=574KGzV;#R}#=uLXdoJGWyMJx{QG9B^G|e(kdk8ElX5hx;N|MK?V~lBS<7dV zp-5iJpC#V?_KpqS$ZTg+j899Xkd;4w#}_tuJiCu;Ncb}KNxOKPX`K7=T^oFcnM|cR zrrq&&xh}ITsda8I*-Jaa{K^!2Gkptud3~H1nJ+)KdrxKe2?)mp3h@)Ma&YwE@!d8YW!H8ga>!i`l!?H8D>3AT|Q$TjG(}lnP=PKhh!}z_Y zR!`cFm^<`ejlAvL3??B2+QdbF)|@+z+Dlr+O`rqr(t5wAq|R|HnRcS}rt$j?x33gI z2x`oivD_~x5z#f zatTaz3yiLh`rRP{3nx^O;mzh2+JF04Z?2EF#dDHq>kqVP7w|TiU=xKq9ydnwv*IrA zRIZap;yIOYAuhY5%`wXO;AcH2QB@d8&CM}K5Dl$%*<<<$|9tLpmT%gz zbJJ%djbwDi1C%3y~5D8O@j5r{=<#;*NMo7v?ch5?Xmo$$!+km3aL0^yMAs)5ANk@XMBO;l5~ch!}auaIQ~KeXf*BY=DO z|M5vKBWYR7b4I+ko5fF~NBMFnsE7Xg?$#ckvvQqerUk$b@iEa|9OhglSz-S>XV}Qw zgRNl;8BbFYul0A-hSPgn;fL@QY>W`wMrom4R=%Y}CR|rVzrhdCzRt1sa+960`ciAp z-NX_0|4r3eK5d0BCil}Z1PR3f^*a=|OviyEnB+}JN>yA12yukGWOLg$gS z0XBei4VDx4yIh#dsS+~jV(a%mqUk$9kW4oO$w~pX=g@)Amz?V={)BRWkdlR*u@}`JFBl9IjXR4+ex5yN7@s2u?aO4@HvwA z-pLEz9Q^M$ZYBOFe|l`j+!JQejAP7MMvJ&)Pt=_iPO;%lb4@=nEAbS?S0-sLi-nE?fBq!6S$E(NrV$FH4@hp#~GTtyVkYMK*;t|GD$H|b=N9?xpkh3Rt`s)nbjF3z z>1s~t)6IH8cbT=Jk9}%BcPO-e3=r;K~I#wM~qE+E6^>@+XZ>`!Q@-DWxIvp*j%8fbDtzTPxpH#jfed&PY&+*F6 z{+EAiK`$t~>2M&Hig=?rP7Z~$NA!`4*~kR-CqmZ0qd;+dfJwN-GHJHlRZQ2DUAd8Vg1hOz9Qw=K<{R}&bt#JkDlzbu zp;=jvj_c#3Sl2prHbYg`(`1DPC?|ogT-q*uhS)y+b8Fwn)$ueGw#U(;c911VeEY5W z&i#`*l|p10MO>vQlH1O5aB!LL+}~UMmuo8-G`|{yys9kch(*WDz4+E?t5BI%f#*<# z5fp==@ra7kPB87+AFb7{(blqfWdMN507Ub2Mb>NWi89u6>lr4$uZs)|7|yg)oV--~ zzIxI0<$ceykEUY@f`}(+=S}Ovi5KyIzIJe$ZQAklw2M}9$kJvi64P7&99vMJDzYpJ z&UZvcl(I>3JU!y--w%ofJc;5#^+Wm&jd@aH8owV`A*1L@uY}m;QCnv0e%^4_<><|F zb;Ez|*MhQf4x^;j6?Vtu#=YYGo#1}Gv)@+c`4V;P;YB(A=h z^`Jh?$9cS}pEU}cm_pukd%2?)(Se4T=xq}htT!y$f^ozbco|jdZ#sW{M_^D6)#Lp~y+hw(twRRRJ5^%C{ZCqh7Cm_XPx{ zGz?e?5M5Kl0*)%OVc90qyv4!{EZ{D$_WR1RLR3!Z)ye#J6^`%Z!DUCq5pCJ> zqvFk4KiW`MQJ#0z7xpa8bWI(w~V-t$qC@?!(jRXe=kUH4&__>(5`*p##}&OVmTOz+yBvveQz~ zs<|PQDB%J@33;o5p*Vs=IGmv=KDQb0MZk#?R`ft{93W+CQDL9r8^|aY=i*w99cj2y z-;akSH%d=RK_`d$@-G%H2^!H2i#!{JSAnUaD?D>x5_Bu>7a2wmBd)XSGar0e?{0>I z%qKG_bk7B}oAaIKY~Ey)z7gY?yLK&yXz}deTljyyt%g3;Qx4csSjup;# z-0+Hpjh*ru%7;MA-I@f#Dq6eV#+AH9EcYp?GQS#k;*XcDu(q{NStOMuof%KqGcHzU z5D^4TM-e0^s|5R7)|gAw`D7mFm6WjHpyb#$@9TFkVR%t(RYQOmawx(^-F(z>3|juq z>jx&7zF;%7txC*aSR41{RXIEQd5gZP6zjX-ZstOrJ-Z=39*R2Gl{TcGfOSBW+J@FO z7EYJD4k?A+{GLUD++L2oYvN`LI>EgH^{L5Xua+usxcBP4o5(T9n7<26uYUBwUtfn2 zJAi#1_IM_X3n9@1e?Tf@@2Fi3O|L-5foPO=yWDgXQ7A@%AnETq6CxF%fp{;mj*tjK zAOs|ruL$KeMSV%$k9#@tB_ISw;24ScBWSCkChGOa!yPoQUx`u`V!z@(l^r6wmPU95 zMT>W1YRDSsQS=y40#$}qWv)j{xSX;EE$;0=l~mo5ThXE5invA+B%zDyqF&SrS()k z0;yaCNoG~+d*Z!|51SeLrNw-}6^i@a!IVScPw)QB0?$`Jrd;moa?MqhmGa325gPLn{X&n?#aA|vcHCmX)oo-wq;liFfF zK@#aCLuUnr?fhWFSL4lh*fZKC&WEBwFF+_Ois21=f!}H0QEjU|{>BQo&k=Vo%(53a z-hG@dR6-pK)L;ka)VC}!z$%L`aj(?{8zY!|#-#l}KM@?!m96{9zm|%tRpL`n8APMR ztu-7lB*CI$x^H1|Ospg)1LZuqXh&Q#do%y$~nUyik)9wX48Ol&Z zFqd|OudPe$g>Q3jVPZ<4Fs^#DnCIEaHh8Cd9~}x-*9HSsRnES)&bRk<%)N?Dagl42 zeE1qCv-7d1jNUQ*I(rUrp6<1ZyIYM~kKSbM+q4(%+4VAG)_L$uXFUGGv^!9c<*wBH zxIO&>&umuow~Yvq#&}jb|ECSGQC-}#k}u@M>H=PaKdjkc^$yeWcDvGFs*dx6QYL?V|V<5>^vo9y0;yq72?QW;Xi6 z@7rjDC;MhIF$4)j0r5H;Z&_!9XZto&hZ={h_sZL8u5J%G3dSQbO*5%BV{_#u(%V%tp*@t$oigoV ziw}=k^iMYcDMN0(=T^OY@6q?&dCN^D9k0Ke<-3o*H#Tsj{+Ch1{duA3?XUi{Y|hXT z-Pks}`O*?!j;~KoZ$ij0rSANAVqoWJp;k@bjWub5x{P=Zy$E%oPHYu12Xeb{_rNtm zgSWA$rY1M;q~h%Vzc*0!6TqwE56-eOaOG_y_Yqt|iIk;lVx4@9jH)T&YRDHWk$S2; zSQ(!Rei4&F#vONq59dsrY`ARXv4M@uY}}2y>5@{vXw;q+9tWwD0KaRo)rOgWoqyDD ziq~)7Zt5IX)wwuT-Ki+)l#Bdu$=^QPY*iIsO0Od%krxG?;k>R$qOv4xoi-|D_}-o0 z^O-%;BKkDsEOym;6VJl=odZ>(chuo`f`u2t}M$B{=>yqg9yw0M5{{2LSF4q zz&T#bQ`T7UBrCTti@?>kT;cNkG@yHj zMY9r1an7weF@58+udOm0oMC1YZjUN^G$l)ue*e;*)^!|VE)kx1VI-&CFR5P5QczuH zlF$oQBaOwsW0sQ^LwfA&>uc7{HisU|ZU(V9pW})Ovf@oYTw$%=$kWKOeCbe)%BkUj zu~l`>FuG4!c^OR`xuLwLD!{la{f;&4)osn6+8bQYEkK3x1S^)sv%(r*dh2q7N&Fgc z=SCz?+BO}TxurgQ`Hj!*8P@Z6MXFOuxGI@tT6*Wj%kW9Uon)e%Ad+RYLpo+Iv*7v! ztAw9WEE>YdSlF)rX^0{}zG^inVMDuwMY!bm=sJnYkt~ggJ_09sH;)loR-NQ|uUQ>* zlBP_=@^ny(o8vB-f@(#+B)$+&bL|( zWIJCJCZjRFBN0O)Y)Fp8GWChxL%Vhq2jL;;j$a)Kc+`-XAw8IjaY=Hgm@e%>kgLH3 zlH(a3ll9IKJGJ8?YfzQNwu%Glp;-Uz=~E}hKEKw)!g29EAks2U=O|ebB_~#2M$>um z0G=py3DFX_=-~0g4VN2S5Eo$ycd9z>OJ?b@Z|u2@mZkD86mkl69w8wJ@3#m!W}L)V z-?titS@x*B6(7WU6Ac9p`G;PW)+ctb<)gZo6QIZ_UzZQa#VpwX!l|Na4M zj50Q{&vTko8&YLM2FpPI_SUI+r_hD)0D%f zKHm%@mH;~oc4^DQ1&>3Yr_lIBPztnoGVcYL0)4vqgMDtw%^6(d_cjb1`~*akIl&tL z9LT8)=0$IKAgG0zVOj_8;F4$Hwj|d`go&`*U+^uwj^=dH6(5NdOgjZ8BfTRJb-g<@ zi0td`+OB?ZpcC5-tC9R(Ey(r3uFClkK7_`ot_uy0`@>TF*4I!f&tY2z4_x}+b(t2M zhT-4r`~21QpMqhe+r%tZ8Jt6PU4Wn%jG?NzOhfxg5d4i&!@5OKu z-ViCF8xSvMS9p41_Nw2HsADtRNaR1opD(Xq{o5zzj5Gb(E)u`eeF4q%!6DDlWG;MQ zj9kQqE)kb7H8Y|}%X8Bh<7P=-p)ty9)Tgy#bz|nM`nsQAF{&ztn#m(5jgf?iA*6?3 z`7jNnf&)d7b{R>;l$NJYJ^!2O;joWfM}|TLg~4E9mVIF70b_QfgdcfPj;X=Ys20j{ zS#6nPfOA;aPVzkPp+R|CK~klpq^u?c(uvPJw9;6VQG}M-C&v&p6i1P;qYAE>XHRm9 znomXKf}vrdaF`=>T=>WU$60w3wH7?-_Bl#8sA5#om6dnnC1V0zAKk}4DS2d+C+L@< z5_p{Ki4Tg{j=!HjzvA~g2PThkYvp_Wb{yO><41k$3*31T=Lo=+G|R-oOqQ4LXGW6% zD;(fkAAL$_psL{4C~scF__GyhJ!GVUi2OMZ31QRkduf z4c;sqkeHluflb?`*-S&~)+IK0y*Nqo32MsAD_P3K*`+pkx4294QNH$G+MD%&w&q0x zoX7gkN;^d$;~YvTgq#;*F+RaF5f00$A@`C!(jjS|lw#OS4oziQxel$i!Dpm1qKhVE zg}}2?>FhLn8#&2mCyjm9c2&kM?(5p`8>Xf|`iRQdY{MV}G^5+qJn8PmubJ zBeJRywVXA;Db~BdGh8rDsYJC_87-_Tt&4P_bL?RK<(rPb{Cle)^kPsMTED(j)@$g# zKfm;hYhj&LeNVYFAl35H@N=R{pNZ!dI< zXRX3BffUEush7+Tz46cXH~7YLPOOh9sfMVXG@sDmVRcW;Z7rnF0miS#+*j0mqYqI zn%}p}Rs3V9`vZtRjdpq!8@Ld?s-G?t`8r}V0ZeOQ1)E;ST$19^JnvuOntn__`PRxl z#YM6L0!K)QLQ1SqSuz_sw3h0e@}_A68cS?b`UT|TzJ8&|e3c;#OfLH1jkjwIpVfWz zdhK^T?zt!GPBJ-YF8d5*RkS_$5=4(v7y!DVd&NQyojodEYa8Nw38Xk_D_RI^Mml7fdz0UDs%J`z)yh$E|01oGAJu% zXwEn9Ok9kO81w((?3a;qe(uK~kF|mohy!YUG*H|S^A|t;3>F&Ayf~`3=RyW z`zbF#!;9dpVB+~@L)#4)JPY0gOrnU_AeaM5wm>eyiAgyP+&+B{2ES9q$DY6E7=wYdei7^@GpM5B9=cA7s?(^IMu+LciG_g_%$wy zPk0c;FJ*=2ePV$16SqW|#K{z`4$OBKgoJAA)ccKN-TaL`|14nwUl2-E7W(5=jvRPl zt3APN;a81o6QlXYDB&1uE_`Hzw+ho;Sg4T1gLdgabN)q#Z17=WvJglYhy6K45y$9! zc838DvSPEmj=f2$A-nKiN^;vza9`RBnnxDKEJ32lF4UrpE$0 z9Fqy2;{{Sd6|7G|zq-d@V4R5~akj$OrLxl?L?m^hF-EzO5ouD!M1kD_H=-hmFNPS+ zA|l26QR|gCx&qCaj4JuzbZ+3P((6?X6iN^%3DdF*;w}7dx4O$7bKiWva@PgZW3C0; zhRMb4HKC+~$2rZ**Cvfj3CppiXaul$F^0H2fQI}i5V;JkfN^UUEmgi=L4Hvrk z_OfdSVvA zwF%%vBu0`^0r=AyVq#W1&mJ7@FzZSNY+MCuIY9F@a81!5kT zbcf^j{ms5FUxK+r@(iv8G6_-9B$~1_PB6w2k8MsG=-5S0$GOUKmM<&gvK|&Tnaf*1 z%_fA5PuCu*RZ?=1V(#@(M>*KI-5g;NwSr`dhpKGRRZ3Rn^7oSFBRI2^iq;5?#4zSo zPLmWj8jyVXSE1o|i@rehq+dMKr&!sU3o z?tIH!zzq5{36Xjn4c29a2W@@dMBWm5J=(WOP4p>LEQW7I@y^!2px*Uk`T~yCr%}8v zCyVGG+GcibX3miwZz|>u#IrQG@87jj=`Cf>p;VhfoUF5hlFY6Pjm(#Z`x`Tx3i)G+ za3GxZP`Be9I}IOm0HxGol~f88=Zj7}Z}r{9%*T--DFhjuM4Sr36aQ@W-NUTM$ecow zNVgJe0~KGsZ$ZCfrlammeZ-Sn7dGRO%vCKryTwi)H=m$7hH$o17#uvW-f8un!EPgj zbV?L+lbo}oi8gc*JC(xnGdP}?i)A@eY_*`9*h?U}WKq^6!7;PX`AMHwW%2dw3jJ8$ ztN*fT{+_Xu17_t?_5dMAGcF;Pr)8a~ma$gWBX%W`5&3AYz{Q*-G|T5&&&nT_6FBiJ3qw1(6)5Eju(al9 z9Bp~dmu41F-#O_NHdwjBuLzVIWyE+S83^jM&W>@}xZ|g8uWF%s95`mtAu%TDjN)i*R45SM-+z{vpX`kmY)w z$0L!PbTFLCawlDV@O{(Ysc9^pq1fUamdh%o_Wg(NoBlSNU@MlQg|10T?Bcu#9o%bn z6(?ikiFUq$E{w;?n_D9y9-C%4@*F}hU@=;$4O6XY#>|kiV|rJ^i%#zf!)4p?zq#4y zq-zhmu&H>v`)xuq&iK)#x5Z~+{-Khc*Lb%~jdZ31x~53!Ud%&_h(quHnLOq*yP zw57xnJQ9d!!u~{V)}W`~C(R<{#8})c0*z;z+$Md}+WTYT4DJ%-fFde>$5OEHq=n1F z)M4T}PC*5lDr);4W5(xEZ@3tofw2_tQ67!+-A_xrHDJijoyk6l5Hw zXvTh?F}T*kC%3R8irDyZ`V<*|9OCgSZUe4!FI@9CFbqdv}{|rEqi!0&A!QCF_!XS|xi_v&~ zWk}6eJF_Apb2|582rBILCjABO9>jI5UAk=9a(yVH_Aosk7gbFa6qn*W)O@+rg6^aD z;302meb7^q^$4?Li3L4LA0@zF3P_*`b!hAN^DO8o`Z!Sth?<9j;voI=KU$c3lHEik zaH=|rp%R6lK^jFl$3x_;_bgO2bK~)HkqX5*Oq2-T4uv*sX>(q(W|_n-Cuo{t8U2q# zf%dlOP$T4xo2o;NQXF(v^3gS4zjSPZRlT0uLip84B;XBuo!y`Q%7h!2ke^S4D7ijJ zN;S?E{roe1^n5lvTUk%P2H`jp^m1YM&k+6vkcabX%7S&?c!?dR@Y1J04K|`qkBcWU z8S~Li*V=%;>SJguwM06LcbH;Zzz&|bkTY4@MR>SKy_?4vnoyEVt0~T7FVP1 zf)tPfhGId=i7ho#4$pwus7v#BG}WEO#4Z@Q6hhOn<-n3S6%a96q?H6m5wx4bDT#8$ z9pm2y(-C+HzFn7$+hI1{`{b~d&~z$(5o8}nqq>;O7zJ4LYwNu6PW$=?)17<~z6E6| zUgmVTv!U;8=qmguup-AY5>GiNX7yPMx&nU^bqR%SHL;-4(a(PV)`A|#-_uzXLt_7M z+IIZ-gXtE37GD88jbo}z&?4*h<>h#+Gl!WW(ig2UF5;U|R@B!nky#I?JASaBlZZVi z%~K>L(3tbUvEi>j7#X>RF=Sn)X+zVt?a3jh%MNll&ff9QY*HeLXEq6 zu=yfo$^gV{loutQlVrvj_pP6QFxd^%R)eKr3|O+tyb0lSd4wT!bQ7o=snFv!F-FpCAorBnO2oivIcb zAB@-m*8yq?+Hq)ZD6fvd4McHLI#`bu8rb5@XSuyAw|#i8`N8OmSS;pqN8?_fBa|+? zsIRb?P3)rA*f1e9=2N z>-Fl(pRE0!p_iges9a|KWm#hCv>$b-{`t?)7xY`f5TpAIwc`<-fzyBJB;)N_7V}Ykff3paMHS-Djd|Grs`!aB9dc zDq-j2f4|)PyrE0{BApmC-WNIOpXburWDove&J5 z-g4vUJ7V3hzx{SYbnJQ4$kF#-KQi~8*cG?ld*@B}+;h`CV|EEmKd*alF+XA!u;T$) zL#L3D>KTYEhRkdrBV>pVsIGt*D}E@Fp9pmIjPayh9#!T4FkE70{{JZ-mO^N#2W5-zX|550YT)4kish)j_ZSwnSlcjz<)jQUKE z1ZsVynJi=ZzReSj>_cWP@sC9@5a5KMKg)sg!gKE%`E!iOO?E~&7R}^`V|jUw7vJ=E zPcHey_$00w-2Px`B}L=7BnQI;?)673{>2&k{+gX;y96sA=EsKu9*(E!U?LvQ*dY|g z=eV%TY-7}o7j`q=j^(PaUAFJVg`+>dXw7v-*srMyjc^* znw5w@zc?DoEpb%UtqaXP6|^?Jf_ql~XkrGzXO*w@YRYT5jA z(gBuY%m4*}WI7kg606{DM58o8smb+He(>UPF{iSoxHW?J`Q>IBGS%o=a+iAqeXsl4 zk{jdqGxs{K;mggnekV?sg?PPNy!;Gl9ON}S%(d!xJ12f4a9TvcSqvq4ul0=x)6(}| z>o+RAbjz(|59<^hBtj$M^@QD42 z#)~eMl7KqE+T9Uvtvf&}%uZ>I@O8D#L3**>53&5-v5 zQkhI#kSG$vP=aC@6vM)n4a$7)+P7(}F?Wa+x5%?2!XIcsCS<&}y)A^iKGt5@W_dlE z))HNFT=6VQJn4hhnNG^vsbD7HqB)N!dliP}6agbS%0d336J}doVA`!NaBG2KJ!>)r zc1ZS`9p*ebLYFIN)MCw7X?Ty-1Sn0UH0$8woEc%>iirj41y7kwxxF;yhyO__z<@HDfJr#cQJ*@k=*Z*dwE$FU2Hws zhN%peCtZll7C%%z2v1W9DN)k>frrMy3>er9o$m79Nsoo}8nkjQq%OgzQ>f#;*+Lr` z51=eZ$6;;0)iCk0)@qsz-L(IJ~MY}oC$T4$D_Jc zMN=h5irM&1>o{lB<*s5Btx6)OHxCe31ch2hLcOrpY^Ps~kJVp8X*JZSP_&{^$-Y^d z!8)@|Tefhrw%aSyyvEbAn@41gV^BrbyprHzfZ#b0R8|&T2+LBE9o}jP=V!N={k<$R z*)_?Xw;bGd?U1dTO+Zh!rp2?Lqcpl(^}uVdC{9M)h#*kyu!qG5(oexC0T>Fn)Qb@4 z<%);=3F$a=Nl_i0A~*wmwycZ4~|>kuuU`feS6MMPJf0e&J9G0 zGTAwVjO6sbZ{R4?p`Q|E;!GnYar)*IOhIexatfZr2!)mc1xT0)DsI1UogKIJ)>@;tpXDkyGqU9KNwPP~clu!VUnSK#P+(_+RwY=JX;f|IM`tliBN?KZ?m zbZ4th!Yq;O$Mgvfg9^1*=mo&syas;7%>=P18de)*N~UoiEsLT|w-@V?_V|sFR!VI! z+Am+)^3v}|^k(Z9GbfqZ@E+vf%(g+(1-pUaIg-P}SdepTw@rg^FsV$0@O?Q&OaZ)s z2Kqr1iz-1Tj5vh4B?)4!d@(gvnGhleNa+w>RXVUoW9+vtGgNqJ>&mhZxa&D7#+*TXet$@fX!vdXoj_Go0!4I8(hXR4xzK@m=Y(`6;j*<45&u({Y#Hl+nhlP-T&oX}fd1GWe|zy*?p zv0y4M>h$|QV5U02o)p^iRHl(5bF;jYJ~mN)6k9_Fa%waFR83YYx4oT%C*!BMs1u^MafP`r{wy|@A(}EM*~d02lLqPjO)zV$VO!b!cyWDRq9{8P zm1Mvc;9EFfFhA`LgffxoGt(<4o~+0dbb00~D^aVw4R; zc_B^%<1e%r17WJw8^)O`K{GLl%P&m?b4!vTM=qMSZk!>jxaLv^ctW8RLAbAv=H-G? zC(X8yG|$?sn%W{Uo(;9lSAvasYF1h@qkn=`H<3#rrexYDeS#a+ID)e@N|zzyEx+`t zsbL)<#|kPC76Qk0~S@ zs@Aw5fimGRYd#E^*uDQuOeu` z1DKx$yYiZ;njCyqZ>h56uk2w#?q;VOTR09Ilh4uvM*qQbHHvh+_4eEUpsNdgZ@TrC zkt0UmJ#zHu8)F0SyX&UAZ@Ty1o5sxR()8)c1#_ojBkpBy-nNuN9?4(o-p=krm!pee zEY`6FyRRAlgx}-+^x*?L;RLr+`u2wAJ126xnAPf8@`tz4!{}#kz#Hl(eSdcU7Jps% zjCczF7Jh?QTpKF>1W#Zm)M>$S=nj~PJ_p~!RgdFSpd57Cm$r3-N7>satRj{SFIWyQ zqPyWWd>_oCw!vo)EcJdyZ$zKvzr*LR?YJR$xG{R+N?r_pJyAB*OppW#2NCj!r-d*My=MV-!F^GCd>9P8f6 zo*jlypZpR%VmRB^*!Dwh54o0eo8f>iQb7GIwBloQhrA~63D%5#-3&)Me8!)Ld6%GB z{Hv}ve|Yz<#up!hHBBejOW5c9N$ihk=Z_%P4K3p8!dX+G!{7R)>xd5}bq#m!1?=!d z^i{p(=Wf8~bv;YHgf(}0GjgEaMD3^eYwXEC!m9MD*uMPdh_&>izX0(P)cgqTgqiRe z1}|emkBM;8`;hzsd{fZg!>+u8SdFcQh3NC>%h2Tq_#B>qvMIoggX@A%gXcxKb0RR$ zL%VmN-5;^yIcVM#=yJ_V(BT940KS4@Rqg%;HOpWe-1GoH5gzDqQ~Tf1pFzzV(C`lW zDO>^lbLN1KIP3?y=a1n32tpH~?FTR$-iIrvfctgmH4l9j?zrx@)IIg12hD_)@bFrw zDSZ%G4V~VC`>F;@Z(_-XfQ^I4;AM0sOhMm<7xa0@!PjWj&*-Bcz_YrR_!~SAzk7_h z;}=lh!p^{B_$HW$7ET22P4v1G=%YJe8uWPrf)Dp&d)Ov2fj3Xg3Q6Ujljt zY=ot-9L7TTyAxwU7}aCMumSxuzo5($X!#Q$^l-n9z5@@IeG1Avh(DS$xUr($4TG<^ zFPYOXd6l;lbp_qPcd2~z{?Va%5O@}Peu4IW0K10il-r-53EivM>&u=2w$GJU@jd)S z-D+InsyCqj2Ds@p82o_rEJPni+3$gP0?2ql7pha0PR&YG6e!fcfWuR zcm?LeYM76DS3*fs_f4=?$Ilw*SUUl(xqrxZ_0w~Ma%JaV_|SJ6s!Q>BRy8Yz*+iohJ>esTAd#m zNl7>Vjoynw|hx4KL$!D&tMh>Z?D9?nHk;55r%e z?;YpikN8+@Azb|yl>UN7UPr?RQEdn0y#m)f4h1vOY5I8^)@ihORp(o}UdLTk*WnKT z%TPHJ$a|#g>uTCPu2X>*pu>G?UAo~({d5hvV$kqaP+Jb|^V;<5`zG8N&pZ#4(U0I8 z_#-TVgE}@Js2q&%1-uX6DRooo4zZp09jLe_UV~P+YWOOuUvB?)MV*v>)dg%co$HmD zU~!y#0tWRX``0AMVkN}(tAGKRXQ8U8BjM08|tYadE)|Bdcm}xc4nxeqRlDKj`0}f0|guU7dPA4~ah4 zzJhLtM?-&u*d399^=#9iu2W$=v{{Va(LL|l!ke4n=6ba_ohmGsV}m--_;Fj?=h2NuI-NO-ny#m4T0l$$MUmu!^!@pAdqwUuNd((*BO^gSpY z)H(m^+lqdtsc1wKnGRlp?%qpR!xE+M{S`mC5TFZLb!#W3BFCQtMIk73iD*oUsF{qK zz|t;Hz{Lj&BeJXz;Y4W9)A*BbLC{5{UFA)w*=Vg==dbBs@-kHQlN05$|A=kc25GHW zhy=L;EH5FIC)FZ%UAUw`3X}eFA{`FI^TU<7rC5F<5D29BMBn+}V+Y=bq^b?d5u>3z znovV7G2|6X^QBli;=zZu2@xTdNb!M~4Bg30Tea4U#-(VoA*ZY$F60PTk$uFR+^9RL zHE2YlaOJDmsdu3>(>GaJ$2a;1$0f8&(eFC-xG!h4(5p7DJ38D~e{Fr&E4x2b8c1BV zd?j{nHzWi;9B=F~I#7i6(@AE|1C0Z3>t7Jjv`|z^-jI`f#Z15-gIa1(L-#7afA2tf zO`CQjpl@N{-j$szZ!hc#Lvy>*9ep?UZ5q^;AK*<(T|rgi*NRvp{S@>r2;}8qNMooBc^vY}-a&7B7K_(a4QnV6`bTmzbo<^T zi@M$xk!}vwUY{9_UZ+%eu-VY3pv&L~H^R>+vu@P6OMgJw9UXDHm_2}TLj`;fAW&8jc!`k5;h-$J6rSFm%$PV9s zcC$Hf3(7u$uGxyM-wFS751}3mo6650z3|*$i4on{|ApI7kE*GTXuORsk8#7NE&Sp8 z$B7Ylvj6uEsWsp4M(gwO!+(3xoX^LSQ4V7lB#}$#c*c^Aox8g1la(Q{bUT zm%u$Mq04TaCND*QfwlP8*aArQ?ZkJx;%P_?F7MF0Q^y{IIxK;9Ln;Pz=-X{*W8ZG0 zUWLM|tcNJ?7km-o z^Wc_8!-Ktd)c5H=@Y<@8xhg$?EAMtKH3S(WPlZUiTAN8%b4@wearf2waAjp{WUu50fvbk(-=Yq4d}_7$BGJPqP)$%zmihkAPS zth+LAlz%o5Yr(Y!3XekXeK2Av+&|>TSgoh4r}8t{g+8y7mgw(qo`nuS03E*r_hM-G z&>zyDV>{7dW1(a={2p%K2J4{vcAXgD8&UsJ_)#aPb)$5$xLm)feLKdf&MDEAV27N(qLh)V*g$KBY6IY8PLPHC$?ASD+@aDRvf;GUj z<*V_&bS5|EOBecTk!#07dn{Dm*_S~Rezx?+2%7J2)3$40%2zTVke^o{Oaoq`75VB4 z%Y6O2Hq-`tW4-A?p^l-RZG36cBXy0bu?X8S=%YP-RzR;)(0FC^5!aPt+IRP5nu;M) z(hR|m;ax~o2_1_6ANJk^JgQ<@06x`c?>T4oeap-wnd~760YV6f>>wZl?p{rzQG*Cx zK)rGoSpwvS01??lgvc(kL_~;y>_P;@fCz|)hzLAHKtMo5`TLwRlNr5u-@WgD@ALoP z_ddP=IbB^lpe35WWjR-Ob)TPYaGN>5I5Wttu` z6j4qgPjGva^hTY@Wj9%M*{l@Ehot1B&i$V)By%($_wa_9zXYFa-i~@G{h|9FUJ8LK zfS$UduSt*m2W*Gt0}`L?br1DG4?X`3{#)NVxUaBNp8J`W!v^T+mIGc$L2UJM`#ixO*!SU#0zbhtg`Rm}46e)v@CWpgL!Cyv=lHAh8q5 z&orhoQkd!@6r{Qfah^X6sx`8?=Rqab;?9UQa)&wipUS3~1=4u$D9bG@kev|=EH#v^OzDCu|qo!UONHlnS?;|~6Ckn}`L z{7-#=O*&~Z5S`T4&tAOf+DGq4%GUrX--YL?_|d-aE=bn;+;RN zQzd$PoV~P~yYM>fN?c_7s`(A}HR}rTb?0ID!v8w+4YO7FDcFEM6P5oTh8+oq36s4E z3Kv0fb>x`MWaV|G$9HZ#(*fZ>0_AOyq;G^`fUV~-fOTpDxa?C7I$7}#tuVW3xz^Z9%JlS z{N~BgN(^NA@D1k5Fgm0r$f9F;13ksNf7 z+u*@Z{R-H7Px+81$_E9y4;@%C=&_-J-X+7z2M;P480b?nR93k)n7s-hYixM%CKAy1SIDjSLu2;8FtYFHF% zXkhE|f#mOd%F77IP@Jd$3?>l6RfsYIGLZb;edu8F_dR6_f8{tBq1L;JnnG%z^1@DO zLfN39*!BzN1O3W|JXii`8K(1E;?7zN%xdLI&AQez`f-I z2bPySO{zR!HYCuiWJvj-vOpI?X<+%V7qG5x$GK&3%l?*HU)krlpw#_er20u>bNZF9`M@s^!9ZQA` zDK9N68AO0f0>jG4Z=~(z1jF+LcF52)tiMh$XV7tUo~!iWg=ZV82^E~ z@;RzvN-I#$^=K(nqW!SMxWTa#HPRR1EWOX%m^~YIqhshI+Qu%WmxeA&6}@g)8`i=Z z)5%8k8O+daL|gEAu4c&lk6(E1;61e$=$~p)4L=7h<;$CHZ7?*|0g9>8_rbgbPQ1>} z{FFY753#eX6tyOC3%v>!)9F*V(8-KVnX634^^1Ltu8fm(6?4)55p$G%hn>isXDZnV z>{;d=_5kw{yPCPm&SFM#=jbo^^~?`!4gCpMLm%Xhp%3`OXbe9Ez09A6clk}QfUkx( z_=hL)dCPca1)nmWziSac5?pe10D_6-sCFYVSZ-@mnvEbLs+}{?eTG!+0r9`cfi8+ z?77`A*!dIm9|!3ZAcv=2f0zgIc*xNOEKZx$woh_@oAna3p9JQS5ODVSt6vu^PyGx% zXD<8#dVbF=K~JTZ3thvx*=ad+p0&W4Hw6wr&(vwatOx5R=9x;m&nUW}mJbytKb|l^ z9s#~8`tLA{?l+t6dJYC(fma|iC6w#_qj_i}ypNn&W>2SP!*c~0={%N1_=D8K*jBoe z?PXg4X>*|Yr%?6@Gl%Zp-RHGF(8TWF&7X6;|gUj78;q29MqFM~15b`YF8nX%bzAa|8N0hesa=~WF~``qhx z=nPs|2)=mz&G%lr`eNyA|7P{rMemKXHlH9mSP{;?SkKlS06v(~E7?;Hk0#SB$Cq|A z8k84OuYhdRfkDs>x`UAo>{du91jT2v@$I*_EK#y`>9?$Ammh!-P(%xWxEL_g--<$1 z)w8n?09pHH3q;wzqd!a_`V$!?@MA ztRLN|B8pGSt)X}oN~QY7-aU#6MYvzJj-9p_n3jb=w`v_1DrWkZ|FKo&-n?W3TeTlh z$dp|qIos%ht+Xe)YO2oZ^UiG5dZA_`TfZOdlFn(l=mMWuxCDoJ8jJ@ z9n)ghjIX{vZbXIp@GQQ(seAU`c=N)G3jVnb?6v(Mc#SOYGQ@@BxOySV!IB2HaUZxj z-tA(AxCDnQ_C+C9Hn3~=0c{LPj3KCtyMDbV3Q^a<&ff=qtKQd(@X-yPjbpw0+W6>2H9XT#$wie^hp$AO9MN0AA}^qlBi>?aS+?0 z5IY;#D<1>adu^i56UWDz&*LB(_kxo`b_W7StSzTDL?L!JusipH7bw|Bp*TLy*GC~5 z8`$doz}dq())Gldqu%14^JNrbUjw^sKe#DyIw&fBR8K}B_BXIg_5)=OQ(#F%u}kuk zzEL59q(44jm+ymoRzJKsC%;gL9tcJ*((ag3r3jJ4e*jS}21%O$uf4WQk)?Lb?fif} zx|ax|uEabOiVrVYT>ZUSIbxczlRdH*EM~?|>#fGHC>Sg$E;?qHoLZ)GLNF}e$zD`2 zG@tNf+1~N03>|)RC1;nxvv^Ut+$ zqIvgwresk0&?h4rc|_yuI(W!qC0O6@nXM1^%U&fhzt@twx^_Ks^@-&jZf9T{kx*;xO(N1|`ylk`rv!NbZ1V!1yl z?l|z-(kBN$JG5+gg`v;+CC3%@uq)1AIRjCHdJn6H6EH%^yv|*M6YR}DA3X*iO7rzw zjfdoo<$HQ==JwDFq{YlG`k`L%pec_@|CQSJ1nzh24Z8LnAUkl{XxKx)3_VLKp?fWA z^WWPooi(2ocDUx9ypJ1>N+4yb@tuLPf8{#8{it>g@!xQMP@O%&OCS3+l; zIu;UbcmKsV87!HGO_1TXS#8dag?HFRw?{~*gx~|X8|}PD3;bkJCU(PRWrJ~H@x~Im z?rmtfKavQAE}sAS+;1|Y^#>n{d;MeEt07@*Ov5buU;(FI)u@Fitrt$5jbCeUD11 zJ6@FX&YqfZ_mdeMeV=9lC*nN39ee!KE(_BDLQwesU z@>>fa3lyKIrm=P_PcL>HobY$D`kWY#SV5mz2?1aph^&ooRJO@RQMH1uUPT)71X-_4 z@s@9Y{OOQG8QQrk=vi+=Hm|`i`c{Qc$IjVx%Ft$H@RZ1l3@tE%O&=;Kii8DLd_d<9 zsIV<@(uEat<=f!3OAMn6NQO+ArWpf^Sdm7o%p#&Q2wLO>yZR(&)>)-fTK}u{c(tC| zEt@|$u5=4o(q~rC)82-@otj2&<7#!}+_54})3m4&nN&_4m?IPqlL?C!les{%#XCQ) z{&)+k>Uwp`a0l#;q@cqcj0JQ0=u@>S*^{rWpqH)!E?^}Ss-4VwOblWoNkAP+vrZlO zR%uqoZ$t7bq{{8MSJj4u$igN4yb`=vm*f$p#6o&<({fof?i&SR;y=KsjzdO6boHEy zi0HJ->*y-7z7tYAOOCw9Ui4E$UnuH;Ldw(1MTetOp!O|#+e%2MxtuhHjgPE!;6nm2 zd>q0pwBWwoN`{mUes)ME*=2_g3*1vODA4JJr^3SYt)82ULpF`aGuHR`v3{uaJK-=OE`AYl=Gk)2a8AAQ1}=3c?|e;aoi zX21$sxQYJo1Gfu}7S_N#7!ARH+?$JV`q_)Hd?B&d%s>eoMPXu@(Oy-CQKF7Q$bi7) zBi{`umd4?ujU(SDBiasUF1-Xx7Q$Z)Rme3!ejuf#>0zb_r}B>{bTbtj9xxVI#=@Ol zgdA_EphKRvZK*+k4t=0(TSfm~eQmX&;@u-(RrV?(o>pFh!wbPoQF<@=@enR;6lGwd zRwJ$1B73)LYv}AHs9Oky1d0`S&P1`ig^ETvQLj$zj6$Bf1fv#$q{qthI#J|VhGk_< zva0;w+^s^Uo9(N=hslcoxlI&h%%MTHAaL;%5octP5QUqji_gEW!V+#*U4d;2fV0Ys z;LMR(8>VT4%mAC9Sqex|;m>bYdzP%ID_3CY0Ju;N*O;*^>g8ML579QzkKBvVg)4DyW5iNEFp5 zQfdt%?UvqziUp7d8HI2cDVVVR>$Q`a(!20&=WfF41<)?DchN-XHUsj;La5Zf9R^NB zJ!e46dgxESJ(u0rnZp#Jc1)qQ9s(mkssw6)v!}OzrY2cUN<(JPteU61+2$H+&_adQ z9feS+BwHJMbK55gio`itgK8Iml|p(OiuX3`cyHA2O)-l`7D+h=H2wLRPi;T~HXW!%Cl&3f_Y^HCBvxkh7maF7 z7uKDbgLW$Sp|c&49Hd|DR*Q&!F@FxKUjzl7_7PXdik)f+SuFeJpfmFo)7(lHBFj^t zi#?|O;^mvl30NBT+*p9FEr2YxyJZX*TEQG}z64APeSca)B%#=jODaOrpV#N0ss$kU zQ$<=A;8~A_Lqa50>cAu3lH?M9Qt9cojUPf=kX#3x)Fw<8L1ycSJd z1b~eQi3T!3lOxk_O+$40op>EpECM>UgTSS9fd=&mLt1wpwGY(V&!`t7(DRlk`%>Z@a&Lb zWkX*e%E!=QCC?5i88mG8BDv2uQxDE28}yU-o@=I67tsq}!pmfb{sf+1z;=HZbzerm zfnGsBqNnzP@C|bv@5U)j*5GsV=Kb)VCbyqWrxl#pQhktPB(H^6rU9U*crOop%5$Qx&*)xrqQVBMl4IEN} z*Oe{j01+8~G9)?t3C=9zIFN?=*Fd|jIrnzyp4rNrLZz@lUz=X{js}Ot!+!@!uQEA_ z`up`=b-mI`I(F}xb*Bs#A?96N^!l}Y28c;MRRF?9RpY%G<=%~x*hi+FlR zGdIQn)4aVv=ikPwF>8%#isnWY!i}Z*qnU-3Al`|Ru`c4h{4iRZl#QqW@Pz?+lNq(P z8pLqXktoFC(aijDkk>gol-ngM7z=kft|1Dse>AhU5^&pmNmq~?$K#wPDn~~%hsQ#? zKfiN^FSm;pS66lXZjVA-8Otw%z-LM(X)n31Bf9Vrw_@3HCc~@MDi`BRUOekjo``bPCX(%NOhEQjTzo7eRIbGc)q!(xvf>NtUHnud{kR= zinERW&$c*rHr`nFNyNcW$y8MX&K%;?WeoPmV$&a-@ZF9GL=|&kJml+ec5_M0iUpDQ zVzB0qz^&Eb0%{28HCHQ@j`xzSy_%U^4Xqq4bSZR7BsAptzeg$D zsA8s!2iB7#a^7ZfImxf?j8do`ukb*blPJm*jft$fL8_xT>c%tM#zP*D0?jzu7Z>!g zA&TQG>_30yJs`$>nM&H6PfiBfo-49akn?8V*x4-o{d86 zpU5;!1l%&87h5&QanVH1s1SC{jhMvTs3mpXsvqz0Ywv71u2Yu6l}XHoN;(_Q{%DUr6STueG0<>K5V=D%aj>Kiv2Z>RyM zR=va=uZF*ZD1vC$X%k}O>}V%ms9_F`2V;Jk-q0dl7YiqSe&uWeG5k@S`x{&6Ke)Ha zUKeq1|FaELRGhgT%Aa_080OXM7g_y>zhvn%sqXBuJ4#Q}ct3qP^P*jRBI)@)>!3%; z@OPnSn};7Pa%IZxglywJNO=f483wd=_nHA~U<8!?tyKkBmI8eSG1HKKAL!~KZ6_MiykgHG0@aB*rCm?snQ&2}sKQ^}B&8qkdbuGo=kliRjzeRo!8$2&wp zeqjQ%E`P9V+h>)dWablL8d5X`o1!V4`M;t5-#XOh$WT+oCl+p;xoN&~j?m^x`0RPNZ30rWsqIMB8OeQJ@svs&Utvmp@ZXKzV%yR4RIe zUH6Ma`eThMKst6dRKW#lFG{-K`ykvVW|>;kI+rMRG-=ADn(E}$qkFzq>`bwt0>Y9BkAK=H)BdLT!BaXoz-r&?*GH*0RKiio3XI)?=(rHJjhj_~EbKZ^3A5y$ zEb?23rP%@jPpnQEtA=5&dLF54ICZ-!Km1y~_;{`oc1vNJ$xCMF+?Z8$`h69jAIrz9 zpk6}GY>INkXQsY(ec5ika?$hXcsMNa8OjNOpXLG?Tx`oc_KAwbhS@3Au+pUMc69O1 zci*3X+Nj`OUJbR95Xjc?30YEHCYY_u32st8c>;`(a5z&GQz9F_mJPisQcgDe13GO(Ej+^egGjg2vkuoEkabI~2{o3*GU#|cK&BCd0 z-PEa#27kKZ>Xgsa8Rkx{wa+6) zM?W7T;N~t70y9RcpUKECoCXc%B!5;xvqUUQLQ;l$G-6egH(nU=!<(So7rq4$uL7wo zE&puohL6-n%%2APjGYoR8prnksL&u?w{jXBHy5Ip6(12_JZjyn_es~0#%-SlTZ{$s zV~yMM{x+>U;)+za+{uHa{|JG7)8L#jRi}Nu_Q{WtwjG}aGfd&g=Mjh0&mN4)=eg!* zQmP>}Pss|Z&dNEnr)qUBOoL6PupH^V!)hI}X7@~o)n=v*L_$&@o2S4JuR_tpef^&- z8TROt(W7%yKBww3sf6`qMkmv;65YtW!Psngjp$b`m(E zmxs061%du$L!K@lR5B2|yJh!Ms1F@B`01g6aG?9sPnSP2M7=+N^$}-?a{BO8*|6bT zY<)IQn1B559ZSuar%rR)UHEA3_HO}y3iaG&VI{ySWSa$MJ%gnVoL3x9VTQ9yQUK{$ zr###{%;?2tej&0A<0=sR47!ICdZcWDN$@~g(IbqBG8hu>ywf)l-h!*N&yi;N1N|X% z8H2jL2lk=jpV8f^S$uQrolLSk3CtxHR|3*eyg_V}DTB@=f)3~U`J@)<9?oF4gkKy! z64k;Rs0O}PPE<6c#thYMtUTc60qcFc49$5;MojpLBXQ!=<-|Y5# z&8hm9R3`s7W+m8X0sSYj3sI@E{-mpf&{%LhhbBXyB`)A{s4B?HPe@8LHe*ug2ZQ6l zcSo?fC$ah6j$S5L&=Fl-BTh)A6Mj!d;-bNh-to?r>tmGTQ_FR4P8EtOzH~yvmVl*|%wi7vGiA}2p^vE(FaJDe*0~DBxBDvq zUORkH=#1F-{l)zIuo{yp2b*>5JtpVduUQ|&kiNK6U*fe(# zKTp5lX&Rkrr<799uS=Brsbs%D`tMIRQ zyYziib8ih8*WAi4BPgqkJ4tgz;U7?{rqsGiO(<^-$g6sWdyNxE|v=HG~;%J)4fI;=G6MKS*yQ$(yq-tl!ZSlV?JZ&1c!rVo!VnL zh>X$xodhD`*AUU%Lh}}lztE_yhl?4j7*=8sq9so0V}{mqv>ZjHbwl|b8nuRf^t$#Ptxkth5u&fLjln?-k)3CH;@-~4&x=dX`~(muFob@m>% zn+UvKKwK)#x1}jw6e*UYB+{=s8<7vniMxzI5XlNNQKG~+iCw3cfYDa4O|Nmhe}TgB zo&Rq!f{KwU-uhLw(uU#l;rCW@tv$Yt zYmSpA2d=Yi{3Y;5$BXV2Q20c*F;Mspq;E#9DHyVt8@W<|>Y)UKjVZ#ASC0YUl zI5TaRnS@AD%`p|H5_{fKL$}v4)*PMaz1MEiP7o}LU%lo_6($*5j#!>da(Dw4>DBV_h2>^(3r3flcCy%tOhfv$jzJX#-Z-_2>bH0`$`n~;8e?9Iz# zlwH|6!Ziz|Fs21_y3ATItxLSk9=oYs_r;EPv@rDhU5kOyhjgr*AjQsnMtr4~2eDzL zXAop(BFbQ*D4#=fB(ZAN&ht?e+dS)mGN)3MDJAYir1pBW{FrAfDR+``2Nm{>Pp>HCMumd4y4;D;h2^u1o>Q(p6h@Vv~ zWJpf<2T`Hk6eDVcDE=-KJI8Mv*`T$@qD(APYs2fv>kIk%I!bfRkuJVAK?O<2&Z@vn zL}8kuB#z8fE24bl|GX*AX|(ty6*dLi6?8NCy=jN*$J@HZ!#hZxN*pmpk`P48-xxh}ArbgBfD z(GHX^NX4=l)m1b^I(|!_nnRM62Aze8?MjR1kJ_j$#@&HYEa&VXvkn&rx&%RqL>@ci zxb}CI7U_^ZfwhP+2UtExQ^3l~W{Z#%fmL&s%$O0Sc_2{FBZHR#y$53RX~xzg8#P>4 z0&_uddPNY8G-3qcU5OIKMQ+)s+34&39>sMdu!Kj>bc%9h#7&&K2`XPo-kHE+#2AxA z))0()t1+Witxx)>B3Ofv*~`)%3qxTR#b6p=RbdKoYGrT<#|4};C76NI?$y%bZ6<^` zo}w5F!-OmhZLw+nXIJjd)hHB>&?CIo8(t4^=+1vG+vi3QL)J3Rwk;!kL6u zfsCsMfy)**&lkTLrF|x}mZLCP3pxjiT_L%!LM~) zGe`_@jNC#O+gzqIrDiN_fl5Yh6^LB&Un7*}V(%!loK#m-Gg+ zrY``iW5qly=;8K>0F#O^wY zy4T*z{|dbwHo|>#pzj(O&^ml~hvd{)((5@_K3Jt*ApR%NP08i}MnJj0FK)g%bCkMI zG|&fVw}BCiA}0|YTA$^$X+6p+8qN9FM=LC({T3Xr!l@{Kp7w^)H_9H*9AyGFQRlar zTxouz(40C$ovB*c_K^(+Q#>*9)}E=*&*n zUI#c7Yvqe$HzyOcS^o@{S7BAubH^=FP&dQ=I&L2l?IopCVLh1qe2B_)cM7L2hwO)$ z8c1yFvC3^~kLCPl6=DOj<6Ct=60!LrcY^8a>jlmADftd#0&X*}JadG; zr`h8jn|L}fZ)W`hB|~{rQJf|+>HLO`yVYy^liAA%TP2netU61g2qsJkvcS?hqU)Oj zcA_>%vRay1^=|HTg|*iIYCT@9r}A^5TAc<;A`WI1Ti861)H**QF}C3y!%B*kO71AK z>uec8vpGpYt}R?qL(#Bno`NEDD=<*O$asD9iozjT+;h3fNJ<)%DEe$1hzT4k$P6Qi z4DcQe-mDJF!kG$u?tcc)tMDotXWy9@X~|Nql1-v0dytAx;MgD&6-7GC?PC+}D{_YJ zZL3XMMv9Etcy(YBeg%Tw0TqUf|K5$t;1Kb@mOqW;v{rU~YJnw|41VLtxeCj{UzhW0 zxk{sI9iKGxZJK_yBe%W!)o+5u7R9M+(^uZD3~7yck}>;R1}#D5 zW@e(M=9(1-ckG_6FqnKR7+!@@DK1{BF!uW=zOIz|yji{e+*VXdmYZ=QWAJIa6r~*2 zbf~8bEXE#@8{j{^_5D;(bqsWt&Nk>0GK`U+G3te-FQ(U3zOTGB{Z%=ymaD31Mddpm z?ov^lrZ3PEYxK*U9G4LE)b8aG6u&HwhTkD5j<1cPsAhhqojTd$ko4YI)R}{Oq9}e@ z9*tZ>P%Lahv7Kq4jiC-6IoQz~vm7^`UK&C1%W_^VS5ch36h*P08-a3-f+OA}sou;BTmL>1N-a&_)qB`iFHb+uC_=PKIEIk^2|e&e z03AzFGDmC;MI9wSqL*g;SW|ri>Jzx#8^4{ZI)Il7Rp7E?z1yZ_+Raik$tgy}sYM^H z8m}DgF-wG*P>8O8dQLv~%(3m?I+cZRTG$OJsTl%?nF3uvi>JhK8nZJ_u2#A-bSto? ztX*^7P)0;izl9UT1kn-YQ4cXc+RZ78&rVeZ$aP^k2uXgP;)n{&>S;dB$5BFprs3$7 z39@niVg*;$KZE5}SZ$;$)+p=|vuml88O%>h%?NeOY>{b8m)wV-XJ2bmr|ZG+Gq5ldc(abpL!+VcMswMnyo`trX?Go1r`c760z> ziy5^_C#C%sT=Y2?p?6~3yOE`EK$-{zI-K1qdQ(!hThEVB$HsxVx$+XaE8WECtg&lW zT~!q8NI@*j!p+%gmDV`rtV9i$3Q-sv1x9Z%4(=@)k)&s40=9FK#F{5Te^HV+t*X+% z=|?N;epV83{;O4+*jasL!@Sqjca#b{y-f=tl0)}Yt;!8);4FP3u|b{0wsOTe9j0%M z4%aWsd9_@{J?(R4xQ5UA-OU?&{9EphB`-u@w$Yus^&Gxc?z8Cf*8S_Dv?I=M5RTKU z;J)YDDN#AoIf>GXI8AsBarYX&gxlvpax&`f{0XEFp#5}cmlZPk#clsF8pcy&C5R-xjD@KmouPUIohKnj11m%>yhw2up z+x$LZAsf)MINzyrr&$D3ib>GSQMZzk{le%GAN+|JcG79#IBS;>Ythl1YSF4O2`a}b z#RSXG!fHlz7g+_Hg-5(gqy>?U<+!W-^1ZDpmOWA>>t)!0i)G?AyAdajG^oXgq*W|s zcTCH}~>22UR2Pvz;)HIOC_iPz^ z0!jz`k5SSthk4Xp=h$}(4}_FPUz8`Zb_OIHpt!v7$8IQ%_Fz2QaD+8ja_QR)F^}%S zmp>m<@XNxcMy&d9^NJ5aK|EVu%{o~|?_wekhEyp~`J;lE7+xFnRcuR&Q*u~KE=os> zj+p=Q^f`^XxZ8M=nF{wg;@rt|Myk`;9aq>yeAGU5-bOfkETOmjC%&n0;)!=&9u1}5 z_`(?4^Yzt=V>kzTN&Gn}gA6ujp6P}McS1}J)LCdkw z#B=ratJ5`}V}&uEuO1tHg78c*pK$MHoxI>wlHJDodd9fV36I1G+UGgT*jdD+>df6( z#eIg5kb(_u$YS*5LB5tlUdz`zaqIREUVlOvS!;IGT0aTf`RlZR9iq+N%7n^-H&xh)LqicQXI zjgz$nTj?Lcq*JIc4M7`?g2F-FQKi^|xhbLJjPL14F3A%M$wwk2&nB*CLyRPWmDi^s z*}%ArVj)@)P54_o?)96>tuXOu;x+~q&Ic-TGwbX^jpnN4Gt2-A3Z4L}MIi)|tzXTt9-ude2c_ZKY zOwq#d&*BBTO+uTjW;U%?x2}D^zW%UkHrI#^$Z1Gw=`bd?h|QL7HfjKg*jR~=p(Ljx z)uLlqlg=KD#Toi>OB0s;csXqrc%z9I46!WEyBfb)69G7cXV7NM>McUjxX% z&Q-eEkW6%4nbsxg88Y`6B$^pPd&fa5ApBDY;vg>>OUBTi{0$BsikJHCC?n9o&P z;Fkc=n5#r}JAZZYh!!fxgkF*$W(IXaN^H}6_50H*jb_+$RGJ2IaTU<%R>o>%=tKt< zlw}!ie@b)3boOW%7hO^?X8$J@iqr~J@w!HhN5a8LsSdH(1p=4VijS@1kC!zy;+FtX zSwKjBcqY<_CGrNu=j91pZnHQPZ|-P9@k@X>6r;aWPz14lzq}my9KAkWkXpCV#l+*= zr!^#@e*}ps`ZpK+pr9dyuFDsYF672i&?Ww&!{7QQ!s{;~qGR?|T~mK-({Dq%!aOXs z&J|;g*)_MRF~0#BmvkbS&b;$J3fn{1Sjy0aO&E2+t z2FPoqD8Wuq$tjTo9mO*HW~PQF=~h6z3Z$aC^mT-rGlt`cO3kNGN{cu_{PET%Zhi?6 zmBa+agbNWAHO4bQdkX}{6PY8lx_pl{q4*^LuL7tj-cToc3brmaPNU5fWx&e0hY}|M zMdEy^OLXfRZNifkc*J;w>`ywx1gt<2+Z$mo&1SR^V#ho$f46&WWChj}wTJO1GPEx# zqS7fnJ#W&7Ya`e;m<}PvZ3GUd(pYDu*~DHF5@fAE&B|6j`o``k@D|fqkW&3T!cJb! z^>D!I5W+GO?l3c@Z5`4}n^sY!MHZrV#A z6prv>T66^^><(!Hj#fspVFxMA#NM;ISu`@}0O=B0;DR)5aH_6K(th{?j4A7r%{yFn-)b_onEI=94pn(siY(Ys5rf_zJZk5F+M3b&~5x3&G*~2 z;iala0*glkyTD_VdCw{GG|NBI;T(} zviKbh%Uok4lgqWj$ta?ZUDG=KnDGo_mS~P+c)i0UnPR(iO&x*A$4N8I)ohwb@d*^g z*_6Nt0Ol~FcsHUrF9kxnz-h*2SZ&k_t>ey^<|34O4+|-GbFsAIbtfjEQY#j=ST>Nc ze}s;-=;Q?DMu~N$WeKQpYSIyWZ>cBZKTTesxf&JRI2(c0)VL?y$ zM@CaL<@q^{{s~JZ3K#@^f{~YF1GlM)losL43R?~BC2cVRmBbVKNu(&E%Yu!jz{F^N zN-GE8zz~^+YWT~#MWl8f4qdUYBqqOwWkjDyOBO`YCW^9S#t9NjOc=_paV@E4&g&XK zmCh%Yr@G7%@(?s{pgK z(i+bpB-!1vX!FF~r`@z;hnhhBw09xc!fo4i&ZH$lFEPUm=@D5{_rVUunPjT+*3ib# zOt?d5OEA0WNApx9xqfAmY}=vcKCkoDAnZ?(cwbl-Gs_xw?odwS&DXMtp=}q#i9KBD zDFbXthLCp0a>nB0Z0S9?$MGz?Ul$hd^X3aJb$(PB2)o1jKI!1JSrhb~jV-Kga5Hz% z?Ffi&v((<0WZn+#i*S2?X}~El`i@*@`=dgdxqH6Lso_1ekl-a;&1!Q5rSe>QGRLRH zcIC!77u9aL*5)!Ox7cI^ab|h_u6j|K_D9=R(K)P;<6>wJ5tG_6m0sBzYicj5%WH1C zix5JTUZChs2|(FQ6iQR327?eA+pI3ky(kQ)hL6|xxjJg=D^lr$xEEC~35JJqA4~jG z_Yw4`s1|;L%#?iB0QnHoJ&uN3#)79F&~;=F@qUBT)!{|6!)@~O6<}Kqau>^E%~=QK zkz1qg_z~~jc_7CeT@U{^Bad3iQ{Gv(T)A0AOwPmfeoi^3G$c5rIC*ziy@*7Nzw7iC zPLMdVp-4O{3an^wX_h#pC{~rnc0_KcoM4x;0;k+vb^2t{5_c8z*qJEIMRq^2`$eO` zc@u30gLbqfD7Q2!4@It58Bd6Z*SmG*ObZ-LL2;xlvDp^qsv^?z4kte9CW z?IDZ#FMZKpQ1Pf~i(lQ^LaBLNTFhlzZP^|jqcgBZ?YLG_7xcI&_Qlq1oYmVV(_l+a zplP!<2aPKBr7Cx+*goGjigP1L)?;2^TefDIpdO*fb4BHnMCFp{k#?@P|IE5+F4M)Z z88IX0!W^|c9Xrq2FS22gLq=K%8xSj)z{c?jh>r<`hWSxkTO3DOH?L21338mlR68?T ze!y{#>muXq&ieR31hs3_@@(wA=2*%GXiD(Xj3_XI#f^D8Pcwo0F|F|yRCsTgro!7W zQ|DaI7NT=Roz0_*SN?S5yKgcSG8?>0SvJ$na2c*R6~AWhB<&KIb(?PkBX$#7nwbvI zcw6cjEFv-TXzQyAvG?zX)1l> zzZ-v(;Q5dF=dNjjXJwmhoJ7R6E-J27!Bca7MC3Zzwl*i(Fhv;!it^KBJQLO6kW^Mo zv~T)y?FLOq9c?p{^&&9pDKN{#P;vpvh=p9+^wrwPM4wf3oXw=Dyfg~pUezxCB3fQs zw30O<+9?Ba#ORE8`B0?%LeVBJtTW~$N~UJ9*;iAembb)7bK7ob(-|;w6j)gb+{&dp zA5GDOZ;_?AG@@lhgq9-oPHXju&^q1rGHWKf4SIm?sSR{v-4FXO(#qZI|8Kd+=;nDj z*q}UvELGnd-cvqsV9D@PQlHH`7rry)NzzG{xqO#b;hE9U=_eTY0fe6AIzr47mU_$b z==4+0eBV4acgLv@L4AHfR}pi70nV7~FR5RDZ)Y&P@-iaNQrZ$jLq!vgN5taXQ6eM z&OKty*}Af7meL$&tgwm8_b~4v1;?yHdTujHdTA?ic-yw@rm3i zbdIMW%gDwZ4F7ns>c`dUHKDljrWZR)e;o62rZU#Y^Y$ZTZ>L56OX-MEdgR3nqb!wm zmo+4$%@>-FMf_d8dEDnt98(~^+Pv)5&-SQ(m0tqzDuBx8vO}Z3_m<{h-}?Od;Kscf zL2s}Q?VFpam=%Js0la36t+B&`bsuOrv;LDBO&u}sutLCtr9%Zh9<;s>ot~FWW=-zz z+B)k-qyd$!M$v3WDl25BMPB7ATgIzfn;P&-0A2-9@qeZ^fS|b8Y9hG9is4f6APxGBv}e2>UF`m*KjjGzpelj;&5%jMCkbkw8&hre=)Z)zt7`0>t?$ zKRFyhak5}HcpY}P$7yrL?qh#5vtDgiA~w!1+>gN3gXM~vF?7(S`K;`UG}zjp(Mh@$ z5U&EMw8lhfT`xR@^uPpUL?^^Hs7n(yTFUBcvm1G7D(nI_}c`oQ?f%Kg50ZadkZK!+{3@z+zY!#RTf!6JM)xuwUB=3RS z{?@rqS*ZCGcmtfh%)tPkM@8QOX=d2K|4~{|-RQ>0%T%N6Q^4C{EUH1(kkEyz0Dn(= z58Q?7BF#j&JzGc>%I$4jz!Em(7y^_()naa)UB;#54A{Z=*~{cG;;;ilkOx#kyv2rK(}!}pDe_^p_%c+aiv^|dF{Kvy8~{EofgwsN-o~4sxO>>vb%zS@@jtbgBNw;}QD%1BY3+$(`ykI+A01 z%Au`M{x$`VvNosRZ+G}K_aIW-gCn*_%P$8jIF!>8pjitP^QRnYh?cJm9cED~QTfv% zM>nc!bZB?9{Aj3>)XyXJbK{;&&G;Z%UYWR^W%6@qI=5LI{>l&4a-y8qBpv1<-9b_A zG@{-I0hv4$${^-|otTPVKSlXMTD>$S@XLrZYCS7vY7>vMYE}|r%Bh(`g<4(W z4Hg%*FPm;aTIHP(lOSZnPhThC0b)+FycT{A1AHlrBpksOR;gW`gNzGs%NTz(?Ar_*AQJyO*dScC6Z$|tBhg%-z9Yxt@ zXX~tpQlPx;JhWOZ?|^eE3T`L~6KFjkWTq()fI?RCFQyrWp^!i;KZwzHHiCgDACV1S z!BMw-UBsSkXg!S!q`IsLX>L>Oc3It;X!-HhV>xe<&FD$C%Q275rgzsx?Am_!27Dc(t(ZobpdBSsg)w+lS>{{V5E|kf0dTY>Y@eq0}%Q$?Qnz~CXL8ceK zrN9pV3b5FxWZ=`P0`a>?+K*cEeFhJD3>*3l9`r;MqF-4Fw)Gl3c+k*cg9nuny{F{S zCpG&T^Zf=7EE!T>f}Ooe1}W?p2Ktpe9S8?{bPV(JU#0m%}nj+3S#cG+9N%UOjS$Yp`4#@(`nlOcB?8-=Ya9Gl8R+D=1Jzw?h zGA9_FJ`e~bIBX`fs7W9-Rn);&rT5~FhipU;oAca-;Vy;k``=Sk2~1cFC3b68@DlWV z30jT@{0Hk*cy0&ejRW=-Fpr@NUI*rn)}gqU)HQH>daLx9CxNK)E54iacU0Q{zXfrV z2kZKW%WGFF@7TPv^w$`{sAt2R5hTfIF&PX3Z}NbM9dXHO>rPKlVzo+h4ObZOx)E|k zyq{_ZUpuRnE;Vdt*rZf}OHN^9o8Rd(+Bw-y<6PS7)k#L9!6?fPr_Yz)TvHL~=oyP<7)B#YjiXqDrPr}~*+sipf(N0=@a9O`Tp zgRu>(ezsP+)O?2V1LO7~Ixh9v=~<*Sh^_l9>*<_;lS=}{VJPT{)RZD;PVc_+nv3Wi zsk^NWjOa_ij9_4Zw{bXR;5cWhjITgmi^WPZbH%(N?e1mzOx3HwBZ|4Jt? z20@l|dOko0m~GH^HgwA|<}f*YOGlpXPp^QHH6lqu##T2Vcu$Lh+r!OsJb8EQhJ@4v z_x+)}on`hHg|_@7!t(`pFfKFeZW_=%pMI@8T6^k$j8be)qT&@Jr_NMWz|chdLfRhc zS47hmNp_ial&Gf#4x6kr7%6|0(W^%&L#B|$ra4Ji zWgc8xwL?(^t$W=2XvQkhj1V@Nf-XJ6k#1E3JU6b`p~NIe+2Gm4+Oq<|ytF##-diVN z8YkO3_T}xAowG}3voT~1v7tx|+0(mrD4u;`zh^Sbv~ovcsa?4K-7cpxJ7#z%vvSxe z=#w3BDf4RAXorc{yeny=*={gcZ04Aks$uO8Mb?{7`mQljeuy`V*zS~ltvc#se)J2G zrZeu*g=Ewwvix1@+xm)pOGe;YzxlsnlYptP*8zmVSF*Q+nh8>D%M1axUJGa*f7$ zLmYgNx7bC&?3P)b#ImA?rOmSJGjrZQXzgpI#ILMbL-3|y-~ROfhq^b9ud2Eh$IssT zjQh-Yo~PX0+$1+6Nq{gK5CLUyw$=dxSZGoD5Ia!&8X;l?gop?c5hx-=pokhF0wN+p zM8t>)5fmaKAR;32G)2_k8E$f}t*@`|`|I~-e}DMF+_m=F>+Er@wb!s5aed{y>EN1z zSV<%rP(%I@?~r>_ac2+n(r@2jyl*O-@@A4^H51RT1}+7sR1@0TtU*&a(p=XP-$!NI-QJBCx?2uk zEpM9C7xZ34rE(lDS;B(f6AW86+s3EPvs0f0Kcd9mQ*_Hz0Zs+ z7g<=@3zvYHWUt88gm0Qmd(0S)2w%?r@Qfa?8^*$J)DC>CSm>sNB1*FPtU8(PoCFtDsa{ca-t1SjE@c6MK6buZO~KcyGp4fr&2N2VH1*g zEDl*5esjR&u;`y^*JaursB?RXY5_Kq$x{KFZ@r~`^g``t>CahC@6!-C4FTs{pY!VT zCPEIjZ=>(+D^Vd80qmzBry@4^gG4}IZM*o|jk>k%M-e;I^gsXZ^!W>>8&<~M^bt_0 z@OeE|At%!pvF5v1bV}jB#c-up_akqcB(!6&gTAW2v;cMm8Q0Y4=_$K@&Y0Y{&7spB z9GS1cKu9JAAe3d5uXv-TYa~`O(|`kWicHaV>kwV@q=^v1{4r*HZxR&uL1dA^m9Zmd zy<>6}{u{Uz2UoMr_%4mWSIl5d;uB>ON>&-nHA}lVSi-ggrm~d9J-acM*U}?1j%_$; zCTja30%IT;T^zZv{D~}m2_Iw608na!1TPUpPLQx(yT1JHLxW8G$B-BU$so1!t2C(< z+%yRC5(J?-0cls$$yx*>dD8SwmXC0AAe|b_p!^}M<#qJs&QoX8yP*L)2p>lfp}`P# z?`IMbjDcHdepc3x;4lV`Ie6#N>|DYtAdwd$2u9o9;WQ;iUt62^cJs>`959q1l2;Ni$CAdLT+%gH4Z=)dBY>z9 znUneWViO@Bd-hB7G$E4G0QR(>%=Tx9j2KCf_;OGe>Dac4xGkvlm$q z?{~*Nnxf0e#1%2~PWkfikrxit7!e3-)g2)2_9U}hmJvvQwR>mUTQAm6H*%2Th?7(q`45RKB~~1W z5MA-=FVq_IRQQk4tw*w#pZMk_O`x@7=6$#xv2)VCW{scM>yL%POnNWs?#hYS%ZRl0 z+4x`ehM9CfHH{|YVF-8;B4;sW`N%!<^1{W>7MsoUby|V- zYc3k|p8ca(opD>*D86R!=g0JZ>IjMZmy&^j8VvT=fd>!IesiG_L23fKh=0ES!Grq@ zz!7Q*1tp8#TTiuoalHlTYVqu`iw}LIFGI1NT1)k%s^qociosUKjaNVZQMgsg=7Gm_ z!U^m+M7L4*%D}EChZ-Y6MU&BN)}!{^Mq_Yt|2sU!z%#o1@IE6ch93)O>0?w30x8-V zv1XW#54QE!`@6s#pjZGUJ!IPfsP6eB-NQUlbR)_G4|n$W<9LjLXMW-XMt>nJ%wui8HV7kvxS=i^OQi)HNh(eAf-@g2T5mlkoaI48ef=G!3A%+3rw^HQn zddv94>>tC)$h`CALgO>Fj#{`5Dxs-fSq#hw`TM->12c;Nx0|YT(f006CZkCB+|8Zi z_(M2jz>N;>d!lnH>hKY2sE4*+;ZBn4cK`mHfm7%IXo*uM*sfq31i1ahTL`6)HY3y z-~8sR2XECsg;)oNM&`lB43Csh#;?}19~kxItgU;WZq_GBd>?*=W&+`t3Ka9xVOU>& zH18?h43vW%tI=A7Tu}x|Zi;kzNXW-cQA9PwjJb~(h*2ypK-)Fh)JM|*F<#0D`ZfIw z9x_pia9{^&LR>OL1MDCnLlcm3k)+&5Bt<#HXmohC*+9GVRx%a61t!sxr?V|B?VFkn z23!+JE-+Um9lXb@D|rkyjl7cKJ@d^A22M8|nQd<*eH;K1g#Zf}l_3GekpQVIDNvAg zSgt2)&MsPIa_XP&t9S`i+y@**u6j^d14<8okz%2(3LgO(IfXZ$ZEMj}#^wLR23@WK zAGhuNuA82Pccy*NiWFZk7?K6VAMi`8)J!1@qCRuF>EFj|q;maZjueBwgf4*jA8evCZJ@ODl zz)cVt@BZIx?m}1+JcI&}aQTVM7=kBPb#+l2UW=*}5V7M361|aqUCY5Lti4gb4C7ISfNU>o(?X{Isl*lsEeVF{I9_9 zs3Sfiu4Y@QT4o(J5wwMKDRoN)31TuJXicR?cF<{2(NFx%`%FAdLs(a^AF#3BGUE@j zfJ!GV9p_4WBmj(OLy(mb zi21;pPWYZ~m3kntlSCPT#LrLfg143_NrD)ZOTf!5W$~jL6RsUS=gVFFS)ix@gbECm zv@@^Q8~4rVq%pHsRZ3uD1su-c;hnSh>+q>d{>^gsVQJ)~i4(?*i(EU!sG~6T8FA#Q zEruko=kVJ^mT|ba8|I2Eg-y@l$K#b6go&15I%Ww&3!4||H*n-{z?Ll3H2<-crufDW zKTj61q_3DmZtKyudFH!%z&AhkE9A&4wyXIiE^B#z{&6SuAAqgvz3Iq9E7Qrl>cKuT zE<1{&iZjEhwH@k9{{%ch7H91j@$AEjswOz*{`hdyuFW2A=t5xmZ|+qC^$ zy`JYQgq0;|H%Z)_OAy^%1QB(Z#sLu1`K7drD0B(#hgjfPT3{&}$5e`E5#l)Q>avrv zl9{Zjsdl@;e)0d@sPn8kIRCM<$g>sACtZm<`Z=@4^))l{m;!Utq4qSVe}j@VQ1n`o z=k)Kb#JP>sa$tA$DV)&P?%{pVCpZ#H0}y;{NWltFc*U*c<`rC%bz9dc?D*DDS9<*~ z+FD!t;7UV@(K85;8(gbInUh#+U3EMIT$Uws?CY76TU;&flrkHq*SD=|_( z*9gZiglh>71Bn!RB>M+SrKu8@fFdhvz|95p6^xzc6#|nstVmKt$koGAt`@c!ir%gN zTKZj+JO5onT@2_}zU{CgWRI7J9Z~BJnH723GX1Or%O3 zL-R%^3JX(JTfp$j-mIp|q3YzlY#tnLeZbsH7xfiz+5etK7n2L>49#9+avIkTDyi?_Yk~h)Y&>b1Tsx8($^@f-e_w+LofdaZ2ufT10kOTp_k8CJfDAPLiY(5 zAQK8QY&e81!F1KfCiVA)GmuLp1==f9B=0tj3Y5MyzdvPS%oGct%h*z5$fJD}xk`POL@x=!4VsAP(zbMhHWbX$7Cq<&tVLuvhE+UcZ7IsH;@ z*eo~BJo0Z4dc0B``PLl6OTdk#6JRC^hl+eX9o>xL*QRfPo`ON%sY%IMkAZ%F8qg_u z=@04)*BB4#!5?CDKBOLha z|8Of?U5G<Favl+@0bXXZ;>)zII zy_h`W-2f}$75834m%=J^FF9&=^Wt5Nxq2rvgAEXQoCrES(0YmMSoOH^0c(S`kWJ=M zOl~fl5p=Thaor1xpB>r_c7WfMc_bzMTDkUd{e3wwBisQgSB&e6NSR{nKvV1xq3OC& z8cC){mP8t!S7_9>wTn*tL9e=28{Y!xh}V%XMLq67QNk`K2ZWqSeq^@UqR6AQptTll z>)Sv6gYLq0ChL7*x^U?~ANy?fxqZ3S1vt7aegKrgiONh6Aq7T2aG1zoC=81E0;~_% zcuzWb_w!?vUIl)6b}bs~fs7!BFw7|-3)FlE?=MO1OM?n8|0udFpLyIu!9qlR`_ue308C?#t_*<+a=$ z+x}ua)&^P&*Fi~=5OxqYze9BKnoPu~J})l{rk%$SC^}Y{v{n|KgR~-&lqhACT4{gU zgdQn64oO8Ok*pvK+Og`Gkx_na$x4dK&zTFNz0@axtyd(wZ-&p?*QZ;aG&0KnC|=jr zU2~*)sgbzXv9;thfE8H;8!C~+@=}rU7n^6K)1%MVNt2~RWnV#w5@I6FXPog3`rGk9 zT(+#T0St&M}W}hwJ25cU;qB=bp zZt!*Qnb6vbcHjy)6{p`NTbEtqK@)nYVi_zg4#!H0B2jA<)bBT;N4n2JJqU19cL1-q z>K<=fv)%|vUfg3f49TvPiV?-rY30*+D{DSKmz#PKVE(enqklX4SCOkm-}RG6e({DY zTI9OX6YiSy-}|9qGOK%8vBvn+dnS*I+%VzpDWkD4a`dl9|9*7ZmrcHA!q{JoGqkF~ zlkT~D9Jc>P|NZVscTAZydCH`TqYKAOx^wDAdF18=Z|SO40Lx`(MWEOL6>=lGpwRTF zHqZKql!TK}Pf%b9o0M9aHyj5@soWm_<#z|~^!GPVeTVS0wnsKR=;!r$4uWO~WCr|0{XAUi)d+|8qiuX|VPN2QiF#1wfgZ}i55LS2l%jN&YZ!Zl$-~j6 z7byLNIL0)I30vycELo0GfV0u0Jz>Q|@7kTg09=T+r+ugOmx#IVy+lgV#0zmv_l;&K zCaoIOhUq4JNuax#9Ix7Mwm5)yijo)#$dcc06qq$yytUip^c+4fdYt{MR9jJrCbXr) zc=fCMnY|juqX16>Thw*7YwdqTKkxa65>3GruW=uTB~yaqa|?sN{OvUZ68@VDST|+Q zaz?2z{6p$~P<0{}JfAoonW*?zU!$lE*-FE7giqEx~1TVC~r+5UZXHt%qS{B~zBV7;2W^|=XcwjC4m z;;$-4E9jNH8+Xi!amK4;&@2l8&|=g;|hUsL=L2yJ&FZFio0^D|w1B^NmM@aCS? ze?9c|x|911DQ=l#pWukyR&I~pT48Aw-ybr&t@pHuY~TtP;~(s_Qk*PZ{+S_W?)5Gg z3t1-Fov~$vg)V){gl_fi6^WrP0*-LgmawvGg$BI`kL^hA@Qk?gG4L1A>-T*g0@)Mf zE2(DzycYSrHng=|^+r<$%4}dEt42XuyduCtuHh36y&GPCUfBDO5Q2o3AZ@M-0->{~9kfRnZ zfAT`J?q(yj#y5$PfZG=idfe7~UhCWA^&@v*e2(BD2&w|2;ww?wc|y|1Yulb!bvX{r z%-$f z`0Qm9@0dL9?lF_Fbn^s_OqXvQ_E~=q8#iVAq_NsP9~m(Ip2=gz>sbTl6f; z`NR@7(9ai)*^^uY5LN;yKzU@F9eZtafiliD?B++IZ5S~I=SD93LE@9%|Es255g6aR zFr)dfksN(Fnn8Me9;e&ODHO$+r-YGr^4xnbJY}S}J%nmWm)mXE&OM655ubJIcN|Wm z>_xj#$mQ_cHRXk4c$;PCZvP;Saty82P+VcV%xQE)n@f2gDADKhCAvb4zIDk^l^t+)QVr8>AA$M-OskYGckI-8Pr-$Y=-iF*t zD5WXjxt4_8dNK`e$7f;0o*W#uyL)irE9zt{jb^J|ekG%)1|56HD<@7%|F>mnRF z#?MDRDq`UfNqRX1?NJ0AUcf`AT_u6XkQEr+k@(c{ba!>aUPPA;rl@XLuvT}?i#C|x z_k|rOo+`}B$}fmpSJ$b7EcB&}WKRHRn2~ajR<@X)C-cs1{rq zvOc}>HNCk8Ug7RQQb1vNe`emfZM)LoR^M9WA6_W=hUJS^q|&xGbg&b%^FmvY$0j(^ zd8Xb^x0(~KL%u}B?ac~jJbs*eI}L6Ow<6_+BqLv&LtFc@rPTy0Cn9^18WWRlHiz>U zxQk5UbqCX}PlwkbPen|2mq!)L($~5_4L%mRfSAH6%obe6Su3ICT^+2c+xw%-QJkbw z96^wp=uJ^X+5y&hHEcZn&>G`x_$qo1Rj^djiwMe#NK>Gd^jU2?^3ED_Xkt5%KtO^2 zL0+rI_jPbC_MDAvK|Y$vlOUup1T;+`S9f0MW2Uw-WKvoeKZ6S0wpf8jjatU6 zQ%5wgULfn=D$~f+=Y)~ZpWOF_sR0u8P?1>{bBf~ix!sl!L{xh*A6o)?j0-81 z1J@DqDu|&-(P^#x8oMrr9HZ($asR}ivO(7*uOerHjE;|fbb7uKV)yq*o$myT=e_W$ z9uMQg!XkPrh^UEyVO#b9YX_WC^vZ)r=xahgnhJQ_fy?_zvLKM=4dl@y{aOXR`40Ad zFciSvLppO!8#`n@uFk>U{oE-q*l;8x_#_};0+55B1{j!OO);Zdmrb9*z5G7lJ*j>Ye9t5^+m*pBqd7};w;bl zr6HZdMd1Ko<5?`1m0+x#s5Otz;*Dqrp%HN2Vio&}Y}N~I%ZcNn4xKMv1hg;0Q0{O> z%x&YNX4@ul3rO;8BwOIZ8L9j}GTUAfj{qW~4M4av=GhPn7Mg9BNh?7J5OF^Nq87CE zQ>|?__MVZ5>R%$82(JK)L<@O6V!d6rX>tlMr@C=Nqh#2xlubbB?jpG!Ze%gvc1|M_ z!TbT`Hnt)`G3D8GrdP<~l^d7n+FbB&Fgm@?=N?|Nd5@u+oYTl_^0v?Y18edct4Rnx@caT6(NGjBwPba@L@{}%nTEo(m(j~42kR*&!3$cC>^t6()oNF_C zS?*a3QkW~w=Wvm=mpY!;+Fyo?kA+U7KL&?&yCP>;x1T=>2K1R!5LVrg6G%sVU~&N< zQ;Z}+8M%X+l;j;Ica7qOrB9x_0RB%%WV|jn&pK?3(`j!F2<7xG4CeJIvaay9Msp;Z zqFVt--9i#MS%46OfDqCJR0;h%JEkv@e){*Vhm?^U7tP;)P4yl4XG9Iy4yLRJxAm|| zNK-Mz3A2Fr3PPl1L3Duipm?ZnU~)M)4t`S$2BzXftWVYBp!ctcFcaqel$%zuC~+~S zKfHk&%#C%APKb@02|HSbRYa0!}guT>vDALy{g!{Nm8I8~- znvVVNysquWLL6wM=RpclEXUE>KRtTdY`KLtn(=suMWQq5nUOK#pg~i^X{BdSN-QXGPKBZP^aF(DQ0QA$)Bsf?53jZXLm4K5G_%Xel5HszjO zFQof?pV@#MSg*tl^sJH&3Q#!5PV)?)d6pF18OHk8jqlZctC?+3R#}E&l2Mz(X`^Yc znW+-!9Hwd2K_R=x zsTOy)UddZNc_%$SXSq$ZHr|TdSyR^-pE{FH1lzXb?PR=!mZ1z(O-n@n^b>FM-p-zu z@cUp)8zK(`E^U{QyVi_ic+K)}BRvYPJ~re|)Ea6vm$0gWL61V}&+O}Rt_q$s23_)B}T z8fsqM=bbC;lyDp*HC`Q%;I1Q4;gy=UrmZ+88xV93faZvo>TQ;NXSC^yQ>Vl|GzM7H z`A8NB6sv6lf}1Hjr5 z|gfFlz^~E$wlE{zTA!KC-=-Q7}2NK~>^lITv|DVm62k zj13x?x~i}i2(-XB?gPw~T+z>80wwoQ`EMj$Q4x7D|bDJQ1Zz+kqZV5wS|9AEM8F ze?Xu12$q`cv#CK5N|QX~5+x(iNBgSIes;LNgFVaLzTRc7jDDIg8vST$$kxmD0peOm zc>oD9x_9xw&`_m6C{>apD}L8Ez2-N*v2qSsox-7}fm=yOk}0Hn5I#yMN~lRTdCN5+ zvaBeQlSn7{uDS3RZ8iTJ_`BFg?s|0f625u|z)gT4sx?*4)rx*S8x%K#n{IYB0bix7 zEYbg_72thXwGO!M8n~MD{U$UtHFP^@2a)2+;d{Vyu(0x%w>5%M^Whxr8lMU7su=9) zP3{A^9Y9yX z|N0r7*1-!KH?%e1Z$yD^$Bm+m;q8N>yz|DSCshf?RzbI!Dy;d<<(0L^M{rdFt_nsCquZNbFa3h74%vilc&|`tCxxC4#2awKEVk_p6OM(o{8`>5 zDgn13X6Ps_9~*sWQqxv`v4B0CVDt2LBGJZU-Ybim4CN>F9MMT_*BhCr4jA}@aM^lI zBV<^X6(x)no@O;6M7u!*mPUe2phVT9GMr1b+wC@<;{}G34W&$@V>41>95(1&gZpn0 z_evf+&nrBqDW(jg>HZumI=wv2Ygdz=NJr$ed_WNdO&CCez#>6HB#8m51ZYCS22EBE zUs$%opsC$Rv&A_g%Tlali-kF!VR_CjWTY3ad(s$JtTc)%1Ui`{fs+S}Gwm7$^i!kp zp(oSh(kQKvC4T&WsuC}&k~b`IqAFs4mQA#qZTUwX33=7A2IY1U#;cp!b%V zz4yNctMC7b80p$CuYWb`&;g_P=VHf9+2fPMAyN=Q`nyuGLZ`7K?_%(THXK?s#!~`n%S9>qL)> z01}HxMTv%TavgTWu<5!Y`pw($l7XwO?FQdINl{qF=?=}|m#m#BXH~CKp zT4$QnNoUkaY`D}3Uy|4tgt~#vy z2y*o~3zXU5=IhvujIC{lj_lr}yB@OVk{ycO@$=%Yn3KB0251QGp@S4TG(gA#*>}!` zq=*>_3@*GOIWXC~;;PBDU=gV5FF{Rs7V{rQ<(b_2WTR(poR+r&ebM9Un zOlX=Pj}Z>^wG*<(D`~ok1j+1v43!*X&Y36~LBIy*+Ih7oZc_|3}70!2$UOeva1#7ZpV3Q?q> zWCyOj(^Mh!+%K(f7;UtPJ701B9hiRt%_PrjdwRHb9FkSksMcl2H*5w|>)<~qH}_M& z{*og{Tyq^Je?4jP6x{3jyCzK0F!aEead+#8m)$vT@`N#?Bgp}yCr_SGJ#O?}dj7J= zlyTZ$QzlKGFnVI-w;Jx`yK`~Y4;v3RVrMk?$kCI3r8S!Tn+apaO}$?lx$)Wdw7(az zj`DI_Oc|qTx6W&QN)g?9$vY%K^fd1&Orr+Q`zmOOF;8PJ=Cs$1d624pFtV z`Ev^f=`RL#@B*Fik|YUizMPOdY$>bvIkv24xYv&@WkCxu)y-0Y-kMX zI>Rw^mX^Gjc4drDb1%sn>G)%jp9#J(_y~c@~kZHe7*%0H@k`iZLGD zOiV8`qb2t^I6ib9gmbgc7On`P9vicVjxs!VaFzN2?bLOgrOh=<(m5K^Z+Z? z?o`7deMt9^TSx(r5>KKG>qz^GV08sfuAtV_2}T=bKnEy-_Q@n9WfC9}B0CKTir4qO5{o0z~2e(b+Kz*%bkwwHsNUgY0O&t|>9upb0uKjMC1pAJB-)J+OY zve1?8eEzuu&**-(1^*B`qn>x|mbLGp>Jl7oqR#?N47|!$RovG%GPVzdhA#oNuwtrh zFs}06WHtHz;RSow>w!`KQVpX#c7~o$kx4&9 zIRRk3kZjDaz8(+Q!7bo#xi;=hav?tAPnA>z2YJg1Twx&>WrYVk4L$~A{#ZVy=dHgV z_aS%?AfDuD)CjT*-84^#4A(~<$7d|w|Jtm7^L76cvRxm!`;am4+6p_uw3B%R5uyl! zr6Cc^B?vQzI;GcVKAEeZ^v&!Jnsgv-OOu3DoZ=}bA`nLdF55{HRHqY`;Z=6R81C|a zrVV4XG1yu0ospqGf|V1(F*3KCDq+Fvh$PeLD-G@a;9sAhb-Vi>aRXIQ77b!v7F}+d zRn)wMbx1t(nTBOVtu)cY^W3Rnxt@GWMtgbY5?VX3)Rp2ic5-xRmgGgUEWZMVrPI0{ z-MYYQyyA$bX?t>b(vdSP$8wW6`IjXI?G5q{iYx9f2}PHQ*19;lRD`$m^x9b5ag&;ro38Ho~PlA{pM%9)rQy9`WCJG|7d zjTR7Qfxy!o1I0|NhSxf=HuOJ6YuXpq1#XHXnKYJZN#1Q>c`$jP|0SjrKBVb5eT>ll z=f2%?ex5k>;h#LdR2exkGIG+GU;TE{q_IXu(5WwrBWJxnGaXW@ETaRG9P;x@*m652 zw8L30Jpo{r0tqn!L2(hV0b#&@?{gc51j!00TJle`R-@D$2IR-qtCNv zFI@v|05B0s81B`CWIsuTX~38(Q_yeO#(A$B>%Wa|B1^qA*7RFX_fXm|fzvTs9(-NT zJK|ZywUar$-BtD)z`Io21K^shxSZrmGo0%lUVcjYN2s00z?tuM&(@#IwDYW;Zl!v- zg-E$a3|ss!&C>_(G&2+Rd<1y?JlQ2OA3eS4@e2KQeHl|rMzZp*w-up+=m$U@mhrmY zSii8ZmL$4d_=L9z&VF=X#jTAk(TRF#?&Q(CC(KhFG-L@)i!TV^w{~$#w z>K>NUiNFLS4a{MqkNJEZi2@;-_J=8JeeK$Po-_h<_|wSe_q*LbpU+CBdUX4F-3A#r z&7Y+ar)Myf5Uns!2!sVrn=Zz#WVjr^{H@tjo$wqi^9Q?k3xs-DHANP_q|wU8u0`TL zG7BLO1E>TW69~xqAU(zs>DHfh>bZ_LiC<~@t;>!viQ;jjY2S7SLx}{(K@MpW1H+|r z>qthp~u7GHa&xRD>2vjltu;~PPbhk>mh>gVp&^Jj!zk{zH0#I}Ko>y#-d#0Ts) zf9ahPz}RzBs;n|T4J4=Fy&!cScUJKU6>7KLg8mB+K$$geEa@My`oqZKndu+UL0`e1M zP#70w48yFk@yw(MXJMRVdPga`XNF7r*$rnN1=Ti8ULx0PgHfpc_FDacb@NTL7IhXl z2pDn_M9>oHzn{BNZ=)T$O;iV}fCE9?9l6pRu4ndr_JElN={!{n<203*O{I@2^MH8J zXsc(WqUWK?kh`#F&{I$eN1GCmZgbyN^ZCYE#yfZ&y&c2>S?Y!;$iZ|4No+*4)Ei`+ zn4Cv9qDr_E7-Ghuw;FeR=FyY=Z=#zu1+$l7+CKKS@vENUo!$Wk@@&Nbfyr=Mnfru6 zOzUtO(*j*A5*PqT5z(q;>N~i=z|m;bGH3K~YFCtJoz@|`YJMk;Wz061P{epxWbF({ z7mhIepf@&j(r9Mpz&K{|vU!|i`P09(Xk&UVwlO;Q`dmCT+n9@lrl+xoV4;UqRZZxU zImGI!pOu++_pmlfU=5El`Z7Y?KfaY(-a^I36A6 zgr)7B@D{Ow^zcH!jrolChi5)8-~o*1NhiS2R9WxjRn|^_Yvo%{e@^P}!4|aZ+rDa< zcK>|_=@n8f8IYA&Sm85V#J+DaNV_rDEH6UyK(L3mGh@dW=?$?>K875!C+3u#8GdQc zEPgl5bGzJ(BEfhf8j0p)q~<%+`ArQ<9T`jJ$HF;zQ7Z)J=#xhKJnWgNu0+~G10=?P zc8~WOPN=ss5{zz|Ez(l+lJLmusA9>Wb8|XUD>8Y#OeK=e5n)XfI0`IRNBS@ z>?v`mxt0!ku-U*V!&&Q7dw}R4rVimm$kRMaNkD>9#dUX7-!&z5^L1xHXEp?F2xqLm zFzY^Dar0tx4VZ{_*qX0M(^hkicO<#7u_C_v9G^ zu77muEDEWP5Q41WRs6Y@8_ENp7&t*JEJ~dLBuUW}NE@+@pvAh5B}@K8&!TLvn(&KA z)wsKI?v7l0&#%W#9yevmI80vln+bPgMnAL1jGOpV-v;N!k>4-=i=I2diG_QK5qIT} zat$p@B~zUaQ~}KY=XO}C3ZW7kAGB6l+dN%h)jjUPR?s6D>)kUF?qfwxG|bV#KCGNU zyTRqjZjP{XSicd!68og5$z`~tgY|HvUx-{CNc&zI{%jo!(vo}|XdtV-NiawX0fnjq z8E%KG9$qx#NyAU}?~pn#+}gv>d~h?J&JHrUQm!T%2~8dPk+HQcoEtVsi;3N zMQxka1zv_UDb^*DRED(E_J9s9#-VMn8E~vGByl#E&nc=5LX51Jq88l_RvIq+#p;?oa%%bPAEyzpi+Ggg)NW$f+?-NQJSO$?dyG9@7;B`v&r^ zl!)UL#EE=~&t*Y+?2Px5jsrSYE_Uo8pM$ny7C9>NWM@x~l=E}U1U-t)9Gz8fKJl4R z(eOu6yTYt=bnUAAdeOtrPOW|d;F;hExm7!{hV*q;QC0Zf#9&*5tOfW6@-AWtuuV*j zwUzqjgE9pPBB9>?EP!?_N|Z#O0y9BgER+&_bN~dH0F5P5La}gF)~M|5prA(-6IfGx zkf8eVlY}JUsmcZbSE4?RC|HZA?SLKY>5HqK<1b74w}4ykD7Y=lTn@Tqdh#1%IV}G7 z;;(BZ&U(~XiMkw1&Hw=lN)#j&JDpCjYZP}s_25x$=CZM}f;tWgf1QwXZg*o!7EQa9 zBW6r@qjeYpb-5`6ZULZ;)-s5-b}3ONZ)l6Ld3h`7k3W zJ~f)36|mI0y7OrQrS~Gnc!I; z19413Y$O|VVeMP91jINkZJ=SnVq-^nR^UBQ4^==OOaMn2OXqWdR14D1?t)QB`-sWh z7Q7y+0C)yr(#;U0y@&xBxjmPClK#Z?LJKNonZ6|q+s88MwbmRp!7CESLCS7R<~!7k z8-CkcvmZ6UvvV#$2PgULg6OyIxAxs>@ciU#BvDFSq~(nI0?nW5V14qF3p9j8Wg*)`f5mOw-O) z;K?D<3W`Bt^ZpEk-O$BLK4+INj85T^##5aLi{J`qqi{r}xs0-xkF4%O&@LntV%S8G zW->O`BOlNB@Xyms(Go6#aZ2c&&2oLLt@Y_!7oYp&PulXe9e~f#NlqwMu^!SSGL+v6 zjC#JKB~6B3j+&?@AP*X;5Z1-~_>%8y^uhA{0N#~{f6vc#4)>r7R53?~iZB(l2H~5v z<|pJ}$2_u@_8|fb6d^I1Z0aX~*K%n6=wp)yP4(GCUIM1-^T`|cA9``TQGAu$OKW;y zVHQLM8A%I|nvG&uK1DC0^2Py~W1a%cFw&CgAKz#)ANV^Qs~+z4`t908)uR~W8X0C8 zKLZ&j3z%Rf>gX~gZhma#>V-zqe_<1Sg0ja_9$Qwf)8gilPfcz#gciDmO1b1vu2TwT zAbepW6yVTab`GF#MiDhqGLZ3sP}yuirn1%oEGWcnz0yUHk8ImjXVU9nx6=ws2{K1> z*1`PbBk%5CRAb~Wt>@;@jKWi#gC!AL>hY9#MZ~Jb<(9)rlD@GgqHeOv{(kv#7o{0^KPZd%i}SrK4+*S|Y&zYo zqCbR8Z!!^+*jp=|0ZM>PQ4U#%lDT=0L&pd)Na(>kMkdnZU7xxbpGIJKihx(<1Iz1u zdfSXnrjFq)pi<&{^x~xqE5@w1W^^)j9xouh4nY~%U6kz#k9bT<){30cPEJ`u}?PUU1WS(05|&wn3%j9MIWh&D)oZ z-H`W>n{;iBQ|ruPx!vmNLQzN-2z<76ZB2h-?nnO?=C9+@$XzSm|Lb^70EnLTFMc1M zhYyE$T=wCO&G2338Tsg-4&j~nr{rPJ#-D#f=^i1bW2X<}rk^#OqfhpH@(a}Y^U=p= zwmhxpj4WtMw$MSvPC9|g^vZIBeCz~vW)`?HOU?#C(vDO{lo^@lWhR_nKXq^Jd}=e) z!-_A(cf#2)C6Af~^Of6;G4tu$uzt@M&rH%3p}#|53Fpdoi;z z`w+SS5*EFs+YEZ1E>Ksaw_i6J731*kg3~-XK<2y&y+7axTd~fCeElbvcRht@_#;>7_Fb z(!sw)={!jqwtr#pUU(u^Lpv2ec9&*5{DEw&x@alFJ8UkR4EpTaMI~zDvReTT5`{zg zM*MtkvA)#aHF(pj$fkB`mu>|?$emSS4ViVn0nfvpX$5DwK+vXeSQ6|Go?}?OsvZDV z=wjoVjt&hs9|t#;E@qwtrNK~C$zh$P>TrK?R$i`ah;3Nt)>PV*-umj78nO=ydka?b z$-+>nlIKdKcgVrR)0P=bohWFBFqT3fnxB!cu>KW;DJN!X3s>OlHl-cHmc4H@y9Hml zp>Tm9P!f^Hx!i*D=3m5vz57raFNJ#GLbgYmlJT9(KcbL^e* zJAa*jwApC6wz!EEM4KW?a%N5CJ)M-d7jI$&8Dn1J7^})o+v}b1J;mD@LBzDEFd6W3 zySg|lKEn8d0``XZbhS%;r`GIv^RMRDEh^d1V1XBCQdVR!U4M;7Z$8Y#He1uv7O8xiF0Gr@Wum@}bziH1X3$Y5=9tQt9!vC_3JhqDbfc{M1 zBj3IM$ZMz8!)mv7K9RG9COuzCI$iv`uRiwZQ0>s`1X#Dw^K~7M*S8u+{rlv1TyJOL zy}euoe=u$Xj7>r77^llwKLmHW>Akb>;aw-+)Z63l$U5%2BVf?(jQ7dSb4>ESOmG)l z3t!XO(rC}2ck)U~VdPwy&ZwZ!@^Odx^6hM(*9#+ioj|XH*&urX%)M8x1HihF!KimW z?^yZFn|eO$AII&I8n-W>Q74&&=FVcNxQ8s4l-n{YYQ1LmS%#x+crCvaFn)GI3Sn@I z-Q{F&WQN#XIVtzVd&^NrPLrhMr>1@k4yJ(xG0&Nr-WZB&AlO z`9`u1Y{(jqzi1NI^;C8rrUjW*ViHA(F;xzSO^1F#Hyk{^!{j}Voom^xLMU$?kk$j- zBP(>ZI!S#reO-O|^hv|NPZRR@;?yn@qyKMFx_EE(>vG~w_6)xr z+EDeYP^Cv#f>;%d2pZ35)H{1k3fgqc5q4tRcA!iH&jNg-G5}u9MVU&tK|lDWx0@Wh zF<#8A! zr`OJ>Z<`%z%l!!6hkFq8`0jujX9_=p+3g9+C?xj-aHlWutH-+NZs1Sx;KB5ue$#5w z)fzSm2Y9wn0#tsdlZ#;vdB;S^!Jg-Y3miET^(FfT2IGOK440*Rd2D6+(>`tMqSPd8 z5r{koLFA{aHX4-PIA9`Z@>`qGjPn@MlfzQ(N-!*4e2pCS#y9h}uQf*B)+p{2Xbz|{ z#gUYPC0qJZHHt_cHYsW9<{`C7Jc)AMYVM=yh`moYz4_>8CLd?Sl{gOx#rZ6kVH*9i z(OgHm6-wI4yYz>62r^2zefi?MU#Afc1!mwINK|+&f(6!#^WpnU3dJ~jJaGx%&W$4( zfyOPM_exMjYbWFtdG~|Te4OnHMoeA&)r%*L79}{eBC$Z=Fb^o6KyHc+DkKB~38@|m zp9phSN|#sb-}^Sr#etl){160lhSDHm1;4+s=b(--^(go^z61jU$NhTr!UBFBCpt(w)DaIPP~?9yo5I#^=a!QzlQEIPRW1 zr?v%+8kLGOVBX7 zPrsaDH}?B2bA9|xklQP3NJ+n*H+E(R4`F2uxQ3iYaSkF+2o**g0SU)J90z=aG7>O7{XE}Ggp}ucT1DAeC~6P; zDWjK>dN4+v?lkT>M{NKoz%B;y-a;w&9B}7R2_Z$5rB9}IhyH0hx%ZKjm*jCsLGB^l z(;f}FvEm%o;b*vZ61jK)T>+ZScc$~H7w@@hLf@IK{QAEAfNC3G>TurfZ znTt}&omTKt>+ALU>B628*CSkT-MB7)!>?OL=oIzeLw+0Mpi_x1*s5J4jNHRgE0ve< zy0WvM^d*A6Skg270d2!(DhF`lDlB1X;H`b9i2+ZuMT9tIDF2a#G#kLckW4^((tJ zP!h@s_!W|7-6M%YM^`Pq**h;hvs+t(*Z->sTSXCGe#!WlEy`|4-%yCC>kCNhon!6} zeUPLB$`(XQ5-D(=(PVko5H8$iG+nQrqH=pi+3B>L*DQ{Yo|QkvSPQdTShIIlgCErA>B2uJ=7TbcD3By zFH59>G;(N#D@k|taPZ?1dd2FU&KAUCLK0b#>_-kE26($LTHe)p2x0pwR|*CoY+5a+C#@sM7fI_6w9v#wN&_LzfopYn= z&W-j=r?9Ts@%ozchEjYH){=zBM*y!oL(Zw$zebOw(BMtzJMC`w6Oa!ORyl-iZyWF; z>|4*yCd>O1KFlJUBKW*6n=i~UzHrZU*<-UD<>JGp=$8D)4S>-=o1nB1vE4#=3dwt^JL9wuQgN=}N`)#Iw)un{K-PaPtsIdLWtO&A0}Zy=;7d zCgQep%Ybqbj98o5LH&wtU%jF4%nWcB?YEy^_;HPyQ9>Y`Gr@@2@Mk-q^(^*4jlo^; zhw!fEZ*1#itwDH>yhdSCSIg;igl4+ThShJb*Tt;JGN}o%S%Rnl7DgfwMPdli>Gh7m z3`>Mufk@Ye=y>$WXI|H>wODVWP&U$~WCWkC&)2`i0(G(S;u>RCw5#nasSU+?d!=Yk zpPUgum(V5MAHo;|W;FkLL0bKkTIF_<589nvkoJ1q83Wnq*Nxsk1b216ah1_tH~q+G zVWKSN&F&WUS?>sS9~^$uScS?F`4IBP1s2iCKq$9cmLEvcYyjqV0pYfLbQ7tTW({u-wD=P5Nnhmjr2hFQ-I;SJc zWOh(D$c}ng?%2xGSIq118GzTftlSiDInR0>Z_m;>?Nkk~q^h^Z;fL&3agAU#X|*=9 zl2mH%x}AqN%ZZpC*stI=KuJzh1cBQIIv%2UDrp10TP@=mS!$1C8Q!H+Z1lZy?}co5 zukQ%q(h+n($6E-5aGn8zA}F<$BRM?_1kb4S8k&qorBIS1clL+(VHv5h3{lMaRyrg+wi8Tc3+b;OSEhoE+0C6Bf~}6e&FAT=d>-$>E^6w zPt5_Dz+~2XA$SSTCh&k=F2V;EC!nAOA*WIgXvSAkNB_KLKh2fz+r3sgNb`%DeKq{A znw^$4d-PN+ll51klF`@`RJne1uv@TOiM1`*HQKolQM0sk$fafTVuuRze~&x1mx%}B zR|soJO-QSlzRN$q9Y>f$?nj)R$JLHlpphI3^yVK?ghbY~i{6d;xw)``qKuOui8Kk6 zbo)okmV)fXKae#2{~cc3qImO@YI$9HSdlXaT1JzP!$wIj z_it*B^@k+KX{pt2p^_k$g0_=V7<2aOOLfa-$`xpRt1GkW z{>~CtG*u@oLdl92pS&*GD8OoO3pvUO zE`Q4nqQRYoBX2sIO$~IziI$-1M%ZOtS4ca?k>24E~_iSZIXM$qT9>EFKIah=HI~a z*yhQ8tFj zpB{*xvRu~B6J6+zPEELzOL;@~+mU*NHRf%I@s;XnZ!>z(2pSY~ssL?mK^k ztEdHbC0rGD@w0(^UUdeF$K>Y*XaVUs%?4ff ztvsDHJu|if@~Aupo6Ycuqu7z_8P?O{qf`vEwujjW_7kKqG@&NdUqicw89g`upHFUF zVlI4lWAU76(sribNFGylG_?=a!cxd-9!^PgMdvePR`r)>amkjuM%|^hLfd*lshcZ9 zL}O(gbyHhuNyZf|s7cf$m5#whOoCNjFI@W~4xdNeV+6I`#d8+767zNKTpa!@wMCU=*I1G* zyjh8JuiGQTMN4iqU8PEOk{Yc_ri9Ycv3PiSogO+MD1W7wX6yo^nNAY zbnp8zP8#bxNS|dxW{Oo)DxLVh;MP$LM*?Y7anZ4j(m}`0*WQHVO2ur5p<~X(6nRTp* zr&y2K6vzu`qrQnChfY_^IHF=-&7NX4DAi0*HcstGvk;6`#fzq<9btMy)a6W-l5gC- z^-gSl3)v;Cfudbz9I;LsXfsJU4Fra}C@gAmnI!wY>USAml&8D=X{J%zc1}Kw!DxCmR29C^1s==CHYh#={&RtNM zFt8Ybuq#&6=9@BH+&UL%R?~rSb~2{7>+6N}+QU_`?jLZ+SQ|x}oFviUl%(prc=yLN z+g15IX(Bht{)q|JzKB+>`2`MNgx8Fcrww^W!_ zZA{PTo;B3E72L{E(4R6bB2#zs_f-Og(`t%fObn?rFto0lkI@Sh6FvPAWT)rLIBl!> zCE|h*e0o~zS7@vJM23ql#eQL>szq7I*`k4)eeu01x1)UJe_}NRuHkTsSNK-Fw>Gvi zmkFm?9RswFLxh?FQhE&C-oZv)4!dN>Z9XI8+F0s1zlR;*Xs|Ecy(AA~iG%7j%;Ys| z=T4Rn9u^2E7(pw9lq9KJ|+*B!Yt zkyp!b(F;i_a+L_BSP8G#Z`bO1wGH2l)CQ-(8e>`Xb zBx(BXLOm;15G#-+)H1~$w(+FOW29J3bR*O|Bw{{`BHCE`G_jB@UJ3P7e0jB=ie=;j zBHL)n&NCVF6m@#^k9sPu5a&U#8P!^QEYYJ(=8Z3uPfE@~#X8E=L{G-HQE9PE{vnDW z#p9Fr2m_@F8Obg*GPe_5XBo{Vd$WH<(d;ZUi=KyP>xU~>72keSPvvQ98~6az1rg{K z<@D{PyKy3JQKyLjYv~@Ot}jtl^LfBNA2iTz^WA#~ZNr%PMv%3*>`?(T)QDDPFycvHi$fyG_z)SLp*p zJ1rgPD8x#v)6!ht-cmo8i}WnK8Bd4G)KsGKN#6Xh9^p2<4LWhSuUt*|l^&KKk0OX( z_zLD8^ivpl<3jyZ7cjNRgD{I1!y0UFZ||$`dl9n{90*KKh;6Sjr~f)xk8qH=1OICe zTR*Mm^lsGwJi*;uu>?;Zhz{>&)rV9Q1PWAI95D?>U;1af^JVOIyp>y*+R|lAi_T2$ zd~LLI>Aksn63!!*K|Ibi>(aSY5$Oj%fBx%b>A`{h5W4|4aJ1T}R{Qb{l-5d9Mhipn z*;?h6{?(fL3014tk*3rfi#aXZswnNFuh%0~a#Ki0N`}XomhM)<1K)f@M)>E|`f6SI ztM4vcH4m2pXpf-1j*OtTt*{b4M61chJMkH&DPO=sw2+=bETb+^52(F#HMx_#0vnB@ z=h(V=b|ECj>VskxP5B({!cl0N&J`T zXd(y9e@$-WmI{1NqKRN3Ne1#MCHnL0^1S<|wxWo>z)}{nCkf9KI|fos z{f+{xix1^$a`m|dY++9Oh_hp$ELCVMrQz0>qTcPKE1^$*`9U0_1Kaqb<1#^aXgn2x zj?ghWUOl4G0eG6w(CX&o4q%?Qc1>)PHyKVrhp{+^c!FbCj?#mkO!hU%I=)cmWBdP6 zclFFYeO+d*l%w2Qg(rsG_Jm}YLvh1)Y?9}1XSt2Gg;Y}&t~Lh>8%5XR^tWV~WK`O& z67D3Y(Ut5lC~d!fI}YDz-$U4oy}YG~FIG4im#f>#@cwMe&B3cTAid`+Xemm4vf0bc zeJ`sA^ZAkd@tG@t9__5i=$~gV!3)fZVQX?l;rM5pJli@_>aeGj;#su1d$14P*qDNM zF9cU9u@!y*sf@UZ9`NZr`P=sS-`BrB*1u@cF06fh$10E(!V=GYJV%>`^fuK?20vxi z5_GagpQ$684)^g1S^?L1HO7z}NJ2>V^ZHftw7q)1*0YZGJWdn1+TBk|!P~YJsUX;G@dQ zMb(nCqP^*TfD8-Z7}(9T;a}h>#COW(gY;-xHQ>|NWqJa7-Cf^)73O=H(J+{nXDWe| zNh*}S)%v&P0YwArmiN{=R0wvlEjwV@PrLSAR?CSM{PzIA24GH|1(_prH)%)tGD#Kg=zgMn4Wl34Ik4C1D5?wpK@%8cM?+-gZHa2S)amHV{MzLw#l z<8?8(1?jVSg7p+=g)}3j3HNj;hpQi*lJTT#!GuLb(|JIavxj2Ac4t=0Q;^c-CoICX zP8}<_^t2oRCwuzyzdX9MTFTIBKa#M4?1o__dMURbhJ||)HZ`u}RG`%LBn5H)>H#|@ z$vl=k`GiYIn-tLs$ti*oqP^o}d|oFKHd6ygRPrbR#mXJv&+FneolUqS!m08{8M1TK zY?bG;CjOmwC+Xb%l_IUNSH^M}`Hssn z4I=-KB-T=#odV8jRXK8Fr!APo|LH5@bR0|k71wqxi?7|TKj5ucu=)ud%=l!qrD$zx2| zg|k_$2aX&$@NsYHz~>^~Zqahy-c)b-u+egedg-vCkB^ObJBqvHz>(fIV@3=dIf%9X z8`Rrn@R+d!$BiC1ax5F^IBKkSj8sQ_V8y6$W92<{@UsKOEqRa}9VbCXjCxGYC!6+< zmq+g={=Ln}LBj@)9K-7CmPk?Rbvr*_Qn$J8!_TMH?PU4#!6Sw}rp(({x2o>Fx)17h z*6osUCW?RV^wzEXeB$SmKCi6XQ@4e6lnxs`=$V0IAA4M6=Ez}>g+wL|9PMp2df12& ztR>oyw?U*}*Ri8U4`wyxqlb+bIXZZ>^c`4B$HC8d+YcKuSp3&hW0gX!thz^9o3v9o4Q@-=B9sLSA%qVZxwgbBg z4o-sVC)^#1Jon%|aJ~kW@Vcn4K1IYkkebc^0jYuhpMm*Pu(WAvRP}$<+Nt2>*HHqi z_GfKC!`i$F87VL1X0X#`k3*JH-VKy-bj*^i#o&O?_qSxVbScN_x_{v)N8J3H)S7i}vQQT}p zrTBoV8{f^mO^Obo>FjR&au)$ZPM)D~qn5)#9q`Ci)o5ukR&8H)^Dr)&w3_Sx!hh|I zc&&&aASF8M*8JVu4@<{W{}CZWMnLJrfD1q0nq74tD#o*qZk$g%=(-Zp$2$6}tHnOZ z@pi8xHOa0^&}1{VTq@zwc8wga^aPjQrVh-8C%1x-?ph0lmaxz7VO|U@2j6hKk3Gq2 zE2Kt;YoON)c_T9-E$tntUWUzRpv+qQRlG=?CTXGu)NEa{bYw* zi;mPHXuSZ+pDHVTB76iw<8=#A<5TEemT*<6%ha98PsQ>?SuJE8%+f zI~hrwUCkTBv~z&jjTq*LhoH-Ej(&|}RKH2gI}Mc8Op+#3gQs%0{#yD;6l2?)#DlY< zHKD~YlcqsH{Mp~$iT0u2wVpU|8ax@6!lbNB>j!97Y@0v(vy9N(|=9~q@_|>5D@yad4r4#bRGgx=cI^zBrp!kqzCNZK9o~8qwBS}HDG-+Mb zx#1+EZs%FKg_)(+tRuFa6d7ohEyDc^X5HB2lF|d7UPmlB1;Hm2Yi|DE(v%y3>Sy@b zTzQ5O)_z+2G-trZAVNbBJWUZChhwy#rX9-IdoRSt-m{)qDUCh23(8^#oLGHi%C8a0 zuD-sWm~;*(&cG5BPZGRzk3s;D2ynId7aWOyS5ZpH*P+kk9>tc`HN?C#Krnh*N(jqn z9a=V@a!y@$RK~Qj z?5P@J<7t3Gbuf0Ee?@{!_#OSv9@H7z4;wpn#9(owt{6CURD6@q=qZ{r-WDSVH8h7> ziPp(jZ|i}hMXP3X#M^e1h|)vsy6m~(gISxjUAGqdo*>#HEyaPJi|5E^A(>Tm6?=Wo z+g#k&g}OIH`$4ucymiY&14C6laKw|*`t1L(EoAEY1u_!n0pMaPvsC)P_vh^M!!Sy3EOWHXGV^n-PW}-+I=NQC7TU@K*)kFZ-Q7J)z=%dll z7K@s0gxhGf%HVORWi~mbFho$>gzC7^x3DtxX;jAXmF2Es;*ssPev!h zWO&qI)%n$4Dlgfp3bwPj=0l4nqtX+~T6Jk+HMM*n4A~1omzWw@4=E{_ni5&J2C}Y# zrWU0ffkCB(Y&E2?YBy%KIurHgODL5ISHkD$0*tPPj2xlRJKk&5T7u4qA;Me%brqgB z2_AX2@j?jg1kWV&8uZX~WV?ljw2bi6z|@86Xl#;fEJ5qw5QL{e!WPt2-LpKU+*0lw znbw<~2J|WLQ~|yOlE=5MhF(>WGXvOpAnXFN#5rES445veilHyP2O(iC^cTuM2X{d5 zjyeEMSBmD~v!l#QpnMhKEe%2%}fFB>yX{2 zB)7A%S~4bmRf^K`CmCek@<4$|YmaGxDQixKghs(T5)0@9Dc@H~q%qY75T zC0L16UPqeV`YbntI7pTxRKnQaGoVxH3fKwrfH7N$zhN2}DuJ8@{0roVa2+vxVRCt% z&Up~8L}l}#?I&n8V2}6i{zU7$KpJzFLF933B4hWI=)?YG?h+I)LXjo#>}IgmLU;x& zfRW+S5_?}$w|2d-olsFYXd!VGdb|z2y&K?rgm-Pi^6ibzFW?wH4-Mh9iMVzWB#&Hy z4nUV)8(|JU3#woVbXg|)Q@ha;xC^#waQ1LENp=Pc$5)E8x(+L#yw?Ex39xK~PV0#8 z-~yOxp=oI|E;Y}S`?R5R(oow6pqUEz7`}1eP0*#$=srW5w+^&4oPvY_;!L40(S)r* zU08#u>9xLQ(*(V32Q_@qz2SuUxV?k_C4Frg_hmFf=3g+g2(w<$S<1- zgIbMrJf*1xN6SprV&ZpESVggJG5AT#K>c@6G820Bn*ps}2$fo=iQlynMv7W!kh-tV zPMdY2=B7E|C>G1oS+lvO`iTH0n@_Zc)SSvmvnWx^fu1%BoIp4jjn&4dl(fK1mXOUr z>OiM=tboPPrKwgx2GZlp#b`?1t%YAO;~dSK_@BkjQu0lr)vs=>YvD_=2nH}|9f^T% zn*LM)ska0TT!3jf!K*1(Ct_B+-?&lS5>Jbwcpr%5&_(M$%{Rn*#hI*PllW~ zK>HQh9v52a&O!4pQBn2_i^1%_E@CGREojr8EU|iXn4J7cD1<@#2oiN?r1jW>a^@oX zjaUuez>p`OYLRCtG50mJeU5t6wgYmXq%!#yeIH};T>)34K96)Bl`vTUCitJ!Kb8VsB?k1Md*7F+mKz4XM{%ZeW4|_1cn$X#xx0)CxTY6=XzBo#5&0tw}YGUI=j5o z_NBxjIc<-M+Uo|Yf*r(J*a3$S+5QQ7Bbo_yXu7y&)zeVgO=2H$1m1%t%fb95v~Tw8 z4O9z%!{cAT;B&~9)H96Dg|hD;bJ$7IW1a}_fai16tOeZ_8{^9D^vGez?)1!CupYWT zow@@W9fsnbZ^3X+SCJP7;7w$m56pTnOoi;3qC8DRufy=+qw>dbovpb89$f;T;V^E@ zwOm{AT%(?`=HhQOuRrOu!ls?Tk-^?wNn1^iI7WDSb@aHDP#uEA;fhqo{kr z@WU|X7knLBj9&f&y5#r%0^!f)y^Ev2q3}C#%B}_A*bmcjQOR}r61wgq2Q^!PbnBpJ z^Tj~8D$;gArMPXks)Rq_7Q74H#_5}e9!u%m&GD3_622o=;D3>8@O|Vpv=xot0r+}I z{~m^YhW5c5=tCGjAD%mdME9fY5Pk#nDP5Mpd7SF+=`j(?pPvCqkE<6zWIyzoFjeH_ zm!cl+>OKShlfb^1z|VyaWA=%R92#KTbx!Kccg@J}H5o=fU-l)q4@2{h5wQa-%c1$d zL{@(Vn_wz@A&&SZ5>1(Q`8ObR6#3dvKZ@Vyee@2>n2ndc1Mc~d@eK7AG@S|kp6-+J z5ZbkxhM0A*RMfS`D%A6-$!LyfLB8;a_jA-#xr<|A7>%p}Z?E9eamtft2)UPAYRw$kc zEf!11DMR0YevQU3!;?n21pB~*cCCo+yPzA8qOlbcK1d0QL+f5c{4x@&Tdlh=V3hc|dM}h3x|8?jxENeN~-hfuabW@Q% z=ZVMkgIxnvkQ31cb4vK4j5;XTjb9Y^Wqt!-Spk0_O|Y|CJ}oDa;BcM_TMt0R==M+4 zLjPUx#6@sV689L#Styu-v`fVO!FL*-o`%1;3yr!2ofpEV&}%8Q*b2EPLBAe~o>7l! zd>GRE40Ei9kI+TGXZ2Qy0NeMlOJ~6<~Tc zw+4KBVN?y=fNi3ovs<)^j=)>!@lS~H*(*f-uo}JCtKh6?Dl8MFX(LLR0%?OLi>ev# zQgBK9V-cDMC!pIB7+nM2*4n(h@IiRO=fY1 zkJj<3z6Q4|P2;D$Fy4~EWZ_=j5VCDrlRRGQWXxJhAGAsrPfsjB_ML!L0Xqq|oxpSN zi8QRh--D|#Tcl_$O!%5yjef^>(f8sG_=Pz1OjHd=A@3L9Uq_a|z;zg0&*k+D z74z+?MJd=L!m4552^e<>bjOe=0v$(3M)y98vhsu%CbVw609L`c7pw4v(EfFJfEJ5f zNjd<;Mo3%@LjM-E(0v|^>h)Zc*CFGv;J6;0hcsFUEh^ENpJ3EN=+ypGc&XpmnXnf; zWAQ~Wd>UkLfP@T(*~I~aIZ30oFCwK0uZqQRata=Eu0@OO*F1GXF({ zzDKD`q0uUMY$m)Vvgv#1-g7!6eFNBBM7}2u^uG9Q-++72LDZ=00Op8XsDeTJAz3u? z)}hqBqStsDK7lQw5R@%O9X~{+9|E=(R4+QZ_gM-*!0<;~XcF|H5^SV@>NXv<-T~oN(6N>39Vl@Weo77a9K2nhcn$0Wi`cYhoq2*? z!v;41dk{2xLD!}6b_kTyS5e74r2h%ki1u~cdBk}*MoH;woRn!AXpz1^-x_5IxA5YF z=rOHm9CsE1JD~%gPz(Lq8|DCUAINDa>jI2rvS0#ZZ$hZUJ=HoM+k*7B!LMBnxqWRb zz~ZF!meFsc(l#Sg#L>@#dKa?Ifc&RA?SgSjAU|zv@8q$$<`l=13(>f=A$?OEt;&37 zkqGq_St~BUe$~6s-esBzHE8fI)bk)3R*}CFHQxxj8qhC+ygkrp2`U!7HLm|n$S_WX z(bPJ;!fq%1$ZpBf28(j^gxkW?R+Kl0DM~8L?i*>c2-%j7XD-{J{i`arEp%<@IQ$H(IaIAD$wjft2u_^JPwF{49vjJ-gCUF;nF=zl*k<2>o-GU3x|AHzZU6W$^ z0KJ0LHq4|atr#17*S&AkmCCJu;}x#}`_jUn;iuuof+mrt%0{%G1m(M-SGTmHyhxLv zJE$FGPIg+|Wy!5`5{trNbL+mn^ZJ%lLcx&U-3GBUKvW6-g}{s^TN($o&r0qeE-K6m zUj>DD5jE)RDZE)fs{B+BXe{&JleMTh@}wa;o&V&9=cdwhCXh1LDwG>H(wbEa!O%@i3OU-HAwayt?%QfyKrKZ)09=>GN(6Hk}CXp ztR7?DpK$jn%xuL(4+>N6%w`_1A7#&P6t`Wj-iMPrKfA6uctK9)AwJ#Q)s>ir^j10_ACo$ zOIJAb%9$vJIQQDW;L7uMli5i#TBD9nh+^T=_2v6lzKYA$?Z2V!1sf59#|&*8Stvgi z0`>Wkui|pN=srvupU0DSV>rniXwLeS*uTT4qN5eC2~`ha-V3>!rgT&M5hPFqGoh@c zwbjh9cqw6KwOYQAGUH1B@1CruVA|iXVyx4Z7IC;!8$7Ij|J(Yx?)n=RKIccLtLxN9>A1wMxE0svQuxdy6{*&4wcNY6N}ZqMhHpHHgWQ};pL=6^asb0c5A>Db#}Jzg;n*h+9$CDD&!&(NJU zjTtph@asx;0u~gM^$lJ8NU`W6T||-W2v5%n7~*@a=KALX9tf0%RzGSONQkDFRwytrY7wG741s*sqqjIMkp^#O&RqZO_nlDD?tjutU~*tn)uwV^Y=V-i$a=d*@#iXp=;L0;Z@qr9wD`(O`F!i zuEcp=d$XQ*x^;d-aadz+lEgRQ&B{1@kM5X9uz7X7-KAIVPcN;G!1ziOzmvi6P+m92wQ(Yt3io!nV1#{up)-n3B85)En75r{HSpt42pX$4l! zFd^f)SoIWBhK4n{c$L}R;F;L${o6%wfK@**>diW>(WDm)g?NXfNZ#!UTtpnO`MYm7 zye&tgFEd@V5cXse*BKCyv5*E_E`|EGJdTA`O|r~^rV-I*j#gthG(#T2$P!m<)7WUZ zBtGER9SgRcG)U8{vEMXf$vGGn%7zBHHs08`r8*WdJH@P3YpohiXK9f2cFURftK~4e z?T-6KyI_x`dkr3|C??Sq^>Pf!oAEyGIPMtC_Qn|oOJQ`&07yt*L&x$JV=nrM9*_BGmc&WoRKkOR@zLYF}#+^;k>-lJY*!RSAvoE{_w}o z>*c)J|3#B}3Eenz>A4HCgl=#iw5U=eDmIeBDX*_~R$Z4Qz`?T1TxZQ1qlRgtq))o` z!|d}P$oZWQIu{vv4MlKjt)9T`R$tKNAjIzzHKC+bYKPXv`EcI3$3SS!Bre3S@}=#p z=8nt=O52JXlOlZ(9pr5G2T`pq7?2hY}7~=m6fwX^MNA=i@%N@BsP|!2Mx^! zju;_l<1LeFoQxPD5KYL_XL z5=b>AG@X8_3gy_3ep5d;@s( z#svRRws~UHj7(C_zYs7+6Z6zgTE20TT=wn1)zT=p#0KnGdvo6rTrLa*l?WyI5yopV zq%k81w~6Wjot!BB^|jY|=@siD{1QSwapn4(ff6aZIS!sfZl^4su*2#P*%c*xYfTJ% zk(@>a(m6VqrjG6bYRUDjdrJa~G+ZI?ka~?Pgo~<4#SjEexWmywWGP)Qq4`+u0lAE- z*O7AdaTI03fg9_$e<|mwSV!$8ZApHUJ=te&Ku4|ALx9yw-?j=SL;KwRxzBcJ88B)T zNBrvtYc34?&yni0Els+4?9=n|K(*9$Ty4^;IJ1sbUa8$(6`SxidJUoj$tot86ieD8 zsg%3#NMI|=R5RD1!jPvtX`HcGf=E@9RBMoyWW5d+Q6@%{swQwvnkM#wO^yz)-1htT zQJ$-62}{Ura3=fo4d(i;1U9qOG`0$FK2UjhyYc-Wth{WWA~%1NGOt?l$feidtb6SM&^F?A(Tep z-c&N?mB<@R-NqQWj$4WIIAav3c(pir&=oUpNZ(w0iaQNfQQPncf(bZsDP>FU*2a3c z!d=JxM!^{{=pBlyUA-m-zQ`@ZwIsm_6yBh2;n~-u0YvbxqG+3GN^7D>jq<3!YPkgV zu>3sDN}K`8DEbrz29)r>C31UFb}wsA6IKHNueQ52EJ4_eHkVS%amlN(VHWY12pz9A z>IFfke9OI4W5Y<`tRkb3+ti>X2qh_C&AeFqh5RJaY}ac{4xLunhObSRz?5q|~JRd18d9veSDEtIii{4}wtaNW(dyCOP zX{gCa719M9uI2D_eoCYK<^yRRZeaSThS_FA>U41Br?%@k5nR69%;)<((>>LeY3MBY zGy$8>)pa(gZQ!6RIc;(>BMF6`LRW#VuVDeo%uqcQY8^E_d*K;I=&+V_cImN~~h zDA+fnTeu3i1z;{*0X2|T5Oywr#9q*vPA05e$2>h{L{F)MSZ{q81fdDI8G|Dw>vL?^1(Uzh0PRd4eu8iy-!Q) z8kmZgWVomhR!~3jQH8MUPVLT*^|Gf#ZP94$I!p1MBEzLatGtmS@nVD$4HeS8`9HPgF}E)aIyE=^BJv z@>#-e1Sa~tmXlJ&?K~EzauIz`8>RC4&GQF;kyFi8F&nwZ!W3^}IKNdzXB?%zm6#6EyTpEjIPkWkV{H zZf#epynVe}d+3i#sG|IT+-1Gk{&~K7!A04Ps#0IlA)Ot8KAt61PC)qC@3DzitFH=t zIwRUO$(*ibcI?3wE63xR+|`o{9r>eBHii!~5#>5KvEW%}2ld}q6c)V{!k8>KN^L2=__S*LN>Nvrz)?tD;lGcVP zj5u`R_n1W7uo)w zCnD0Sse1otjQ$0ItGq3viPxIixIv-Rnti)=Md1g6E3`(2wHRoXRdIu_ZHvQC1P|(* ziD@2JD8;WhqnF;7;o|&n2X6_bc0-n)qRp8G>86H{rU_-`%;r1d{ai@c$#Fp~sq*O> zJng97D#8DG`{P5d{Nw%a9+`$JbS$#~?u+*2i$pvveOtEJi51pD*%T-mnO0~wyE#8L z4Qz>;JXa*iozFFl+xayaILiSSYE7DvnK5hiz4MZT;UQ6xJoCr;wGQc}htxf0 zru71EV3Hct{W!x&#^=97<173A)ccc{Jd|>au;smrvYp<>ISx-D{=M|zlLh(p+4`>* z|4;?d%G7soBH4>W$k#A^`05#}r5YIAWw<~Psr@NDtskkpyqJILjT#wTg?5pu+yXV5 zm*3z3=A(}#a4PHFjqc$*Cwkh_lW{9%r>xEba}%}zOBQmFnb$`ryJ=d@TDiAb_z{wJ zh1HBZ#3`AuzdsZk>>z%d4y5Fz1|zv?N_K_yAH={v;rD61iq-4bSQTH{(EfgJ41ANU z0kuEKu|A(#k*UvS$Hu-xEkR}#qcyOq2KASA?A%r@gHPzLsLY}EK|^wf1SKWRAJ^ta zJ3p^mtuiNs&4yr7gV*buzKelZ=ntsOsaaN2TBb$O8(&|EfzRr9GJK~}PE+2j;e**9 zB(R&+A2U{|GQmT*_=KR2(V=uK_IUoU8G6|-G%VqW=H&!l)+y>2vQqO;FG$U;EGIQj z>g?)d5LB^TgzNu|HoR%r$#N-HMwM(M6@G8}I!4w!<07@gXVy7`CarS*`u)Wic(1Wa ztq%pYx^ST3bLGntIEi&tTaIaT9!TLvQIBb!*0mE%2Axec5y)n`bVKyRe|=Y^L-aW+ z&DU9>Ajk`0%o@akL)%6DFthyB{e0~k@^IHJN7Ph;pTNU`2E@)kA1BsYt8(|u(K>qN z3JMc;+=zjztXEWw$;{GblSuyajWCo*3E3gJg&wm5yQps#4v+xXL z^vr7N&o(#48sQ#|!(?(9EDnvw(2nfKH;ZNDo-$MB=WhE!PS?4MPTQqZtgw%Cj{ETM z-`{dnRIuF-hF22B-5wnzumYt+jp-1Pz1_rZ-_Eb0@rm8G@b^6S*JDeZ$L?h zmd%IIZt%12CKUvSaX72fs?e*zcu1FEF*RQr%d@}f$fCjKAJ&s15)jrgZ)M&^|+MuD;*{{Z0o%vhjzmrv8@lEgp3i_n?|4Q|S1>d|GT^YVL z;HDY7hanr(>78E{17Gl8Q0Xl}r_LI1DE91*S$E!wf&&+DXOn>5Rh+16@W_5~to7}{ zG$th!3`N3$uu}Hm;T);8nPpc7XOKh!=}YP!6Zy(0r>_Q&QG$jSw7e#k`$-ap#jl9X zCanC&4>euQM~xWwWW~5K-mc?Dju|YysTw_O@Yv^~&!Q*PaOK~w{dN0fRKc_46D#mx z+US8lCe5r8?jtX&@_JOPM>!MOv~_qtBLb|vq`^IqSZu{WgpIwS(d;W_n>RYLE(Zxs54mrGDvG%D~ISG{UUYeVEJFs zG?MY-oWOMArBvUtPPi^{L1ffjv<4;PR7p04yEwpo%Jssh%OrMtMg5O2BwUe#us5Yq zD9UakT7c`1{WJfPIx()MkCV7St8+7(r!Iz>_}HeUsqm^ezbqbk(1d=>9mOfyXXFNVnOsA_7Z*wPjvD^$feddSk9{?QYAG@ zTt;@QhPRn`K@rcdmq!IhdzCnb+l>ecl5N4R#de=kmgeht4>yS|gf7xQs7>mVpd1zd zaZZ{>3TwYeUIKGQM6jeH8q_2$&?btcv_U#*ov_kJ`+E8h59GdPQCkR{(K3WeAe9rs zO^2gg)1Ia(ag$xpkd)8k^khYi29+di^Iy3pqF7n=A*zyC0|k^ij4C(N8&i}LUv^YUb1|{Z1$sBxA1{p=k~{t-ks+FR)y#F|Fo*LJZK>IK zj0e&^z^b`19@H{tQP3;!t^li2wD%v=Bs$Ys*FrlsqP%^$ed__O3ks*e1@N~uI{k^p zL?#DMR&L=|?Yp?;JyenQUo?oCn4-Y^{nc;lH%mFM^aos*5l3@sN`nLl(7CEm%*fdK zW~E6YaEp5Jr#wrXfwGlRuL)%69 zzGSv!x;t2P?a`RQdWtc{+y*&_;OnX=iF42l z!kXR0ZOJKiDTaO3g_BY;MfEx~L6umbWkdN5qNFyPr3yvWXdB=;P6VtU5!oKVRF3G; z3ok8>O+T!Z&h@M{_*pb0%@A>^4QbEkYXjv$*5Xj}QNzG54fXK#Rnm!p{yJI!v^|m6 zrsznVQxO_cQ8A0ZTPYK}244VVq>Q1Gnn(Fb%DTH|r4&G=U58%;kZS&!?HJZH1yf4f zFFqS>KS|s-@vJZ+GDD!uXZpdF(ou_V4xtU&-D$yalS0nOxLJnBIFcaorx^{8^HgH% zSnjb0(ax%f<2WBMGn&M>K`tM@ojWO)JXuIw!TF3L1MSdJq%JAy4U!UTcFLl7nOKDI zh!YVhjs|sY*6)i>j1jZjCX~#Tyb78}E;~QRqR}Bq+qGL5&FV zG37jON7XsGG|9%mB=jWL+}I-6Nd3$}U#g}t`DBB_HuGPdU!5oQvcfw9GVHFxbep@8 za)bEulIR#$y{D-x41(zx7Ema7I3)_bYi(PbTDTJ#fT`30KtR7mmKU?}V;GU~y~`UWjTSmMh4`s*5gznIMBEoC+v< z<^7E}=Wq4M;Ju=gDb-A}fTB3RIkoXM5uC^RT4vzAvJi4q0}~9EG))L3g%fbxqyuDW z1Q8<(cNEgyB>Mz;XV5M7M)0H#d&o0YR-B(1^E;=yt> zz~s!$h=l~NlgSkY;1cf64Ms}x0x8k>Zjglftyg2*((V_>E9Ki;wOYi|VUsi3eCCJo z86C%uPAwtkh+iR%mG(i(;EL`5wA}Zd__U?AMLIpj@+kHt z{(Lts1-}yaaZ^#2-rP7dc7P_$d+DwCyzWp3K*&nwwV6p8<#c%8?d1z(wh1?>qLvX} zir%u*W>c)}{Tp{;VD(+voM^I!6U>&762bfVviRtyoqJJ^!Csnev^7%%St0%9=-cvY|7Ma_cc5)CX3?x%z`-4 zpC6Zrmg4_>577U`+?#+`Rb36kckeUrGv0Z=xw*NynMVSIFoO)@018@b`&OV(O^ZMo z9QfX^jf^owND(1I3SlTjK!}J)5fKp~MG6rqM4%XfLIesaB1A;^&e`YOoYTH<|L6O^ z=l{R7sx7-}1RBcmoqyNBiJ5$K~tHtAQ(1=;@zVrSa zEhCoG)<8$nGedxdEP)^?`nu+r8QU@6XYW!p$C4Cc2-60*bjxcC=3zh2z)i~G4S4K6 zzs2Wa-o_-jq=ky7MMCNEV9@ILrG=$$vcXr#Z$ z-&Ym*oHjct3SEmc9z_E(0$uFs%CDIZ04(>|1zBNSgbNl5`JPOv6qJgC$!sOj@4iBV zYb|VC(R3OUFdH5QK6fDG_4tD(0Y|nc39N(r=+KaEp5RcUYAnJ@J=b8k%9S?34UB`z zH!7rE`*TglWxXUEyhM?GOCadi6_{^gM}C*YyOZ2a@&);vke?@*Uc~EvkKqaAn@ydB zl82GfLX1Ev0vkg}q7-jJA7{%cJWdojmQig$l`8xSlB2-a#Vr}L&|b~9U`iUOwJ_xK zM}po!*i=Lp?oLv&m^ug?&XCXU3R)ay59~_ra0lHlQV?~83saot4lmq;!Rg4g4(+D< ziG-7fggb>LB{yx9{6Nbf0v=8Fw2K`#d?Zo3hO@AWyOn%;!xZ;M!TdTAJ7* zw^IY0QhtAzm}iDV%{!4Cc!jcwbO-x&^#uBsnt=&RPh)s5l)p*YN|)ut`#<{2kUJs{ zqkf$7U;%Oik?|5ilwr%DM4nKu55Z~UsQdq?{;@7yc-g>y)xL{LFBsf4Q9P)`#Qtte za`df^v$ULbUr@;&7&525@>CMO+i?ld=^>Iz1PN1MT-ug|?{lnxN_xIaPUJaFz4qc? zHTVqMj2daghi|_3>1$7por0b|CfXd&kX67nU|2P96^e~2t%H{V$2g)Jmuq)rD8tEe z-|s-bzU1@1fw4h@xraT^peJn0fPHdGu~!)$$cm-p_jo3Cl=GSQz*flnWEam43G^)9 z2sVKq%;?gqf9$cy{l#YWiU0h+Hl{9Xr(i+;)r!mCe7+To?T#`R@UsK+!9!li(GQLC zN`5wIn?rP&1B!<@mILl-XR57>r%R!?kG^Z4eS7oW-#6+R@u_-u?)~|JoMCx>lZSrS z^70O&!F8&gEtC8&^b|wSo9t_O%Z<0R2I{P1 zjd}ZwObzrl{X$QDsgI=5PoL#W2)eKfNfns%fA?u;gWb&9psi=2&DN{HX7Y{sXF6AM zFS|@83i4IPl61wuOMSkxK@&SWM)+L>8A>LY)Chm|rG4)h4Q{a4WiqD^P2~2b%+R0Z z7dkO?a3@o{PDD4AkB2tJatT;MHUKZ2WeWjVRWWa z7BBRvf~kj$a6Sg52>OnGck5vC=p5q@vT>3sNoQE=iqxLirZvbzfeNvTEiUE-mermJ zyLKTNKqz*WM!YEnZLHIqry*st*v$Dd2PN!j5=C&`{HFH)(d&96t-7FC6%rzaPCi^< z32XTJyH2XAq-HvfU%dnAmKoOQ7;=#BhE&A`Jfg&+oZPgqBFntMDJZI2uz+UBUb8@N z96ENhiIBsOae7^X4vEJY{faZY3soP^e$jcB$_Ddn;8h@o-Cn=lu4*ofgN(-OfuzbP zW62WEWmlZYO%4ZR?CU|_zC>@OYdoV56@noYa(RjaI`8@D)|Hk8Z-KG-D5WyIJCyfB z|2Z(}P0&RiB#ADvmoqcXw-hAC$T?7tgIGTMljPQ}_HB=dfb>d`@R@#BpS`qvyV0OF zbU4IwNS0XRr3imO8*jXxY|s$865?$(yJRy;vEWDA`8V|j5hNc9EeQ`8llXP7|CsVy zAQ}4Xso%ZPT(2Xji!AbIlT4ositcIZ@U#ASS)*~r{D1j7FM70m+|%Q6qRSb3#1WVO zwx^>5*Ci+0q(@mIkxBqZn1He!km;tYwN2B*?|?gwpNMq!e@Il8$!puf8f-7zV=q(q z+#a%EVcs=<4Yrjy?&#$bb9=j$EK>(>3}~=jWQF}cU@PfQ0*eb?B`y}fj;gVjl0;!w z0$SL|mi33U>s~rcx7yv3ED63`w>@krU9tQSHn$$8FDb=NM`n@BZqePpSgS+t&`0eK z4u$MAXOWv1uF#=NnDh41u#)H=kaaHU(Aem_RfjaCO*zQ4DJ4BJOWX=ag+pPTFR)s! z_iL*UX<=I4&Eg6)ay1yZ2>g!~p!bY1wcyvI7J`S(t63GH7anWW-|l`xfp3&vUFlg{8!Blrj0owK}!+^XR9yxtYqSp6kG?AX_dZ zvOUof&(E3JKzcYnxU}1_$b;mA?kQcy_Wj9_VMBV2A2#N`2jcz+7qx{1pDUhUnE%4C z7Y0lm@Z;QGs8=YS?aLSPVcA1>0F^JqBC+TCRjI3DGuH)t$hEtRyd zMHSkGI1NY?uaSR&Sj1tN-nOoqPSk;n~`2Lr~R7+~+CqgKjq46J2bk#<68XU;J|D zX|yBG;oy;Mam~AT`?{vrI_7#CNIqA|1aZnGq9Fvx*QfHun!aP*2yOE0q(BiZmhgHe z^>q{CoY5dga(DDfr^eb#5KVs?oAAi%KRg8<+ z){>qFB)dcOa2{JfILbARd(!^I)F=XKPq}-1+WE4t|j?~9nL2eh^z$SX2QSJ?w7;H75N6F)olVHOxl8Kn|O~V^H zw1un`>;U>55ClwU>q-?GN8U};ZRCECO4y1+KW811pdc4qq1DsH@0isut$Ivt<($o2 z5bS<;e@^CknVAD*zr~)saM3?+l~k6GRc|>_k1Nx8>gW|bM=xW^} zmsX%rR;$y!n!3R;jKFEk(_}sEi;ij{n=0<#MybBP>n&;)nU2?tSyNXyj#GQHoM5h4 zr2*Ycw+QJ9W6zXnhnZ8TcDWAS$DS1I5Tq!8jG8OfRINkrvd4uWNu-7dqm&(%N81+Y z&_=FZ2-;xZ2qgNL&!{!O(V;iECf=Ru;yp2=G9h->X=~Td%_4ETl!4`x2Z(W_VARuqVT;MR}lR0q(z8-X@hGHmeKI0uT{ep2+}2zWGIz}C`bd&OH%%B9MBCg0+u>^!4y||X7atc%-(w2lHyt0=f4Bf&((SHlE`qD2x+)iNGnkcmqpB` zzc{7Of0t`E-$&wdd&?-xl%Gzt>d@n^8)7#ScvQL6VsyW_Tc770SDh4f*`q<3pq;!c zRY8z4+4&c{j1_k86$g9x%t3A;!yMtrULCr@-OdkS=)(T2VM@S#kDSw?huvFYc8VvI z6Lnfkmd&rEG-$i~I@c}7aFiFa^V=*%zOAyiCYMEG5god@2?&7 z3t$5m7ikw^BL&iiJXsRsrU7rfs9`tG!*A>EQE;^ok=)s-_M|NY&!GKntWI13*SQcw zOAbORP7w%(BaKvC*nY6oz|jF(Q3SxuunnYJe62ru8&9PkUg2YQU!+Tn;w8>VoF!;e zx!0=qZ-jMH+@XZi?6QT~d~s8UHo?t;he81_Yn0KzV%UkxI`-@EChs9_ganyh8I;gn zXOtdIio2k;cm<#t=ZQ_yWd0yv`f(11m2EO7rpYO8O0>zei1@fWlZz2?I-(p0)nHg` z1BjP}CJ&u4pbli#gXh+PCuW16_eyLA#n0sb82y-=oZgR_AT0p>Ug+0{9w7cW^$BK} zFd;J+H3P>CUn3~|iRTGv91~??vQ^z%y1Z?9x3Tm8rSv2v;L~-L>tl*Ri z?I7<;lGBAmkCV4tBOQ9*ljLFh>bN5C4uu!&mKd9RS9NF=-J~dXm&@)jalJxC2*utKgf7$ND32%Z-CHBIBFvV)0L6&9&sM>HlAV_O8pD+q4Y$!2K1cJ|5rV$ z!N^C`@>3Eyj<733ct8<7ghSQHeUriCyvKaZne_kXFiBr2?fvGXd0SuAa*d>@0s~o3 zIzpLVdoaUiZui&sR$h7kByLbcorfsU$IJP9`%I}|&5rfS24|^lFyxD71>Gr`=GVA< zduM~&)FQ$YADZP(8=}`77w`+scb!Arr1wLgClvO2gHaR1+gmy@9A-AD7zSi{)B0wc z^4G?#oedUohX^)a%rR+2$W(yWyxG}cFIPtn>gr$@Qk2$MUl?r>+_eHlb!BAV>23 zN;uCvneUy}8)PE?9sV#8=uU||)7Qo`lt_#HvVQ#HY%s`pp4j%zX#>>`VL$Aa?um3y zIK$?OUH;n{j4A^;ZrUGz6YK^L3>ew#0GK$ir1v;;bKvN6U)}g_(`hY+{=aFMJS_JP zwA7po93P9{K9!Gs&54755V{r!SuBF{X}Z_DNf3gA3wunD7S@=>dPb z>SD_}=eMcTQ6|O-vS;!IMOGpy?O) zUW48sUFD1R*_7MKIAPbqzd-2&kWBobg@v5Dy!yK(XRwa*kIgz)e9r54UVlP+ez|VH zL?m)l#_vi*-M-$soFr=3#@FA}FYVCDsc_tYo}ka=4tXsB^UE7&UNh)j?NBF_?sB9i z+;&q_I(JLQkU-u&j_c6(3UKieHsNDER0PIRVC=)jaXWbQl!hpZ#A9kZ>DQ&SI1_Yd z%uu^ow>xP$>sUexa?Hmosa|vSFW=~FaKUkvh~-3lX}Lj5Oy;ZCIvbpJE+dKtr232d z$8-gr(Y9y)UppHta@LXYET1DS*K2VIIdxrckcy;wcO&HJcfldhV+8%UzV;dwZ|``0 zjlqicI2)kL84WpIDVFHDbF*GbF4URmuH&$nyaVomGC1MkM|%+DQb5%L`gOo81MG6Z)dAFv{4L^=S6CNaMJVRr$h%$)oQ5eKXKZ>qoXE0KM~0-Z+%|bvL)KGp=JH& zm7mYmVAECDnCU94xxRUK^R~R^)y<8cu4sNA*|i@&oz=W8ihr7={^UKp>PYqB501<^ z{Qi;I(Zg#GZ_@tIqyBj{dZHHp$4cZlH|x!Fvv!@E z_42uyADo-H?%b@mQRvHA^hTN+mJAP^5pVy)1Qq#UOr|#9u8AIX6oP5tr5vx+&$+nyWjoG$^|p-@gq*OSJoZ| zV;@69FEO^KhISqGgWTa!Q30OVlVm)l4m`3S@JO~XM9=4k|3C&JOGviefKru9j!J)| zd*4BMj|9E4)6EC@0+|v?PBLAQZDW7<{~g*+vTsmdLY2 zrZZHQ;R;&PRkVGpfddGwrW#0p7jM|_w506Y)HWH%%W_SG$^rvUPtd~mD__~HWA5Op zVZPs^GE=YR=Bc^yJq9aPs0lK~P-2BAA0P1eqc7;|yQ9`Xz6~9RWF$hEp4u9?)#xqU zM9q-)L@3G|X3ZO;VvYgsK-Y;-N?~>|T99Sl(jE8i=-?&%cBo`$+U*(X7RTetc}DM@ z`~?VN31~}8v-madc-a6S;&(zJ8W;I+nqVn9`HBWkN3L2`L5_&AVRW4DcOD`XPH- zFC*TAy56P9Mq4heS*kfu)4S~Zh|H8?GIXDc8}`$YSH64blQ)2tK}835qTaae!0H8> zDTh99UrYRCxRs*jcaoiSSZAm2-^QKPwV3HR4Py34S*j!4!_=25e)H0Hyqi1Jn>^r) zrKN-^RpXK!2yv2Wr>tMIVEbcwW`jED^VwZ~x67hSHm}sc4n!Vw?1sAI{-usT{O-#D z&N$&X27RfS0dG9RVv(zyy+_}pMb6!XH&mGL1oP4@J6vxJSmWFZ9f647?e+UiC9-m+ z)>|9UxrZnN`RY$qU(MhAJ|3{j)k4J6e7>}}*K0~G4fBiv8(r1V;Z`LdPcjP-Hd@V9 z!86|Ym%AYRH@BSo(J|x7Crz88A{{hA9b<}CuzTu^?ZSu;R-XRzGpayvzpWaq1`ag2g9mCq5^oU;h+ac)PqOr0jdY1t3eIO?KL1eAl|QVM&WkQ z{l15uc=iJL43@!lx_5O%6=j(7pd@eNj4t`lzNp7sYoA8z+zadL;n-4?-68CS{Nwh_ zU~Eu+I?5o*K~|dGW@kl-QTSZD(o^9D%0VlxnDP8t|M`uB*fF+}yG=wC-WL`Hzom}v zlCRe5IZhX&>#!swhq?q6{m4i-S=BNOS3iK=Xe|sqVCoy{Ic_|EcRl_9bXd}yGrRuW z{6C-8vRQd{x;Bw76OWyO|8WX*?ajRcq%`9GuvKZfcKOTmJ1~LA(H+8(5mD@kuxLtx z%}bL6uI8&?h~|rflu%>}aUE+hTs@YX`2A2nmPfB&eq*z&^=al?pa+R@FQ=rLeVUfz zK5^ujE!=?-mT}k=JIx6);puL^x9r%m@|E@48-TDtXopfpFPE6z)8d}ju_{Sfy-*KP zii2cgPD@serj1GX24Mpk=n<0qWkJz&qie4^qrvTn+$roZC_me}=~Pb~{vs@fQI-m% zFtla2+P5T89v5zaOvFUeIXY}!BQ0+w;f>;Tm@9D6ES^m88Qk%p_B=B2skuLcTbwOmd3{sS?B4bi0F{Yf#%)~TrIq+)}7 zk`OW?ET0)>%!AN)J~_kL%3&CTM88x(_B9=k>ThCrOr4>!gXrdQ7It;Iipq$6AW0@Q zx?}Y_f7X*=pH_|%r6Jzu<+Dbm%B8<312J{2y*Oz%Zqp6L+8k#A=)+~_lz3fPz6T_y zZA{qlIq(D{qC_OvyL5}~5zYI*)R$}JMpJ!V1H7sCy(j5weThttW_F4(m7 z9XR7M_^;~5znMA|x&P@2;V7IRKy`=eRX^~61jxg~51VK_ZIe%^W zOMlp^y>_7+;3zpbTavmOg|nMJ-~aL|d`cVOF`+oa6DrDdTZD%lYfsKxr6o5AZGdf} zL;*r!ASqFfOpykJOhZzn?dc}_tXYcNtN1p4J$BQJ<)gIc1dAE z#RVZ}YRqY5j-qj*w%3z5W)mxvn9m(c^?FiGAKCi1lJItTUUUSC)9wDEgh_MrYsoRH zh()qT6dVw+$gkLg=EM1(x@4Obsx}j&37;JRNd|O=>95@WZR1__3oS#LtBKpPONJ0} zfmdk05(Ggq90amc;CSP8K{KZ`Z^QT#$hDnlh1nwDO6@G|7FbXJkWt15 zKN(ldyZd1SskJ*sY*GZfM}m~V$^o|s0neEHuwgsKr$vnrgCh(?VHR+vn$mi$^)Ala zF0Li_!BYNVTfgvgFB#5Qt>58!Xv~g0CKXFUMv=%{Y_Ihjlk3?*-j!T|MA+$1x4eNh zy^$RI4jCai2Mv(Z5@^-9Y2$2TyQn(JMN^WUB1JQ&NX?tLySj|qs13Y>&+H}&1jQqg z_BsfPAPI_6|8OiXOAN8-q!Uydr^8pu^ zWs2M#os^xX&I?pgM~pGC@}BM z#w|(Ww$dRb=n~|B(~=>p{;g#9>vRR@ac1VbT^V`i9aD4annrvU@>VcD2nb5xNt&iS z0fCd0a3o!yh@!nB)||U$?BFuy7#j%p>gJF1w3HI6{Q|?&k@FoM$Gso!LrQIow$CL1*XeJ?fGhJdJ!)<<KT<6*li%?vne{XE%!wWE%AK`P+{bh;@iHU04|Z3cNLrOt5_B}&yWOOI2j@us?!(DMy@|lb>I0MN;%(&u;WiM|y@NeL+u%8?8b;lRi zv4gbtC}GQ}0A2d50uzSE`t}<*4nCSWgNP+Bih!2k;R4JJ6+e^{EPB`smAS}bX^L(E z`Ju9>@`61^n{VJp=&=PTeim&e7_aDb%3i)N&)A_XY1!7ClvB1lc{k;?xsCg%qDu2S z5Nf!aK#1l$#nc>+xrvRlFmOLtNjRLTDRxK9l5DDSCI+^1D+nbs-!5hpILu?*a<`u< zXDBDpYM7s$TjaKLg5R5xF#QGUzwM{>zK$vge9RKd_O;+v6ZvZb}+#0NIc+UGR%j_=9^nr%!4=vNN!Ls6<>BiNXt?35FSO-u@78Y z@yRrejB5EjjLDA76vdfg&aU;lM>XIkc?FSacVuQbtf2*!cOS)yztRL<1RGE_+@QG^ zl{4SghE_XoP!57P!{(>4jO9*hy@xUHQ?5gWSG1buPD}lpHoFEqZ*L+b*`tUK<0T5; zc5RpKGg44^==6!x#!u0Tk~}kgT6E<2DbHC_Le1F0kGOne^4hud5~EcwyBa&g$@+^bP29 zXXkr8S(f#m_gWHuhdvKtDFX(iLO&w+m42Sre07$uz4i^E**x0##W0tmb8~1aM^C3i z>o&I!=3d(JoxTz(hxe5}SK#eFU3Xtp@J@c1oaqMPB=AKtQ^WpLiyCm?IEH%>*DlNj z*+Wa}3}5ymdz-)1JGO`&FkNvKCS<221n}OTB)m~N13a1OE@wvEX?k(3|8Bi8@Dgb& z5ta6zg+&BLx|ebTdKt zfv+(REs?f#5=2rx4w?#h!ZEL#VvQ$gY;!$wH96KE`6|rG@P~3U1Nw1bv_)9BxGinHMGu9v1Koy5H{|Y-YS( zi33!xQe#8@?CfA5E6cpAI=+8c3ubI$#)j;!h{SlJIe`rQ<3}EBnH;Y5-N8N@6@7&% zir2!E_T0m;1zf*ecXU9GC#AnBRdjrhg_RZDUXW?`m1H=)T})u}9Sm&bDqvjYbZLLb z=_T8;PB?(JfUS==YcHsOj z9ObhU-2hVdlR+`(hY|BaX}O4Ju?yvs@e+zi>q1+GJ2_m7zNirD;QOFdKkE&9S1cKY zJ#W!$f^@|h!kK1yu57%C(cMAWbS#^pQmuKR+RtEE1^)z_U&?WLU6DnAJB6n`n_mXl z%swKM(Oa^t^cVVS^36bqCwM+BU9cE(|1w+`tM@<{>qmf;zR*&-;|d0@frBynZU?Mx@WhsS`|Vg5OT9QKF>&qhX-jmiz!$pR6w$HGDmcugv^Jy_VakT z)(VjT#YTcOWx3RvPYl=G6R!$u0UPi!jNfb7gXWvfnxe+nh>w>tRC-sIOq3BFhN_`4 z;uDuYJv0rcx07xHDYJ(|OfS<}5P_B4QwOvI!(SC+w9AhuXF%tLy1lODfF{4lm&5@g zsT4*zKFyx2@q{xLHk>?w{gSpx=OG;*g0wh&z?A5wBn5Bh*#p?=wq4u?$wUbOGP+t0 zT}7+je}%LQ2%)%4i4;l6VacolvggkSfG!0$0^MwU{f!1q;MLOBNf)3LkBDMw*z%Cw zc3vNGg}i`Z9jOxIj2VeR@MG22&6qRz*cJ)_}Y{!}OppD=#R#BnOS zzHdtTbK{Zs(J|!{$4+`aI`EnD3FFj}Ri-&~(zD}dZ0AQ@>$qZYNn4pCQS7#76j?ka zHThP$3a)@qpCw>mu;*)FfbLbVT`ng!GFm!dbrIC;2 zTHoQ`ZEe~4f|mC8pEplR8f)J@czef5yvXNaA&kXsAl2%JuzoY6eFvL~8ff=)%XWCX zW|%kHi8mO`p@=@tcwxwuRuD8{7dPTmi+9ON81>mhsa}_*7}>3F-^Bq471Wa+-jnGT z+!ht)$g*7+SW7+V;aw`wX_4s;)at;^R38Q zM1Bx6L{aR%xv*{*_R?NP?*vkCbfFk}s=(yL@4l)-x6-vxa4RhDkr|6Gb&Za=jV|<% zOiYy;EVXy8t=gq&9?nbj;|fXgKAKQy$VBr*<4Fl>wy_iSyEHM8zCbraCB4%XLEp@a zZFL)PB~t_3xpNzvUVa~Ec%X068(``4fA@%bA=ycXb$0qn@1(McWz5eN#+C3(6ptv; zZw4}*SfS5$AJYPQ$tbgj!e?02h&%7q=%Z+#m!>RlckA!!&}QZW^pQlsOOSq3 zTDv%3&oerky$Ml4g5~nlDNBM{4H`z`X13qxf>9g5Q-ven0H!a?(sepnyV>I)W_QF> z6}zRj@U1nwG|@`j$t{KzAmV@K*C~PV_$5rxI-fZ6(VA&ml@OHrw|gR-+vrTi#s^5I8UV23%OC992FcUy$2_jrYoW)P0`I3xD5LW;)oX=8` z9LC(K)}ty^^Fxs;!RWzh#bX8~bUBIDPV>^MD(V>rz<+r?`xkTS|LV&)Vnp;GNOb(2 zyZR*V>jYE8{nT#n&5 zXdv=~zC>Oq={JpISWYih!2zVS(oHbjh38}~!iF4VD0h_vcK@Pw!25Cnnf-Hv)*y(w zBik_MyYxCD5soC%BVmi%+tSxHuvW>2*#{SarvmX;)mukz;K1Q%D~p>0A+6uAf3)syPxO_TkJjRuw*Y!%^fW@p-6Ss5mlg;fT4 z5qA>Ax+Z)n-7>u96WX;+8aRsN-CVDL&E`{VpfC#<1|Nt6q+YtEBWUJMLXR^LaJ&3| zbNz0;WZ=KTZHJEZT#qx6<+gx-XMpc;cYq@;p~#60i+l9S1_NA)YKeqb@;E&y7Eh#G zb2`DxK-^|4Ndrc?Gi<#*fP1SSR~0JDB>)*Vy5LXVU<*$GME2R08W?oGFkyQqH%lImg z31EH(X&7BG8@~0on>u-G`OFfAE$oV@B9n!$zhRJfmahRG0tTEUVeu(B^7-#pYvf6l zLJc?ua%w>;qF7F6E_N(xADI2xhc^iAg#CS+WH!%ZtvlbZoQW%1tP^S>B1y)Byxme| zkDhu3Xca9EoVu=)u~=w_*^qcL!v=q3=B-+~=r@1X{Rf3Bpcg~OdLzQ((0}dpb^VO4 z6E=eo0a1vca~~3b-2j%S6U2;!-5S-3~NI&OG-h- z$QUc)OaGj)8M~wgIQT)QGU$GnC0*^k1?ntjtOLk3a$5PsU%aT71{kZd%8}1ZnvCSZ z6UIC{cG8QQS>WFx-fD|5V#^K9xuPe^w;d)*b6@a{2#qf6mD|lXAR6~QIP_{ z*&e3i45A=Icn5}ibSZdE^Ds@Cj%;K5{=e;P)>5yw-_~8c59)d5K!Yltc?l5rDk&k+h$t^c>i;Z;DA!hbF!JlUAMN zRKK2Fz(#u1D34e&(k*o{c|-k~GxQ=R+espp^b7z(x+Cp}X2gH%Lfk5hsBWyMB&2^^?Qb?U zVxd!&cDI8-dc+k>1T7Id4d;?XwlS?hkbN#r@>?Q~nlECwI>%+~*r8E-e2CwXWzx7~ zi!iWfP7?n~ZUq$&IRj~atHxRR0miQ`b{jXgBBv)5mKU3-lDhc=z3qT+AwU+%!4 zSv6llNUR*-8Ob6^>^Q3((HX1$#f; zI}nxHHi@Jg*(JFK&H}$0SOLaQ8=lAs^;Y`Yf0!{St2|>4D1RReTn?E2sDGfhdZ#-% z`+H!d8Grl0|2YzqQ-1co&INI7Z6g&BeYru&ontcHjjbDJHt0$H4w5_QI3tv*e9rQM z_4dl9IYxt-)LJIMD>1(yTOuz%tLtpgNS&c$ypo?P$a!XibG4lfTB#)z8Omm;V1~t{ z`QEus8rIQ==%}c~QzbFYByxFmCx*TBCT6f*$Q|V3EvZmHn%CK&g|4SEIog*YP?qS= z%We7)TC6*>i{*ago(Cp}?+M!bmKACZ%=r4=%Zrxk3)xQBsO!YW(pbh~ zJ$SXMlY~lU7agGJh&P$v9WTS>zuvsQ9;a92HZhy1qkx}mx7u4S*X?}2{w=LMjS26h zZ&}-|nrzJxU>CE5(#@j3*|hZAA;)GGAjYDCy?5_Ga$fCB8(qq?nLPx`V$GTV%E!qD zx0yPo8^acNWf@DhlXKM{8*~Wu>|rXOAY*wXk(#tx>mJ>oeEi2Fb#Gx}_p?=WF#$uI z4f@haBU}hG&Qo_gX*tOrr&Vz~u8P|hiT<;iPFh;o#Y`bD6&DC%ktyr0snQ#S5ObHU zryg#H<`$5n-(I0_fwvRdxdCk#wGD_NaW21`d2A(^4}K5R`kS4p(X+m*TDTMo9Dm=Y z6UDLSk9G+-KPR`1%4UQ!c>B89VjN3Y)LY_OMGz{GhJO%pha2=?{2oej>bG-S$-{0zlz zNu#}{qLYRy)Iuj@Pq%c*-NoF2bGLL1sag>G1uDXOyN4xTw=!bC=BteppMSKsbE|97 zY9rr#$Ty-DwC)e{>Bi;1*|P-9xcKiF-J=YiGG^k_<&(!u zEH~`G9d~EsDpH81@boqy;fEnMT z5!ZgVf3={+{2ycX(miuNfNy{t=fI4f885@nK+o>u-v`zdEI8n29nnVkf{Ca*lwq+M zG_Cx&Uaw-kk2p;FB#I3w-przKNIyc9fGa((S*2HcK1S4#u5e-087i>k4X9X+ao}1h z^;AL;qv^?D4}1hGU)gH(uOhFIVywg^q!u|XGTeeByq4TSlFkH6IMOZNzI$~10mQYa z{iD6Re+N3PWUXu8+oHnqQAk?}_y}d6`VM$%6?kA3=s6!SUg)LWirox-Z8&vz=_%bK zf!a&@!nsjzBqzn3OU?S^TozHgs7#XTlR?mykkj^0-ZN<3Pu(Gf6m7Q25)# zCAbqV(UWF@w{-U3Mb9My!9*e$N=vuk|J~sved?X4xLuOnW49!sY1*0Wzl5nJQPwaQ zpE<;C(brZd`=4QMK$@3W3K`YQaOSz@H!$3X&~4^6nO~M4M?NFh=b4t@>OJSOXJMJZ zm-gU|v_)7{t~{QE&t@A*TXwO{mQ`eVG3sbZ!cVh{2|hm5C!`Ir_&K%e{R2o?%`K*a zlBf_KI#VCJ=+TxEMgV+yp>DisYRH$}qFgHJ`$56Uem*ZKv*Y(Qb)E z{#2fz3wS=;l>BQtPX1P(>1NbObffy%Vn$NW9s83QuA>D+9}h}#GmvsJgkYz*KpA+{ zIQJbN;&!UGc#_{v4R8@i@&y&yo+nFbrc&SbEgmO?q|~5| zsuu4OR9OivC{ZWFBgUN~J8YaEKu*i(rPA-mCV)@y*u^MXC)HD<1mHq8rql_5V-QEW zIoe6^JeiW9Nqsg7KA*Es{T9>Vs+HH0#hF^7o+5T2aMDg87%(i%G3YAcIn(oW7`kf^M9439rz_Cr) zO)@2!G}|SEGI>({F%8EIC$ekqh0~ukybG~Rf1V$)X2V?V#kDW$Rsps$g%8oGM4FiD z_CNK*yxumEWh8Z5hh-0oNSsX`a(`-`Rzz1IDnNEWSO0{o}Qvt&o+4b5Ozg9#@7(}K6h@O zSF`VW3`X(A7gMnpF29|OK_Z^UXn~0ygGo2ltW$>3V!@=v?iMy@SG~ws8a1bUC7f)wUdKs}DChhX%=nwv+HHm7T z&~phlMY()5Y1DEC5KEHlKmF+NG_7*yNkOZ8{7dymdi14_R(w8TE8|Dgpb`CFCQ~CXMs;YF*cg0I^s>MXl zjK21&u}sUvv#K%#qD26vSbP^RO;t}qv`*YbC^ksNRq0N!0f|xnAP9s402w=gPSflB zi%Xb_)nXMnlm&_VDKf*9%ony{;5P9NSqyEtMId?b@x%LDcyhbM3Zjq%i99MpG=X<2;zvxHGEEh1aT{?|`Lt;h#=n>pdq=6F z^?=9k$JNdzO+@LBkDsE|4jwgT>a-W5qg45R+SKR(^{-$2O#LOAh(0)d;!mGJ8U2Sn z5FI#a%H&B?G%?)p2cH_v9FYHb{{8t`(Fe<)EuS`i9I`(;ed^Tl6DC;Fx$!D}6Qd(l zA$D!$K~|7lNlOxBV=2P0pG_ipj_^N&*|}7lKbzeTJwr-1ii^t zkuJn|+#GV7_O!|i$^I+2^Q5E%1ELrTn%=T4mC63MxxHi}_m|J4XH6;BPo?%2Rr8l* z|7u|$RXjM=mp3HhHU*2Cb4mDSp_)_@Azn@kT0$opnlRjh*quTx{gWp_FC%5&>Z3-# zR-vBqMeLF{><}$cE-#2t@({#d4%*;|V@5Pf0a+hi;Ny_}kas8=~>^8tD?5 zmhYBhc|OG`BdT9;EpJ{~z6mE%yCJS7^SdyVAF200VfVNkWw58_*^BU{)4Hy)eiK%V z8>Bm=J!Iz{L5ENVpH4DKsrY; zg2>o?DoL7~3a%QwXLAzAT-v^CT9BJ6$u&y#L?j@)?6Nn+F^HoG znjsrhZHz^B;r6rU)vd2KhVY)LoLP~0K^6sz!M@@Y9@c@#wbF6J1aS7X z?~m#+OqTz`CR;FB)w$a(XjKO}Hkz}TDWErtayV)HwzGymX*KgjW z*94MOg-_MkoT4jD-(h?KHmt>qr0(Bg=`0nH1b45fKYwJN@yZcUu!rRwBM7lY+DiBw z?vU4RJO*PNEyt|HM!WZmrj_&z>IWT1Z*9cHsu$vMX+PyjQ^|4sj;$}PGR~^J zmhnjTkXv*FEt_{tJF7Fc|Fc^H^&dNSlJV5*c&L2bv`NoTwAO!j4;wfjI%wk4Q^q`3 zKJn>JPL4)Sn?A05Qgryl@dyo>G-=#mm93ANij;xRjF~Xud5y>GJRJ!G%GFCF5gqX2 zwDD7s58p78ra!H6{pZw6VEmZqzzO9O%YUj}SJTu>rTnMSq2tF)nD&g?f6|okGqwpM z)-2t7{F$*iC}y*521kh+&<1vb3OMdRXMzch;EA8{)0AyMsRhg^mmVfz(_&;N-XI+W z9Z&!j3^77!Z;9_}?rzKZZ{N{VpVWZ8q>^HaTk5LU*X*ms4tF{%>2SAe^TLix9oo0W z)`Qig;1syO>$dx&-!y1u<4$O2$E!Ejo;i(^sq6r=$wJWtRNl}krumbAPJcl==4p*I z4nY8?Dao0Lh^}-?cw5CsH{QW+fvT)^lQ>S;%}Y;}_H}a#tfXD;c*Ncl5)(hiFsfq93Wk_m2Vo5*hpfefZVojkpf>C3slX z;B67F%_cZ)Ha^V;!e%sT$8YvD>3FWf2FeF)32(B}HI^qEKgG1Dcq)i$GC&eB!3KE; zB(l2`wC?H8yKwG_Bt2Ey>oYd`mQvJJlp(Mb_}?Qw2PcU&@W^_sPu$3*$XK>#S*KvYyJkKP%o=ywA)B;wP^P1Z&ikHvJAeS zpkq>gpwK90@;%0?-R{Ck;$dhj4Fc%x0&M!h4rmsu#&(QRTS}ppjM{9m6r0Ure{H{x z;VNa-ViVy5WSM&K2~{P_VQs*0zr=Rlt4TcP#go)e2E_{h%B?>-VK6b3Cjr5;BZBlgP zmpk zAZJf}*swjOUPbl>5R6hzJZKATWS{z@USO2oW9pSJk~uxAQFT*Z0Hop?`r}bx)l-Rrj1ar_SOC)s%2^ zBu=ltfW`%$z3ConLLVi!ogIfBHh%TbCSt0Y!L4U>;c;1C!%tzTg=EFH>&wWQUf&7N z(RN#Ov^(5v&dSb`lNd^vkKFuz#hV0;`*1qcn-aYmb5ckysB1G6EL-SpwAPbs()}sj z!L`lXR(kO=9Hr~gGW?F8H7&n4vq6jBxkqmS`tS_5&Yd25vGC?;8SPGHI*j+k<-~=@ zch8}BfPm#sD7rgudM;T<_8xHeOtFUNcCiHgYU@{?mT}t3-h(*>vF>hzl#3*C#H`cN~TZy^uI%@Sus^h{@R!Web=YN8V`sW~r z+`F?c;q{G@^wY(50Db_l5zx6zwmI!j-R8|A-8_|m0B}JMO!J#Gm4TEh|zd?q@p8l9N9}0iN)e3n(8;2qWYsA7;T9~ z9aKd}mg5eQatG8rU=&3aOK;TzCbz-qT=&1AzP*foNU~|GT_Ju z2lf#dN2S>?Dls7@Iw3Jufx%*hR8zEn2kzpQw2jgpI2*h;4{QX?+mOIe`>`GBUxvLzv#&3PD|Z3C^`C7OhSik zeB`dJsqqXbpMZ|vwrKmtG|Iw;iNk6Kx919kt8H_ALZ%mO?gQD|2Bdd$?7?P%c z`INGXs&Nx#`Qpqku13ti6bXgCrITxtW#zy#xMqB^UhQY-pRkhU^mSPu^9K*}Um0_Qv{A8I7o<7Qa zC2K*|bEVa?_#9mPyyxMkF_0;BKdB1e-_ZQ!ZhR27C)U;V{i20AX*UoJq66FAB0Rt#7v>%`z3Vv+|8kUhn z^2b3FG*aXtX3pPO_qOiPK&`CNY#-8uyu4JeH_N>%}lg`V)ZnmHR-dYE*efgmnLIeS6;+j(HGWEw?IQ;tUgvH z82ZVKm?t;x9m-Ja=?>tD_u3*7BAr3rergYH#+8`q%Sy(N^)s5U95Ue8s^iS#BL_z% z7UZclD$yy+O5!KdF^8~j=`gbedRULCe{JXr9XbXfMlOk4&G&Bbga zV(#R+y^SOn`$c{i7zALSI2fVBI*gZ;oW#8QWGn816scW8JCg0w(XM+13%O|@oVfH^ zGH$r|=Z2>DNCOhD2gTWd8iY9Sz|ji(W@Yw$b>YioSoLk;1d?2cKX*gyTecMu?yM@h zIv;mQl)~-{&5%l#D2}5fB+!^>bY4e7t>>#iX82}okojZb7c^_?TW* zDVYjN5$7MT1R6|{BMoc=it9=z;qU{cYwhI87^EZ)sj4iUT2Ng)=|9DQIII?%h^9=O zDrpBH$&nvq(w6-Ek)DyI6{X{e7kDo*|{<(W8ohvB@?X$&=C= zJb~!YB*2opPi=MC)Je)S^2&qj3?yypPDq7U+h_jViOm6e=aV4AmdnJNU0u16e2<7= zb}p5B2TY81c#>jV;X#++CCl<~oBlYkrulW2bYDnTtdlEA+u%iv)!=knjG^U$?k*y2 zFP@^Uz6`g?pBWxxUUwIhR9n-)A?T5KXPAyLh1}QumPO*?!49BjC6|HXEg=D(ouqLQ zSO$b-H_Io5hXjakUY>`(IiU%jpnJvXxL~Ev`&+doS(3j^GmT#exh(Kk-Lt6^AN^aw z-@(AIz%1}3I0-bo25IstE_nZpB-SVIZy-17)8Sm;mQ?<5Q5|9kYUXgnbPHTeNBit% ztu@TkB`Ty$)4vI(x8Mv~67@!2Z3xL%H1GE;4EHd-55zn3E8-k|C(6tV2a9&lBq;;E zj4?+%*~8>{qI4~3cWF{0k-Z4j(IahQ)F?Y~*N{sE-bAftNm$J8VPeH>C0{|q74$S# zvTkE<(7+STxoF@sK!B(Q1P2V>;T)ZF;KmGyln%awJ66i zmhg~iCwQv6YCah2@X=$tuK=k9p~)2Pe(?`EZH0Opw-@prZLHDnGRu4Q?oTrMH@H^D z;O*+v`_gS8f#28P#lAA;bKF({2e|>on*rz-MnS)pN(Y!>P@)ESc zil-}nKs^#ASBF$ji(Us0SqBfeFkT($mZ0bqXu&Q7(}tvW_S?Qmv7?&-8uB@5vvm z7_QZF>KP>b_Q85?CcFw%bg*Pa=chZjrQxu;p*Nv7#%c~0&mpdomsYgqVDsVV({yF6 z-8$(xn~a;52vvM#XzGBs*y&*EM~HpR2aCWVuoay$cHx7B?9F*{&5o5g#9H;@T*e<| zwMItULh@bKU&kXLt+NU4pk2*ubLo0r4s zjM)&6laO`^a`VoP@7r@o_Aa=O@y8mBz8IrH#*dhg&o9RKVM_wsis+)IpxK*}8>O`l zN$D=facVO#m}Wc*HhRKcOmw`}6qR7H%3uhR=a*wJ_|6;NWLze*Gt6oV3u#}mR2in8 zzD3(LT6=EPfSUaHf+;#liCONEh||>kgy$L~8S9z#^w=KZU1-gqRI^Lst)3kEHz->s zus-s~N`+=?=-=6tRF5YqEi%NhwBzPl1Sd@5nwdLH_vjEU39*tn$LCxjQMt$It(?~6 zGHZ-shLF62zpN!|s@}pJg~K=)Kb!|K$~`hi)SkPGmBD8-*V)H<`!dG%icXi+1AHbv ze}7MBH+*cqMjxY7B0b6KG#s>1FhRDw7>MzA1;I}^z-(nq9-lX87G#Q=Kf#+iLPkK6 zs6-?lVo3Ht#T0jbX<)-JbJ?yQi#I*O92w-@%?+F0$-xT30S4cF48aLpmRxQ>tU-h| zpJk@8X)Z|jk5-!=N}ynZMPtpOPhryXBn`qmyiiD^>SWe27r|te{XD2rVxO#-o43ru z(2;hwhV7s|yt^b_Z|Es9x-N+Ehgn%k&gQAdQmpat+K!x(LaE0s_L1&xlTqhn?ZCsi zE8C&gWwdwodZhlMN8{AlZAOPWjI)4n*3kg=Lyb+NacCmg?o61F13w0R=;TJskAG}m z^2c{%=?=4}*b*b{EH*K=U`n6nMvNQUW%s$=tXHB~mjIY}wJN1FOx;D!s7~@oEcg^H zkW1ob3&%Mam&V2`+rxo*{w6X8YTY8N=Ro|QTN@S}!<#2X3R|b8CO-F2?mZ}$^-iDN6mqs~KBz#rrMkf&EzNAvszRKgSMEp6b+3T`&D7%> zU0yu_o%RP#sVK(Y^5{TbT{@}MlV4R^T_b5nB^RQ@dVYCj>Ew#i7bIayRfT5?KFI&s z^e)k;;eRvA)Xh*AZdg6zMBkEV$=JfIgz9^MSHDTy|GEUWFl-t`8VnfNhkgeLia|b4 zO5X#gG3|gc+9+Slgg8D94AXa08#H8C2zvD$8x_ zK0LIQ#Msp|L+I=Rfg?qhjxHDRadW{gTGv~K z*}ROvwBoDYAE2Qyo0Fe6t|HH|BL%ny;vrWMN3(-uX!zD>6@yzw&fBdFqw))8Q6C$LBII z42gJE934CaoH}z7L&Pba;boeNN7`*n6bR0q?*^3F z45|2Z0DHQrpfA$Va|F0clG^AQ&<@yc=|Iiq8}ZSzWY3R z8?oBcbQ?&cKy(+1ic)eY$QPg=w*B}sc7+w18ALK?GZSQ#py=w_?O#tutjOBNv@!Q+ zO(8!(_jFi}r5=P05_`~pih^u8Uq1k`qTI{OP4FZOL^GhYRsf=6ASKQMNO}SRi9QiR zmk~hMGd!iypcX5jR1Qcv?5O7$ftLlMqX#Da?MvIPksPmcxdZedNc9~EsC?PvM{*XN zTE6JU&%`3Vh&v0Yw3~niss93ue3MA-9eyDoaHSD`J%IjP0DL`R2zl<3_Eafim#`0l z=>TmTeg=S4xCCKO6-9-;0szJOK=2&5vVQu0^hy`Wc~&?8DWMTiluJ!fJy37=+vq=k z^-%Kh1{#SdYk8eunJl?}5chzAEMQPifu(?*fs{I$fqV+XB!ql4_Y|B}t`px@ z{RBb-xX#b|0IdnyP0OWIa3wIjXizFye|TY={5f5ePSK26sj+eC(79Fy@3G6$3`jW< zy;&Ea45=_^!n^iC;LR)2542fv`)~Y~ycs5G?n#}rS7-)&8j~g|^~SD}MjYd!I!g~n zv>g_>?k17tonPJCE`N<{RGpv)McEA$C21&19Y#^|9jr*I)NH??tk6Bx3A&P{tdkhU zah0T$YCA^Yq)DE=>e(p3b5(7^Y9sUQ=(P zqggBC5_-G!j3PAT?Yi>kz1!}QY@f@ujf{;l@#O^(;-9*7{6e}Q(yh|0gVZCr6jgv` zp-YfIPs)kuuz-vej`J^fFj5R%Rsu7K%n^me_P!iEbb% zu3B+!9o^s#kSowGo}!(ZypS2ZzN#nQHR}Ntvx*M2&mP%1YuyW2{a*tbAsx>_;Pf(F zPZiQ}!$3%Ej+Qt>gN?w?h=YBsG%#qu?%XQk#_M1ofY`Awyjw_4#MUFE@g`^n(H!gX zu}ny*p879H;|)*`q1{YT4ogU>x{j|zZ0xxQ9%sGD0vDOYhqx8&A}=n5vw@XiT^5=P z@$_ohPa4<2rHDww85r|09dzq%?1;jRdmv&6eg{QGIzccuU(4PoJmfxDY4Rpojgd<3 z9XTrF69TmzUI%6hxY6bc587U?eMF!hhZjLKL&rwZiYK`oYqOIycEaf(#qQ|Z#pcWm z67SS@(zuS^jRXq5Fie3#{&H#$Xgf-%F*vF_z$unp}GJNlEK<^tRZj*Q$3|A~( z`xl`%VkFyc@dZBZF{9uU0i(g8WIh&(4tZ);>?ii)f|JBrf;T`mtOsBaCjqSr8hFFF z3Ca!dck`}}!b@^r+6$rprOu)#FJk_pmZCUwAjdvQt#!3oM)aWS4nTb%jO-Z_Rj_&P zNwT!p)a`hi=*$dlj%L{SNE&G4SV1;4@|Yx78%`3EOw$~ObV?tN@tM$xB1!%_iIr!? zt0(C?yQCh0&fO(dFUXu#7+y71=9B+c7rycS*NumWZNz*S5|_R(vm@vOhIyoVI=BaX zPE)wwW_AUGwXc2u`sGJS@+B}0YCTa#T|}&WF)y2+zH9y+UlA~K5hGL*eYX6u>9P~c zops1yRv5Y80#~5RnVROXrKAUZ8}L4AxQgKtd&UJ| zH(8xFvn3?SN9)S({{AR26@Yr$ZMV6@ZHlE&b~9hm_UQ%U={y^rfJL?8wx?>`&K&wI zMuF4F*PL503h3Op7%ru)+OSxQ#-*s}P>@q6UQ=*b4sXD|4_l4-!!0KH9u#Z2N48-A zIAJwhPaCy5w?U(1Wg!<|*H#l8%o4K&-ch_==%NJ;0peVPXQ9(>aXM^PhjLtna%j6C{C6u4de`lk=YRao%-9=1Cj*@wH}dY$xin3QO-CC1qmrwkHf_!V9> zi^Qy_=hDiRDqFPb$gY*Oh zZq*s`B6@h1K7k(Yz~`D(-;jrBe!tTP=zuf$mhX1qr}(mzISLbk6zv<5mDRC^&Xb_=(gHYQmGU5ZT%V%~Be zH+Pr(x4BzDqA87=hFpfqtQG*$&7n>kruOt5C4qq=tRU1l&a|M`Cs9s^x#AUm%*THU-G~#f0E)EswP*D``k*2b&g8Ttq&8 z19y#*%r~V@knGXf&04L=WsS>uDnGd=*#Y6?!sYv|v+(X#pHm%&Ik8b)yTwFj=Frc! z20Tr5MJG?;-HkR$hw2cN-Es9rs}3I9e3|TqrRr&P*Z7!>%!Js~;Le(NZP5{D-F#Zo z_AjoUM9NF_EuCCdBRR(4sQuySbn59}TU}XRQ!Cpqs?lkaI19#j`c{_~Px3reKEBSA zUr|+q9ZEcf6}9NJItYPzaM>prht_`jUTNK*GM+^atwjS(DW6ao`q&fg8Btk0ZX$k$ zFsdk>gkdTdp_aUg;_>6r5qMZ_aYZ@4yCm31h-2dmLku;oPjz`s`IIuxe;8E;mzPwN z({SKcF~kSOiJjx~CRa_Vsj5IHZrS}YzpS=;T$!ZrTk6R#o>Eg?6+nVl?oTECfO6D# zN*O+dBSb1oCCiAsfqgxF`xWL5A33Do(2<@IBOe~#PckcBnj@=fv5O@-+M_eQ49R_Bk~sWq(qHi=X<(>xVXw^k8KdfnF5!I)M)fj=%ZINu|DG zJ@^6GbykCr>-5qFO2e&|Lc)Z)Kw|{9#YPw#h(~TUFLl-wdMUh##{hKozh_}LAW*6$!B{{!e zN|GGoL_RB6RNqXBKq6$CnKsZTKf5|1ddLV_s9-*MV2krC2$9!v>@*gF4PB=)2^=A^50hCc>um zmtQ{HfGs=RVy+#G&J2n9;)-^B{>{7J;$u2@j_Uvg?4KHszVh+A7wM9GDe)F}4yZJ| z4wx8&+M*S;tQi;?y`-d08R*?bQuU^D6M^oI(PYd-exwnE$ z5v^FGa2w>N#ASzDpeEcBEk`5iIU@C%U%7f>J$b!eSP)8~TQY^b`1K1QrDxx+3E3Kv z<}zi?K+xcgz4dUb9LrTN-T_Yzh)R2+AUZV%7RxE#vH09EZ`;8QfVf);=g`Tsm`IPN zLvO5oUxzb@uh-mxd5^qLe*(*9fx5?Z_SvA!;@Sl20d^Xp-vOm~oK2(vXsqPCBF1{0 zoZyJ1wR+l#Utzgg-O6kbkyOpQsq!S=TDK&H9PT=V+ z)ip3~h>}LHlRU+CQN;J-69!FC@=)9(&vDQoQkTsRwPbK=LTc#Me@tkBGhnE1qjs&@ z0m0TWvc7P)72gSe{eB&rAflBlOxa|*pdCuE-%uEaaA?t#U;g+6aR}CB9?aj z=we)qX>wIn1rmA1b;XjtPgO+~5iB(dcE&zcB_&g*$TdqR6<1Fzt*KkCF5Lg=X~fhA zO5HANt_v!iK{K|?UkWml9Fg58nZg{VPr!)3r zIW}-PY-jv}CMBE~LaH!ct0(OaiN6llv4iTB!Z5`C_W9l|jf5*sqi-_NdX+m$qmBr^ z+HvHUuZj1p`X)V{5uFxMvME`(Wjo=#1s^IRgt@_(9cj@fXKF|a=GGhJ{cOq8!R=*w zm2`_TxOAd1oM(;UT8UvL&K2h|s|_yWgM*&YNMzf}H$OZm^XrZ59oD7uq=gwHLXtF{ zT6naAAqlY|^DtmlkP5tK4TS|%J)BI5;ZfI#%{E(-!bKt+R@j(uIy}6JK z;YXXCpTUky_T>)i;_V)cGg1@&e{|W6LoyjfyuIuig+HX)yXiLKTqsm_sNNEt%WJ<+N{jqCcg_bJ5A8z5ok>&Pa$H?IG19 zZz&Rdi+GUrs9B?$Gj&ZcI132wG`=fr+!UbCH0c@}Yj-5Z*g|tXcFZPNMoaqL(k@ox zjxz}+tC|zdf)cFBsENEg&=lAZYos5T6tl|J#h{jbO69aoTgf;MNnEU2$@H56!g>b{ zQ&(4gt|d7{Ro581{-Nh=y1}(FisTYzL4dp$r3-98F>AU`=!A%HUpmX`wH&WiJKUnk z3kIE23EL(dcuQb{2UIthft7yG(^b8~36TIMK>cTgNYRpZ5l-XUGt%cvj&x(AKq7dt z5A-;OGqm`kgg)a%r#Fz8);84%ZuCPo$Ed+}C&5x9J6tx-dsEqphgAnyw>LUGDlR;v ztZ(ZF0ZckoH`v&4N%AG*k_KMIaBy@xX-BMNqxu}HH#x1Dy&aZlc`-z6TW|gJmfQo$ zg&TBObiCUY6&D@|BgR_OseLO?ttYfvuU@KbMNLuD*1%S5Q?KI8;YOtV7*xTLo7>6A zIQbtsf91fHBnG7O`wzG3>i+&8Lc)o8H#%oOU+D=(-6|(})qvz7$=E7BrK(a=kEluZ z6qHs~Pbftvd1gr7h&;(qP*IGSbQKa5%CTPJM--QoR#cQqDs(t6tsGxI8EGAoR`JK| zTUv>ky5z#Zkg`-!UOWj2nPN0B)+3a0>C}vLtTa?tmQF=tCcn0(qIk*_jAUuGWOyjA zucr{pkihA`Zl9{~(*AeX|Bi3=bjcln zeN&=R3UMn*eb88IR;p5yphwy8A6(5i4HnIl11lFv>Ih6Su)m<%i9nA zhI98bi%@$GyaR~bS-SGA`ssF}k%Cho&Jf-^-t5kknE}hmCf_UMO|;_cz+ND0q_Ak| za`K{2QZ0a!)9jIh(;fbSIdlQu(&)&|(DaK;(TdAI9F||b4|W6D>76ZFfBf+Guh>Zz zLHGkmu_JbAQHLp-4M|>em5hkaUArNb79Vd;=K9m)xfvk52bE^+-=~9VrRDE>-sX*8 zpCw%W6x;>e6y*x1r~oMWw0mU9=O4*M-4@Z)pp$0&4u%eKpKSQx{hwywBE#mz^kE=S z6mO>}K}%8AE)=xnK<|q(TYQl(TJmXo`)@diQ@xkI31C+?#S+gbRSu5a|L0GnHUhH) zd&0vH0bwG0?tJpobh~_mdmkhN7@Gt^OweR|avK>PhsvYTr6fBerr1KNfy{gN_)WRJ ziCGFMYCgOL$6ws9I4VK1w!RHau(ivosbh}U}nw%x7rXJ zrqYL$WSqAyFvcn7ATSSf3#LKgN}wf8vit|yTiHDzQ6KSGg3j}3ux`sAs{`$u*bbnL z@aT2!@DM%pkGDuWPRPg}f_7hw!{(25%8Nt-CRY4JwuxUdEaM(C3Y;dxIcyooiySZq z$a#r0*(6ue{XM^v&2*7HpjbwvqFd7&@n*u}m%9uyO5NJbr^DpIiRbs*E6Cu8=WXL| z!ADkuMC+J!AVId;Yq92cavAC2l!VLtMlciH32{MRvEcOEZCq#M^LSW3r?R95?q#0CRU0g<7UCI$VRP{^FOGfAX(r0T+B{6SOX?1x; zIXZ#!dC`MC11l>fkS4I8n%W;AQA-@8fbC59MaXjz1(u%q-RfYQ-+JEZA@ggF%lv@N| z0nyz8`Ov(QDfT)OFEJtq^*v22tq^TO@-@H&vyxs4Se#{={^U5N}c2n1FqODq8Z^PV9XgA?bI3Mq15rqE#I;IL;6+ zd)a8n5$wYx++iI!2jiVMS-5Dls8~5Wu9i4AeUO9{UiTremx(rWteV5_>@00dP7RZE z9F!2&Y70S`HIrKON%;QoH0Xr>UVgK$w{k~Fto|K4NaHQAj={P6EFz~0#=>;GM=+TU zZ-4;|l_jbSY?xlxH7L|NcagW(!A{_zxtuVlR2d~azYR6|B=bFbI`l|}L=lO%ES*2W z$S@*7j$DwfY$ZeNV%lk^pi5M-qT8bK%GqTgM)2s?IBX<6$XtZcMqAe?a{C#`fpUK4 zhA&B?wmr-p#w)2}BY8#9k_)MQ?ZnR+V1l(dkiTbOimWFRUd~ zTFJK3E&&Lmotm^MKBG(+6Uhqnu^;2Sg+0h*NQTNx-dvTV9E;Iv9VLxN+39q&+K>^Y zF{XyNwSD9#C6?Kv&@HIEK9w;%WHD}S*w+9_5@B`=6W$8an9oB>n`}Rhr-p+gxM_5( z-jW-qv-b@0yd69JIHGhncLO?86D+h4rm@5hh|ZzULHX7k9}(_0T{&Na7xg}SpRsa~ z^$4`qFR|7~Z9;f3T~o&)KfZXzXtSdlt;^C$_^ zQZM7~(TRGMKS8JV<`PSHitD)&=9q$d*tBZ-FMihlfh$=_=+ z4hOg9gErI6hkCDvpxEf)~%%J|m46xDJr))L4@o+7K^*RpRv) zQPAOAF(p_|DBAq*x6Y8+-{AJZ(b1xFln=qC_kh4kibX5xSD`NGY;%okgE`C&xEp`) z_x85$ZF1JF2mfEW$t2SVd?=rYGY$+Y#R+b3HUn*b?Ub4-bl6rpF+-4bXsa<=(H{t$Q{)I;hX-AFHIn&^W}Bi)I9+t?<$ zo@=Dfq2Fb`k!};4=%e;#?wG5IZsnC-^hLgbzQ8rm_t}}~ z^#=ML(?B0!X3{fIzc$obsMs+6L%+BLBp}%bi z)k81{@Am*aM2_j)Jkl3W>o7BqTZHs+ zaXf}#V*FR4-*E&pK&q_>-VX>?8zB=S5&OEhg?Zyo@Q#Cd+*x5JqDc^LkR~$;OuS@) zC7AwTUh}#8ss^+j{`+_L2=Z2GR-r9ImU$+9h5xU(%VW%ZK)W^s{|bV=3H^IF8g~o& z|0(qUqlk7ln1y66_t0GMk}pQT8)V7l`E-)`Aew=NTr>JxIiD+>&!x=g^z%90e6Gtv zZpeJDYCbm)wQWYfuh8!<>iY(I_Y?Gc57A~bg82{hTZqQ_5{)+pjr|e&y@K#qjqq85 z@cIq?eG}pSIl}u_^!otqg+I`I&ZD_~hvxVmn(HfQKL4N>a<3q~HzPRjqQCRlh1|F3 z?l`#-_^7Qwru!21C0-IHh!&o@#hU5)6!P3UnG8mrDtu6TJd`*kAFBxNo@y+`sIoP2EWPU;2;!zoEYWVi3rg^iMSU)1*LdL_M37o@g}G z`!@t}t++0{`-DS^nTQ51^W9dVl{6H^SS+Ka(H6f(WL%BlRHl)HWQ80 z@L*y;YRSa@sR>0EgKi|qo&i*#=Uc*`ND!RTe?{OcegPrD8<-5jGVxp3gjQhzTG<8M zJoN9o^a5@PyG(qKSt@=_FBAU=qrP_i&(xZU{?0+q-Vv$bdZ8(hY2o#6Ak+HXIG+pr zTVA^c`fEhtU&RN|KW5QC8|W2Q^yhz`%CBe|pJ9(rL;ZQb{ns&m;s0X> zK@tY`$2%e-fUtlI5a$*2dyiej{R0tOK&QKd=>pxqZOS+H_@L7 z7r9^olt@Xt_jm5t_jH;@j7rriu^pru_@!50d+nV@lBM|i4F2{d`q77nr6%cQ*YOQY z*RH^g(US3gBVYe5ZSp)Sk}l5RXZ%RV(>OE& zM_-=#eI5Z3DH*rT;#uqi!H`sVhzAx3|j`4 zfZ@ILI%r}eA~PwTQ;qEB)mdpZueE4@1i+GzW#KIrRd++b$ON0t1T6ZnXx~W9lUz1y zwE0bH9~TBh6-;7mPo4on67LgC9*t>OR94K0Nne0W-*);43^Qbjn}K=+|1gYV8sHsx z3EYG0;APN)w3goiwsqfveVD(~+hwQ4ou}vgx_l-HqDR#H;R2l%VGPgq7-WYS8vCpL zwzc^UnOfRSGx@_8Xq!s!u&OoApwG;uZE}|c$=)%GpK+Ov%5DesAUdm8g4$3%P-WC9 zA)ENPw_%@5+J~gB3SlGSBYF(1`wHv>AH%}efidRs&A^@6bznw%qAgLE%XejpoY}7R zpn80ES9=e$e7tp#gY@d_I}g2u@K2K>HZ}9N{z)4P%`bW?EM)~bO8`9wBn_Jo{x^0t z81>g+)tuE|f4gVeY<#bvYo5pN`JT>u1w1jTpyxx`!P}pozmoezNygu2^Sdw84u79y zNhfhy)4=p#Zpnq8tW|cB_S_u)==Zc=<#`+(f5!%6=q|NC=u$tIzw;gKv0B^_7Hf!0 z*oNJKEp0nGkH2%7&h_fnfeDXg>eGt`57G*1rQqjpYi|cYZJWz){GMiXu|`%K6_OR{ z%u2aStYlg=kH2-5P7%!`vsKRO3HGG@AP3a;fz}+N82r3&E?Ie>q&+;3Z@fzP;I&2F z1`A#$6{x8~3QM~*$fBNN3GKyK^rp@QuE+Q4R5Iz3<_jA))EAi81^ZA3{qNg>u z#>lj_r{At5dwD*8_5!U{tF#)Gk`0x@NPn@ReWgO=3-kGo3$!GOlE_P{V3+sbk-H>G z_Sp;hUH_yFQ8vJ9MBrd_Hd=%O89oiFNvI1}U%r1;#@#A$$6w3L(|PX6<;;W%*Lftbo}Cp()^5Prlm^Nte2x zf#j^NDygbTnowF8j}?ws%a`*zpa=O?NC}%z zDjE7z6px!&Qd?a~!r7iLo+^dskz5kvJwuAC%Zb^nc05k@fK6`*s$&EKRp!Yro;103 z3O1ol#JX8tb!oBW98)}{ru6w@9JWRhUX!#xg%vm#YWSaC8(lu79BFGY51=}UKNXI7 zn@AGV^+iC-rh58TjhiTGu$}JN+VYxWq}ENX`@>cE$&H))t`9F+%S*5E+fojE1M^>n z`Hm;J0?iYXbboWs0?qIe%{<{B_QHsv31!|kP`wiLf5sTO0@&XIeYb;s@GbhutQkOj zA%6Vew7#|{D+X@@1KL6Ci&?q7M%0cx4-yx`@teUjeI^^8dm^JaGqbGVg{-n{ZRKOu zih;?`7cB(+#~cTvnn6T8h}{QxrpSoH9u zm+0~8k%N-U1|0wyy$hXnU2>j{oy2_udcF_x3*4`O&EO62OmPROE!z&*e}W-z!)Mom zA+?YA*kV@$cBY!2{T0-0aKfq!LsKJ!$3IX4Hc z2D9i_;ZGp%eW=|Jn3+=S0u087C$)iZ#-j9&%1F9$D!HZT*scm$OF z#Wlrn5|sZ65?%-TcR)n>$WgJ+GP8hhA$V#gm;;~x7QP4OAwc8b0hK*x1Jf1|Q}!`f z2EGA(=0VRZFk&r;{0)2srgr})^AWcn1fE<49$5sU z*8^@bU{?XdGuDxPQ;N6}W*^Aw>L`hMq3QytjeZ|UnU*8qvG2fant8E&HuxMI1@9x! zN5C`lK=#|fyaYHV6nqS(Oi<4Owhds&*ynrI4m$%Tyb4O+2IKNxqkn|2fl)S9K}K{t zcw{NaXa;7qAr^tyk`YINdl$$)%h;}g{Jo%O%^P4H_}e2-u~og!gCUb@J_7E)Jw6jX ztEhOv{Ng&GIt=zAaxa5hz;Q6X4Zw{cF0FgUvzA%FlV29M5%@onTD4W&%4Oq|5^&3l6|XA1fN4Tut@uHM-Y}e2Kpmy!6r*@WKzE zvL5sX&bL8o104P(KvKCS|MBd7z}W;HBm2=qdOjLC2WWPJhepf-slUK8pj-DGVC=*E2;P$Y>o@=3 zclv+d>HmGF|G)fB!#Sh~R zoXu|WYI60}h8Obg0p1wqEgclpgwCv3@$D;Xh%$aUwmHf@(MTDk{*TLzpVoi<&ZW1A z25=#^bsy9_`%*5mwvS6ME9;l)KRmKy1wPxGcf>b&X`krusbbXOZi_3-=u;|=e81of z0TLmpXUAQPd2D!?XY4R{L@=H4D_<>Khdabbh68bj_QMen{3Vxy8DEz4uP{ie$ZoG+}SUnB|h6_j>`-SX1MrjkK6-k8Y|$a#xpt#EBN#f>Vg5>pML-AQj80l$o;s>`=O2F>~>lyib{0TOUu7_ zOX+bv?$kaAl3f&)HGbJsrOwYk`v;z@rWb7GHH;EDG;lU-hI2Hgm{gnUb1G`-*U?J7{xLyBFHxa%0y z4Gr&~nqo*+=fq9}$&Yn?GP_3)^V5`9u$v_}mByxl0U>X1*xC5X>Xo1*U5YrE+-5`qP6lh%kvil+?5jju;XOf1ljg2BbH@(xk0l!XD+` z^g&sPzFf;LV5$UVnhb;10g?>iTpV5M9m0>&j?ns?;gTb9Sl_WPRTYkUWZd|%Bh#CJ zX1x0>7?2a&cWBqdr-cefpCnJZJ1;(b0Nnz7&spk0l*=?AYCu8mxag@Vqts(yfjKog zskbjN&feYcOEWbC%Tmy#5B((bjCr#6xgNP0DY@BQ>%k+H$Czq=a-mvtkCJPrPKio^lJr+WhtTqJ zC1QV@3GM7b=!3-i@6Vs_-TLK9Vk&hg}(5mW5#esMs zNqzLqqr3lJe{|Q;wxb{6*n6xYPx16YdTxzmm*b5Bkw%Xek1Ip^aYb#3gmd;*PsFY% z#W-C&={0&_NRPU^s=_0$Z`<%PC|L)j*Fc+Ud8%VGpkD^&hhno9fOkR4!06K6UqJWR z*hwXygT8;OcpW_R4siFh_Y_h=f+i|Fq2I7!Lq>ET6O&+=WEn$0%MIhZ>3YWW8#v-0 zAacl4{|4z(e+7TQ%)cbe1g5ESNh|#*eV6!gi@=Yd>m*|W(~}-+7^6wZ|7%=aLHB=v z)gUkZS0sshbxY6eRUSDaB!!ObXvodxE}EWCNej8;KY#uF`l*QGs%Gwb}@TV|6DzN0)7SlGUgRf{H*jSLriGSLHK@s)_d4b1s6VIuUIm> zcFjmjP0b3{+go|(n^`}SIEps*reSp4<1uQWWh6;3>z4u6s8P=cy_F;v?>2O{k;<3t z>>_7QnA*uRl36D}eWp|8u&b1!-J}L@=kEk+1Wxh2*Zg>#HF<2JMNU$rr3kxj{b+4R z9rl(y#ctJ#k1&r&vlXM=j@4uwv&0=^FYAU5QnFsGB2ObE%}w^4zFMq(4d9w$WTG4n zJh{*mnCNt_$;osz0y^D5g;cg$^2eMX@fHXN88 z+RSqNHFh0p{)rF=`{Z%Wc6G9w*Cd4rAw_O)l6C}r6L;MBOp=nJ@@)bgm#X9r+12B- zSygG45Uj{{;5vB=jlP3BWrf~c7DQ+$N{oO|GQeOR=+2)5{myZ>94R{I@EEmVwFrEe znzhMkAecx@@QWX}zecdU&9$2teIifm5`?vfX9_gk*zcTf!E9j z9dk;~42$ScvSi9pdRGZ8k$hhxbvk{c_$aEEAvLD&)g;#K#_j1aQb*1tx?iB%B65#J+176HqAwX8D^~p)Bd1u=j_1Ki<-I4 z*uZFW15bDB_Bw}0D{#*R;GWPebqzFTP=8YN%3W-1g_Mn$ToWL^UK33R$^)ObgK>X89gz^~ve9OAZU z|HgG;ql8pv_vBu^yY%pRBaD$$l4?xEDr@7tE`pEb zY(|aSz=nI(kk_>*CuNc@ZJoHjb`LFvi-$$6s_at(!I9VI&*wrs3l@D0wKW7b^Nj+iBHh5H+0b-oc zrMLTY;FpABzeAA4!8LFi590a*7~c&E-@m#c@Wutst(0Tm8uS+m?8It!jt*1nW761d)PRR>< zXvTwNeXcp#ll($G$QbF558ln4x_f5Ebx`t@RJg-@d@;-)mf8S%W({P!WuyB1~A-SXoSV4SoWbr&uoVANqp{|h>*|;27+iT2vJ~zSY>7Hl{ zNix}Tf(&Doge~kH4i1SdRg#iEcyB8^gHP#Vx2L99WT#4jBsbUSLA+l}FGf z3yFIBAdnm~Lj966cm&MAg;wZzO!;nKBX~tiCW4n*$kjil?GI9(%v-lv-iv--I}x&_RyOKb=R4ZG=Eqj%h5dtJ1)s&k(%hCk9Er!GBzib zw3Don9iIi-FG|-yhR2ti86MqBZYQUU4$|ITioK|6YK7Xat^>g3bn0gSy~}t4`{fTx z%ZPQ2c3%K#8M;J6PPY)8FU%)1Hc8@E?YU)0%b(CwmKZDWM5LAajwSFlAThBy(1ag1 z;zF8{OLcb^!8F!y;F1{LENUNC8KiJYgIKT_W6-EnQK2+_W#gYk}Cy1VgIC)noG2nI+?h=gTK~p2wL8`c_p;E-SB`QuhzBu;F)HrZrXa?&U5+ zOKgHYpBked>+f!USf8&-Pz~$eYi!I@j&w_;&ll=#OscV-13y3^JB?+#r3)e7>xwl> zLB)Ew6lAEZLo>CehlBp1joSn5o8SVP$??-{R%A#a-?l@a|64A(HJ3gJ3V9}8MKPWT z21NK6R{o&Xgvg&a;R>Z*Nxz8RO(!~xZcz}l5$3R@V9uPj#y}O*8}wp2#bC}()f+N{ zHl5Z>q;f18tCeY_t;s2tm{AU-4X7BcTa=UgnXQ=IhXXjBV`hWs$HF8{BvO>a^sE?W z=0l1PH8&~aU1x4Wtv6Pui;U6-+b_HonENVrBTP1#6O+uQgdjdge`yRedf${_>RvU!I@fuG3V0 zSBf&HQB-yWMa9_wRkKkn~%$f)Ppb^0&f<8kwGM{ZU5?bIg0zb z&;kR8td)xh>gZ{+cnjb(hWKgAp=&>HBj5f_VJ`?Ay_!24l)j6^RUlI7Tfc|&MVx51 zcoYK9Dj>m#w}5g)nD|!mtJ^(|qx9)hK43Ey<8%11TBng+b zc>Aqi-`8PC`@}=w0Wl5-;2$86l&5>iQ%qRt6dYvNWj|!Y-t~ccF0Fs;Y2QFBcDtne zFbB?;4Snlp-hO$F3rnVJ(q1?nysUt0Tt?6}N$g_Pi=*R}^Xr_zd|Ol-L5fo$?LLCJ zS5mK2wbNZwJig2>5&j(dWo2h!6{cn1{tYDXl)IzqgpWO~4DxAUu^Z8`rKnPQ`Z0Nm zP+F|+pu3J3nJGW-m`g^tOH!x$9vG8bRyR0Rnfofzf@pVEeHqHMJGf+xLc1T-bLl|O zj$iQRsOuwXhKw7EUA2n?2?|S#J)_G@pZAb}8409Gmcr_)$)(jbQ;AVzI4(C@RXs)G zaj1S_ZAsl_zVPQi+Rl|B8cA)Sla6V z`L>uCQ+FmkBcZo2+3!g~r`_y6FcNdD6|*`yL4a(Oo`pj)|ubmi%r z0W_A<%eYvNqSb5&ps|(iWa9%*=aD7c!M1bx3Ypt(f39>q%QkV*F8S$!MFe6ew~9+i zRCd%^GJ2LVYKydhWq67eX`S#fSO;{1ff|#kVO1P&t_P!cfz6<63^C*ltHdw9b7mch zvt_pmqovU@v{T35d-FQp<9xgD|JZxe_^67kVZ2Y>z53qU`@W>p>8xZU2_b~ALqKGS z2#CmFf`FirAfN+`;{-&A$Y4aohzv$Vh=_=YkU_)<4n_b_K(D_Q3?&hvkt_w)PZ`I29!mQ!_WIp@?_YhfSL%QznAwvl43?KN=(o@9)CVVwbB zmo(5i*;vtk(n5{zTZ+$fik;^LIq1e_o);yK!-~tniDoGg6S3ptpI5)lP{>lLY(Q@K zF%G#I7sLyjexij@yY(hMjzUpZ#-b`%lSwR!;YM2Q_D|?y5NJ3{ooJlcpJ~T1wjNW; z>%k_9-oqfU|77}>!g%^BeRh=|WMiB85MpwSJ=qxtb;vw|H7;uF6$&bZ%_q&1#FAox z>)EplZEgR)kt|clZeA^q?J4RFbYw?n*ReZ(P%fA?roh<1x_9COZImC47oOh~Z@NWZ ziFl*5;q7?SQ*w2@@LJO?sPa<88;GXqt$5Q0WjdQ{4E5SAsLD-0N>wQBjZn~uwxDn~qz zE*dE4<+tB8#$C=HN3lqpkh%#0U&WrJXp(SS*Ehboewj)d9%2`x!gK?vFQ?-)vdt)d z&l}dzqCKoemyOxfucbvRxUCSs`q!SMMaS5ykR5Neo)%qXk3qHptA4|+j&W>OzeyjF zt539Qa!;{hZVxvr+gP{yEoA=u5v~KpKfmqzm4@Xy$H47FF=Of4uEk3?@q188$SA!^ zOGz$8{yK8H?5e|U>*By$|NKv{%+n>2Hy|Uv3s>TxPVrYE)d1CUIbM2%Z%%AaCoRpz zfi|H5h80`f{R=*UI+PyrhHTQ91-JFA{-bs-`dej6iO1t zYsC&Ucw9lxvLS}NRL^P9a_0N1&kz$tmNY0p+d)q#yyq`(-28?{PunP-f@nA`GdYx+ zm3W7C{AIH?nn(K*X&X$NMZ^12(c5VXuRHeE<5eIy9oPkm!Z<{SU2>Z2D(j99PeVbF zDK!0^b|I)t0H zn2arr@=g>^ZG>6~q`d-v(7A2;LimEh4%y`*HyGcwm=YXjX&73uJ?z}mAaAQ4i{p(7_%Ui$x z^)sr#*$+q2hj1ObMin-Z93hjhFk=RG?|a9f0^P@*C2RJ}mksZSiCT6WTx150%ZLmZ zpPp38yl(_iC+Fp@O|>_}#LJC9&T^*75!TBk9#5!p+4@UOFVZ9em!XrX9+O$};OMMg zx^9=~@Xznx|Lr*PGG2@>GWm~qxsPBu45^2|z@LCfYte`z$`~%&N(M^D)`QGtwxVjc zhU)rFZi1y?2wexFpzc%H`u4v&f<#5S32kF4M?5w$A(dq-o4)$#^_4Ws;8pG-T7>qa zyQe=qCox~H@^jF`WFBFMm!y~6-Yctz@xiQ~kNV~1E&mQ{M*$x~oruh}ysV4nMyUMp zo3;Z{jVa_$qMdBTgYm(&v;OU0$k4rT>Kr??nJHd(E9lboJ3V0>-%ndRFuRj!&{|(77j5zTv`|CAdziz9i@aQUy@i%)yLys2#CV;u#br~} zQgkpL0Z*y?fbP52?;^9o=%-d*Z>1xX2N3%abBE!reg5p0r`J%KRvUK&{eGPx(`q|M zi)p0HwWv5N5G_pirzB)OEpNA<9Y^kK9e0Ik24eM1ma+NowQJf4pP6)tUyB;x(M7NW zI4)pLf{^I5-+dbjY|t*C-$a#1ZkiY4Gjfdk+jI7crW2?ZRpb|zPO2DQ^fH_TkF~J) z1GE#S75xP7!dm8e_FY&8OW;-g@TnxP;{K%_XBYj-Ov%GZ7lljcNoav|AqRC&792S6 zz#_0pPTnua!ujeg+x6`oTeQi0vDnG2VjDEbiJEUoO>dml#CLFEG0X(bZigCRLtIGl zxf}s=h1e_F51uUWgV;qE2`PfIZaO1Ejz7Nt7zx# z$jLY*t0Ft7Fxny66vbiIejs{Ds7AN#EL}rwdRv9-=xNxNm|n|2$OswOeTcuxN<5>A zsvThtDMU}sb%D|T4TV9p1R4qEN{vJQS6b@B;xUaj?O@tbBBVn@>p#Av7V~HLrCgbD zD>}cV9kgw(6%MoY@PV<-9r`w>V&?^M3!7#4^-Wepo5+eTMKD5e(d340C&+wB9!POD zW3gsLRaeUX$jsDV6{g%`34&t-(^sdrK;x|k~GlcJ~nKxtF6rz6r@BQgha{=}y z;OiyvNSioBKI*nva~~lIQ;Z;|+40(3jBlSdYu19u*lE+|V$002Lr0UDYA|NatE$Gb zVe3wVrY`&rSA4qmQr$kHT(;PcAX~<$D9goEHR<8*dO#8r+!DztC7al^V&vqUigi%r zRGo1~DNG^pr-GEg*1keMT$|@&n2uc`Me>H_Qf3zdW6{~lmSb-}Od8Bz z$BGUcCphhVDRTvZ!Gm#?9d&;s&stRdcqzK7Cxkt7@Z|%w0YY$B!bgl>Rl+_+?GiJ) zb?v{Y5U38;XryWpP#SuD$$`)6NRD#zT38rXm0*%$?Xn5AUmSShzer>mz8;EK!{7p8 z*r3hmO~jR=@nb2yT=rGx*)4?3o10*=7YlBm89Ta!VAyDE)Lz)Y*wT!ck#D~6{%$?; zqDE}I+VOFK*d<(1iC63e$K2%^2w9#RYT#BCnl ziWgsl6Kt<_aTK?jo(ydo?XZo*NH48lLrb-(A4RiF;S7^0l&&XprL*XKYmI(9Pa&_D z<-#70*8_CZ4{Ld!)JCx76zZEM3tBB}wlKUNKAh(LsNG9iknHcM9_%rn)sYgk=oyqL zC%er6znBTyF*)F>0iI&h4@qq@wytFM0JbWk>Nbn6RId(z=523y!+>AMtOU`SW|M3w z)_8_s4gM|z{t9LS6Z0ZA#RG}y*X|*;4#MVW>^Is>NZzV{pZ`~VHi6j4Yy;Kpx0xLQ z10qd!u|prw+{TQzf*f^-LV9ASn~u><(|WgQAZ2HU$LvV=b_vY3)0od$W>{AFqeC-? zJTi>xMXWRz+lAFytsOJxnd(yXPx1k)KK|(2r&Ln5nw=1z;)RHQ4=OeSQ zn=0HRQfv_WMXV8A8M3i6JT;neyNC z@(aI_E8h9_(%<&dSHU`13@;Hb;J>{J9GJ^G2obMA8vpX*n|p{>z%lG7>R(dSJKz(r z$Hif@IW^m0k$Iv%=-Acv7lsh-X4nrSN_!2zy^lW$i?T)Fh$>H8d3%t)Om{D337ftY ztwY`O`;3iKVS=Gwcy_hAw#ub2)Cfk4Dm!*wd6K2UL(p+3>fO7ru&k^|x9K%WdXUK-q(vHbtw;Nq zm}lM}!LC?2H*1#I$S z5lC8f3s(zPi`}Z&9kwnhZt7ldB5`Mg^TPN)p|dD)a+S*F#x4K#91WCsfon6u=Bbru zR>W7NmhS+4RV|elmebNCthVvmu^zV(7WSL)D*TR~GA|XW?mWGDK5?SF$uB|c;IWoxLn z$eh0q))|70#V`t zDoTdTyrbtZJ+6{UL*jR~P{2OSUr;uos=EuAdq{M(@ialkdD59EP}Kb>6wpgs*VEEe zyK}#K9p?WLc*&%gIZ1q^0aTgFn`1;p(z;1o>V+RNSgDv+J@dY*IFtI{nQU8EL5Qv$ z3I88O8X6umZSK4(!jjJWpILDmL9-OK5&_Dvn(ApdOrlRtqx|TQTqE9b&1|hCGO&8; z{khmbMw{2%8IhqikIZ>!+B^+j%~WlqyR;5CFl^ewnGepanxS#iQ>WI7z8bCl>_@7r=KNn?51HDOv{G#i2G4wS zCIJ{3^3ZJU%`t77wuaTT>DKqh?@jdGVQ`#JxnH1f7N&-?^S2-CLtb|qqBUJ zmkN?O+&%G<`@CdIG0t4d-Qey)3TwuKoOc9}EXo>bVP%udU`{m4cZkXMkk{uoIIs4W z?=O)g$8rN(CvcTX!2TwxTa7Zr?xAxEsoTJI@=4~%-BCGtqJBN-g?^0KudZaB`La1X zN5VN>tV}Ydbi?7be2X|FbL0T+ZSCRjwcn?D?6#7W-1MTMStGNJygk=;Zs?px#@NLj z=ZpF#2MhZ|1BqPOyLnQ#g*(EPrP{;2(u~xYG=bR5LrC3aZXHL=aPsm!UCeOK&mjzT z8-IzLJoxtM_Y4|7trSg6)_@X$+Oj2jhFJa_qq5fS3S%iq#J*@;NftSb)q0_wt+v`0 z!-E$4BG9{If)+lYkpg_%rG+()JiePd*`G4pHno)BAxw+u`05@W^&}_z&LX++{FuWbZ+o1Gz-kgl8b=i(33H zX8}7)bu$_498**n4(g|5%jr}tpWdC^&q&x%{$8mCyac4`Q@v#2k9yu5^u78 zmT`Lkc@nIC)8bb(=pM{>hOXLn}lSd78 zPG3HG#80F%=cH|nB#s^nBZ5UmPWE@Pp;C%Xp!q9(B!=YfpXoR~ab%5j46%}ST^P(_ zk;UYuNW7$x4(%x@namoUqF-ka*3B1aM>iI?OZ!k!P4R6;H2gnb`g*M{t&`S(BO}@3 z%p`%bj+`-bA?|% zC*AFs?Zi6`jsE4+>ps7z5KgznyqD>31w7WNl-}ntnRCo)PukTX@ zC~=g$485GXVU9}1?)b_0@>-=1WvPymOvTwHKx69_Qk`oLHmEC5SXI3!U#OHs3osJg zCH0V!u!&_T73BkjfFD2o$&auwqA}`vtj#$!b7xPxZ=QzCr%lIFMfD>O(X=$gAnJv+ z6iL_M=?A4wCdBsR`Y4jwWa+yZ7{v@0HaS*RIi>!2>F~|xDLY&Pz9?cZ&bM*^HHm5U0`m{3jAWgp2=logHM??RO?DQf|EH4y= zp$VI60_B;AY@{8NARxlS_pEtzSW-daUM7A;`Wpxz@jvJ^>Pb|2pJGx)0AuD!47- z^3nP_QD9it2%8wU$jDaK981?8Ci<8%O=tT4-|1;<5mrGU8Vv@MlDnj2KL5>$qj!@{ zSScMvMbRPEA%~lfb`fFa4S|R35E=uu4jhHo*n|+_&qI$d(VpdN;-}uQ}zRqllSRL8P7I!zAjF8GMn!hGPlYrQ`1?g!? zQ00cjKOJ6?M3jGP)eR`%cZeaRFt4GvyJTv3=K6OAW;kN5WwPz&U^j;$^`pe1?LD%d z+RL!hya7lkal$>k@buERiLQlTE$;xoVKB7pk4E7h`6EcXO)va)rBQfBJ`T~Ldf|`t zMq!dd& zTvl&62N}tBZ+gT?h(u3Z{g>M07Up2fSdI0qsji9)nLm4u#{FXJfH_sat$I+GSkEN( zP~w=G^9WzRVBr~a#aqih{%{{TtY-HqCfn`G?&i|YgdTxZOejAm9%H-vY|(tbGua5h zu8SddQ#stIC5+#iSst)t4@n&J^Y33gO*lLA@D1#Q60?0=FKp5J#;w~nlkh$M$0tO* zvSn6bxp!(rl@4Pw>)~2IxHOxHAjY55$ioiC-7Vo@mV$I2D1xf$ zmwkJhsOFi8Eo>=T1$t(`e>86Vl^hjj{_$J+Db{{R3p26z2xBTQyLbL;8em^u=^a5O zqo!hcpJB=PX^<1|X|D3?=eK`M6OY!TRcLHp_K+#R zzojm!-+u13H>q9fQFH+nrOB3}j2?rhjm#)4WsZ`^u`@=F^Iq)(Npe24o|!(1_1-VS zLv#j|!h^``LmKE_8IVF`@7FO)2JOsUqSy9d#>Np?b7|D%0G zE)J7J;`EjFR$NRbO6EMN0gWk8hmPm0y!C-mx0dqS_D?&gT}M5;l9@Wh zwv?-!xg?=>Y*vy(B%sowYnm4yo2{71s!(6CuL3$Ga`%>X@vc zCz=`XChKL+e5x08vulZ%pEgu;zBh*;eV2Gkqc3$|BShuZQAh1w5iUgAgj^Ev-*l|Ed^nMd@+ zSPYkyha7oqVAQ=%u7J1RIaEmMGc;JrtS0EBa1<5feZHUW9SKX%T`;VfrOFepuYB<{ z8#TY=8^PLFAFTal;}evF(%8>6Myh*p_h35i5TrdGoQqMC#eHx&%AG1WKc~m7DmpTH8V1D8urt?*F)#jJUWer^rgloMksin zA)_8sQ!|ew?wCF;GPH_B7+!#-VUOJR;9Mfpz*tvbQma4W>zF^*dsLj zlv%IVMG@{XRn@a+M8-x&r_Ul$hzHd?G`o7*eC!)pHE(9s{+)9pQx-(#&6pOMOD0XY z+l95b;=uK-*RR2pe4H}kJa{8E89?HB(dX_yNaO^;u81uR5{N#9 z6%x@3cN613G-X~XS`A~^0#h+m?rFJn{hKU8rZ>S2C^2laK6vB(26D&wW3UZ*4Rf{6 zUpER@aZ>=NpcbzR(&@9(74PZ+sVXa_jzz%ffQsQt>zyQv|wa8bAc z)<&bp3#WBB>=JQ1==OG~a?j}l7gs5yZKHS<)Qv{lUr!lh?iVkCb)`}I%Sog3f_M?s z-b^E+dS1V0*hV7q& zxIPKT-qW9G(1>4_c{}7Y$e)M6Q;MEo49}O{8&|I_CcQ73H!xhk9K`m|*A3Vh@{-v6 zvDP~q2RqG;$jcyE1~Eg?-o+jk%n}mPwf9MvL^q!w(Z6=FywAvw!B#Hc|MKhF*J_;9 zA$h*qHwPi$(n3Rd zZk1Odq{wE~B#W%dsEVk7Bmoz1PQ?*#U0r9>XtmTVn+BH#i`D+OQ2(+^>nL74Bp*V; z;J9-+1@6S+L3tx$(?$q-`R<>zwr-5u<)x^vtHc)$>E)ZRXyqDdUaRcWNb`@nSMZkQ z%eQG?nt~l0)EVO72!p)EoG>!Pg3{AC5;PC<-`3d{E(UBHR6VUqH+(R{s$+g|%_CK_ zrr{uwFpsRMnM1Q;=r()V5rc)r77Yi_t(sYVtH4E@Q*($pBwdFg+)f%jb-~=Z(-sh( zciPmMx;XaEM;>~Jh^4Evcl-f!#m`@DIX*+$6|$&n|O4Q>1NIaW4ct61S`2V=Av9kq?+wG}UCv zzt3dKOGNFj|0Q0(hg}ZCI5z(_9`X`?JHibXA)e39MUQ*Hi5S!p6S=Vqp%BcYBN5?7J6)qjkSq|qf-5fNs=6W z3jYW;#RJ{!Hml+my!zsv|MxLt(OQJcDPh4|6%sv(MQOS~VP;_Wad8`nqG}o3*W*u3 zHiLwd0)FFBD^Tq$ZK*BKM;fBfb!OnM>e_2| z!;iFocbv2sUqA|H0h`FE$Qj5eG;w18e6w1T}6T!)#1dBFQx0 z;+VKU@!#LlDJEMhwHcQJRW7f+`qq~bz1I>3vNI6smJVIs{ViYo+B#=EE6TeuZ}-!3g=(d^z6#jC7RsMBH|7lFOC|vUKew+Fzsb$E00g zippj7A_g1gbov=h#`0Rc7WxkB7V9%KJB2894O>;FvSH2Yb6ZHj8}D+g?UP^R?TF_P z2R?x_gINSNA$e}NL8n5!MCO$lj7MYZF+&=B5Z`32)RUd6uwQ<6+b)K1Sx4d|7E=r8Eb}sCJ&QXPUit zd3nz6G*CD>~~@75h1k0~9D$|5c-3gM7;D-~)pL!2+ESbr;Nw{Q}+>k?Ix(Yjhk z)m2!kn5Lm>%HCSaiDGWxBibJwb*qDFX5BaAmVOWW2UX3US2c4M&A3`ane7=G2TfS! zg^SD;-yJ$d@*O2(yGhJFhmN2@%2)7ra4PrzUZghq+*Ctmk!ufZU~a-WKwit#2feb% zy$Bvl=05}3=xusC4kUx(V5QJY%+DA&@$uA1C-7Wn<=!<*`LS=aD4xlw2Lsu!{4B zWhEnuvJgx&V{arU+G}*SAyAPpMI6t3-9gQ5tT$}UjALN0;mH-!#NXU8zo#*yzbxj7 zVZ?Ro28f!~f+TFwQ1(c}yZ}}HdV_RNvpcWZ8u&P%7L{aHm+u5MDM2=3+NhaX-;qH^~-v-@^xv{RGF}a=E z@C7(}-Lr=6HX*rm=6Xo>V2i+1J`F62^l(W29!_i}iFXLh?0#gA{&kk8ytDfwuv@HF zi`8c75}Ts)ELl0>jJp{nEe0Loy|r!S*>Pl+2i;c~*5PIur;ADSx%MqdgQ*;H*CIY> z4=$_)XRM3LZ|RFKK2DwjXWVCz-2_gz2_mV0x+e@GI>?|NjF)=OKsG-xoQn7rx>Sk*UQMP^1PL5?Bj%@ebfS7DzoIGe;hKaHBz&m*p;}(_d z-=?a%$B2zk_u5W+ZZ>(=GTQkR&B!Dr$m6x2&(b4z$#W5v6oeu@x(AaIT8^emWH+o^ zylcTKD^{#A+8&2rZ$Q)DwOyurxyyS7R9BW)@n-rGF7ll}(aLu34#w|vg?%=6m!!kj zF3?$R@STSd4xD|P-JF?-ZPtLO}G`}O5 z8c4*AZ{PGRvGtPI`}Z)ev^1|bHQkfw+i*4$YpTEx{}QaieK9aU4;37hj0MI} zKH7%)QCAtuyN1od$N!9xU;S8QyrYe$A4S9c(R&41vH~ zRQPz-(#ZG+rmDUHX?h4mDsO(~?;U!Qt7F!KOuofm(cS79ok#=Fu5Ig3T-Kl9&J8pxu&g z*muI-$b`luMS8naIew^n=sLK6qP4*8wkF!1KJ@DPzmmM^c#mxZ>&^}4dLxGP@0y0; z(y{l7t(|3ayetx;EQl%sCpIzu(Ne;3s{JZG%MFhGOnOnk5zb_hDEaLP3yrpG!6`nh z);cb8Q^sw9_rV)*rt0H&d>JI64!1atp@?157&pl+ab{X8ip$Vb!lGfQ2oI=-frCme^FXpb~^a&f9FVPnz!4F!M6v6GE;mqo;Aw1)9o(@VP< z!Sji&Me7MV|3+sg;|+0~C`J598NM#8L&K?{#=^&LI?tklh@kSU*)4Da7FofX>_VKx z@e;?_LmY#ZF3k67dJUUgds&Cm>9pHyT`UA@zo9hJ+Th;7cp`lYW8Gq5v+CDTtAli} z{|Ei7o$f|fb=YOaY3q_-zU5h}VcqLK&-#cXdTLMtyzOkV-5!bBY)J_&zu{XtlJl(h0;7cchONnp#-t}(w1*-S_Y@$G z@med5JRSC3Vv?t%j!7voJa%5({Ctc6-{(7lJQ<}CcWTe%E|xL|+Fs(ngd7>gVXd|c zF{%5jUc1hJkn#A#L9Z{=#n8S*o7h6r!g^e>d+A|<7Bg@_JgT8ZvxXAM>tO=J43Guz znN84r9Ggf?Ya-ge{wHCQ#SjqwXU!ri$Sc1A#X?Xt#B}Ifo zh4OO!Nvy$Vej#lfSbVe-Z9tB=KY7#H7{R;s=p2fBNOxSIMGeeJgp5dLwco`w?%sb% zGW``c!3AhSr{E)$Vae>%0h=M^t+SO#Ch@1_{q_SVfjbzaoo zFvSD&GI|Wi*UigKGy`qR8+FCx(RdEm8A@eS<>jY-JwQcea=rO7iUrC>r38DAOc2ug z^#f_*c4gtW&;-uX@#`U&9mz^~AuU^dg#M!uB50dfnJ;T576$1eT{q(++oaO$W7)YljJhQU$xJD{^W<` zalr3W8_?*eVY2!lAw^4eyf>fVzt!qRgn_X|CDzV@b6Ae*(oG@cDEX8Z2NL_2Yw8I! zJjbnJdAomHi6tO1o|J@*{jXpD^bwUhud#F(=FF&a|C03^R}c-dT{?8Y<0x~HfM4dPnPM%#3b1iKlnNzxCRWJg1P`=8d?lo={@gmR}6Wo;oHYIT%Tg2D$_!>-<@- z-K#OJ0l(Yr_c^+pA}`1oGdJY^r=Uvx-P9MY(tBw1e<1V~#O|7szLvR@{}#OoKQnKmXSoMcepiN9v3JjT z7q&4ekG{h!h8H0HNeFi(>mj=h0_z~`CG2^%M)5X%jQYg=r3JS}s z#@?6l8HAqz`EJ{w?ydo-Dr>Z3C>}TROZXOTMo&V|L5rZrGQ_?Lsd>Ga-f6y!2gL($ z`*-Locor@A621lvG4=fIyYMQEb}fRz_fGJQ!BfM7XHOV2Hg~?g9;P%xWmYXrE*~{) zHI(dyJ+KqbqZYIjGTKqr1O7&MAY9^afY44@1RWZ%HSjJ>+KpzshO$nhzV{Ukec%I_ z`~;-mYrn1Fb+EjRUewUE4n>%~o zq5cIN&%`*`unR#6+|bTfTDxY_pxC`<<4PzJ!F0a zdHJ6~$ugMuG4y?v*$2N5evho*A@~72zTQLdkg^|;<$Xwh6YhN#9=_XryWJMt4D!2> z_94vv7^Z&(#eYHB?*mtef|DvX!JG-ppI!Gz*^$lnIzo1g(E zOb{RQESPNfzAo>p3D+3wS@8G;r8s4aomkr2nL}D=>DpIxA8K1=r9Ov`XUz%4V6$Y-LZO{U|V< zZG@B##I8VTOSNTP4@+P%?0|hB4_*qZV8ZN24M+-cqKUOIHZpc#*?PDRwQvTC zS^(Ea+GBEP9Ih5dOqG z1Al}2KZUFh*}*yd>yR>pW_wwb^pZe%u2uhwivAZB{Vyu|UsUw}1{H-2RHP@gd8hI7 z{Uo7H4t8CRUV9sqk~Ay^#yI7k0gm(E<0?Q;qEd7i4MeGgiF;}H6I)1<0XG)fQ`>hz z1vb(zu6=GhDUV^>*0hUn17mdw=4gS{+C8AN^VH|%oj0DPz5C&AO=+#`kf|hX!sNkI zqrhb3ShixD`ZY) zCYeY1njpOlCiS0RR;|vGMk$rvsdyJi6VY^k6O86shS?yFnF?dWro4RfqFL^E;5 zC;raSTMe4~EY+T?MT2u3M_TXUy(T6koKHWo`lzwY=lV_;hxF!z z@-jY=y7rwzx5nDpw;tuEI{kTRjxLImcYf4o+YNhn_Pc@HE{>DUb}N?bR$ow(Y)*$G z@r*feQim48xN*Q%D11DWJ#KPhGC$mWj!s5f;A{Q1AS|$~-A3RTZ#!zG@y-byMjj4c z>vw@60#Pf+%YL&O4#%fr?s>-R6kjxq#lrA0KID4zZwm}Vuu9+gLWX*h5#Q&db zcHr-N2MzbF9DH>*K#h+3ez>N8j|+1b2Jh4mH%uFY3Q*-Mo9n)7ew0W+)|Q`VvU7@) z)O1@;#saS=tta%;Q)9jKuN&L-^fdCep_OQ2&*hL*z!vM3PhZh1otQf`)D);RvT1#H z!%UkO z{|Ec;nps^vGctB&WO{W?)jaZo9#~UD0^`iV@=%hXG(z(N%vtz}Qt@f+(RXG{S;F8e z$YgSFBe8Hx4nyfWNGpj3Gwk`|4AhK-M@{qX#nux4MrJK4%g)X&9aS(kHo~57oxqoC zbdQ-Y4R%aG1D(arv0Bj>({MhF!~U}T^68J2RR>3@lkNRwr(N}nVF+?wC6+$#4JhhW z{hNV#kM+q=h6^R83F-s>>rk0MP3gHo?i4+kl16aw_SD?s7jHA;k+(R&QutzOU+brg`0k$;G)>t zX9cDAB*- zy5LGH`2E!M?zM2A-a??Ud!C>z(y?!;_o(}J+eoE1>Ydx8Z%&1fC1&LYSA$`~cz(^c z7eA#*QEs~GJgZ?;Ugh&Jvfy5w1QLIOw$}K3cDmbKAAwsaKL8GKs6LvLh^1>6)6oK0 zY4sj<4Ip^}k0PI;FKGJiWW%Sr@s_*YIhlv--!LdAVI^4b7@5%MU8l7xO?V4zq&3=F9PwUt9fyH|@n6CK|2RDa z2tirxuhACTx18{JC*#~Txw3js`mUoS|7vq!@eV4 zC+3wR=a|pow!pZPx_+OAj_mw(H(5>(me%;2eDj_~NrnKub6p(#A^$#Cd6MiM5;1!c z#vFCWWZufwzg=xaOf68d6Pnh*-M^(_!Wp7!{Ad9kaXl zq7&@hxx2Lo9pZUYMb6YAlkzwlRdqdf8@bqYZpYyW%9eP4H_UZmf_5+ZzVmtNn7@|U zkA5p9*(6I~G_vr5mB9$B1&a+`*0PPOIvyqgqp!dUW|&P3+j!nvN6*=|!< z%K$ydd>T=~oqp@5=Luf&uVdQL7+bN+?GqhLPmfE<6NElOceb0|Fl%^?0M;hBpSc2l z!QS7;+qzi0e|?4mBKcsL_0V6j4)3R0ZcA{czns}@)L&pOGPam1+EWxEK|gWz5;h!gxVn;Uc>P znL=5Bg5B7Jx$iGO#Os%GXGL+WH7&n*`1}M5|Mj}RJ@+F^>ObO^NNlV-%cK+--oT{( znJ?mVZ0BlmuG5{9Y%vEFPSBP6Dw*T5FKHV>Bl%-ufkR2v7*N3>va-ag(FA7u;L|v) zb$p{JI4}sVEQ>Xx(3!A*_^y?<(GJTI{t_SM8M~9^A{K^mr*g<*0Ws6g8i@db?9m5p zw7naP?fgm!0&1RqG){j;%R|__R5&T*4jtQX3(QP7(0wU8q4;%Ce1iLw%VJr~ z7Ve#54<$Bg+5V&7KTn>B;WlNBdH6TbcP?@Wo@w`k0}HCgi+V9*QVK`vvw2|yxrO9} zC}+iJdPY>S`aCYbS!c$0LQj9acFq{EQ>o`GWFdE?na@d>3hn++yuL+kmP(3}V!aBZ zDG8(YXP*APP zW#18WH3s)N=xk>eLD@4ftY_|nCBDAdOCT#YZeh5ue^gZ61vyi@4OtI^s?`~j*m@W@ zV)SCz4J+V3O#0n_LARHp_h2Bq4PK)Q`Nzd%p|p4VI)|wi@G&?F;fb-5{_F%fFfe&) z0pp2FVP2>u!!I-~Y%*8;=arYPTqB3miJNWGC}iiYvfb|wI+sF4JhqvMxTF^yQ5#`? zb^j$$9t)Rg6f-Nh4<;>z;(QgO#CfRu`ju5L!YoKr2d z+1#E;(Blt<5;iV0te?CMmfKvxF=fus=w68gf2U8?5ly_>1gESMit=Tv=ybcIhMfyg z_i|`+3^Bs5oIgq?K^&W4gEJUaWV<&doY$*J-vSG{IJ^H^M_+%JV1w10T3O~wtLmLF znfs-c%+pF>4(w_5u!_kixdH(IK|sF0!!3rPX2IyX)tNFZ!x0;*TRdQTpZ4XFk2r)@ z+AXnSuQjEICqV>0_?tfFKGfpK?w1?s);}jHp|$^d@eI;+DSO4H1pTTt5Kt1D@b6CO zUAM6(t>GR)Yp6J2NnqBuKFpm`h%y zfhwzPwn^Wq&ufb`o=v{MZnwFUc?asj++mQiXELX(1H2rL3L9Y)JOP7~f~LW-f$si% zer(=47#1tZS4+8xDceAJG%_o9L|JZWarSuU2sYPIFm7P)XyIT-f4;(BkdGxK~NHNAFt!4~@8I ze9jDMm@ta3FwgPiXBOz^i(KDd{&jK_2_z=3;t$#KCdQokcc(ZK7AGJ4^>?K5DtFLk zPj+Hk)FCB^hGa99?4rZm5bErfET^b; zvvG-I^TM&;5d)N)LW@S>GD4MAR+pM7j^k1pC2?h+d1ux7$BDS)h}dkm+uY7T#G;th zq<}Zz)$={t$oK62l1_Q4w8n08I;~clt&1nd?k|2vl25ObR$9}Yk&-Z|LW<5u(MaiE zZ=-!rNGqJ(iX;B)9!b805bej0$t1noq?Ww zKN=|Pm*9YY`G8h#!Mhw@Q3!fCF_e%4)~~lrnTUsN_ihox8-QH`e1F&Y+bUD1CKV+0 z&5ACD;c6t$IdUy|x#cwUZxEYHJ8`e_*^^3! zJakV16qTZEFrvkqrWD~6wpOVgP~^yk8z}cU6okQR&PXom;WWEVK{+EfFg7`u*!*R+ z%^!;-BNTHBA4YB!dSLX#YH>;RvUY3}Kj$7#1KS~pX_n90;X#gq`dx3(KlccN8_ z+hnr3OeRZ$YuUbI%hxo}>OOQr%@PnF<#7H;RqByQ_1Jjw!dE0*uX+NVQPu(vWiJAU zbQEu;R@L7aL!3g5id7pzF+rCh+P9M-NctPJS2oQvEW+yRzSD#CFJ`u?PB7UW$Ye`& zYWd>W2|DOU><(oS2&nrK5E(tbn3*oeW-_QY@zrdLlEE^ukpgn0#koi~4a9Pkz!-q@ zS8?a$^eMM52Xh9K#rtKuowq|UUDO^lq8M%hQ5Jcti5FN4^b;NSE@sMaJwx_XyZ1ZU zOB!)TQkVzX&kGp?6fv_)4#`i*WW3mXggq|XZMlI4a2avDUj4@pbZsuNH_cKoBFnyH zC4mzg-Xd$GRkw1>ah@utBvbmAW--9t3I*h{3NWPKHu-+JTJAYiAz@Y5A5M(9O^Ot z3kTfRx$_vE&61L4EW4-nG`sFANjyrLE*v}dh=z0z;fh~>{O9Fs1nFAxTTtHA3@7#| zLhN>rPJvy~c=oU{hZvWU6Ri1X`reCRdo3Jf%&a6Kv&_l7NoDkXrg2;9SmLR*0v%>w zh7Jvrh`bEz;VZCF|1>m~n3-<>R~%9kG&2e-2}sc(i6+@_O{5VO+6ex(Z-Y~0EWu=q z1t>9AtDwDCoCmcR!R#Vl*$>sef)C;TnmlK>#LM{uv-WECw!;!uL1vCKBLz#k?>Q$M zu29rNy_2}T$_HU5O0x_0RGVn)5>9$^t3;qIM<=w|YEU##Sh51ftjfq-mpRwcB|RZ5 zmr;RP5n{vE^l*-wa;oiO)H`0Xsi zb0FBg8iKM337K@`#VwSkHt^S&!B0V1c*t_-rIT}&`c8iG4$ywoYeXNJ0{pgs|_3fZzfo5G8^^1Bjrb z5fCB*0zYn^|BIEA$k8sNm58}Lu$g~ulrglKyGe^mfAfxjs&{FZ!)%NqS z=ep+O+ttu4ZBjjFGCAyKqty{rfz|(cyQ&voqkTXt;;c<$@x;gHMGuADA02G?Mzy2g zsBK^h197=}S<)J@4<9)atOqmLbtkuDa{|+K?PAsy?;;Ydq}}dy5>|uO6K$=veY+}; z1Ott%rMQpNT-4hYB~mR*J5^+%#KmdNe2STq364)-%%Uh$W>yQmos2+>7A-P^U9^Wf zcl4hFacy_9Z_;#bABM{5&Bg>en>$G5>9a2|d}^`Cq;!&^TFJ$;RbWHT9nzRt<}zh; zb4Jbg&%ZaQVjOzxK?lRA*R3|E#>+lKixO$*^SVZ3k}UM=OtzSba#_UF5+!x&)qAYb zlHleQKbfTNDzb)hH zkL7NnAh!=m=JbZBM0tLJI{HhwyGSy(4+S~B>8K%nOZ_116X;lnR?01Spr1GiN${pb>?t~6O=ByhgF-^-4<nXkWMs6*x4yZD!!&0i*Isr$=?bK#J9GgX zp%JBVc@tAgGIGo%#5094NYL=hhoLq6jcOtt8fUg$c4bA6$CmrEam;JoGG;UB_S($3 z1<8pdo1wUQV$;e4dw#$ zNsBM;ogP;dwFWuoR|PhS+(l_}vtn9AyYw{;3R5kt0?{*J=w$fQK43!-7HnC+HHBUX;y-z|f;~7XA%ghIOn(m64 z$)U2>?v680Pnu$V8}x4j90c2kklx?(#*j}HzC*sdWHPm@%z9WmfN*a`@)QgffdP1)|rB21KzQvSDHo1(FG3FNKm*2+Y$8YoFj**$2(tUcD z(`b!1hR_sQ)ut;|QWrOuvgs4Et%iiGC@LPAr2;R+T_BOD(FjP6c~|${akbsL>$kHJI(dN_)*~tN@$P=*Opgm| zQwW7~l?VJv&VdOXd(DRD3VRk)jidtQu?l1!shWS0*U5LtgJA9eIk{9yWUK5xwQRkD zJlV)wcoq5;Iw+TpcJwOLTY7fX)6P_boiIg_F!`Qzi5{7)^^M92EAdtBZ5>_LiSDMFUPmjE(#9U&%fPKvDCoeM^k#&N#{7XP-{rcvm#3)d9EXM;re`T&FKAcc-O0YcO2LTCp&haDd1V)L>wcO>UkXfiUd;1^K+ z^SpHTvf(LXmVtRHF@QD2yf40>X2cKHm@8B^No3~$nH5FYUmg_Uhr?~mCB{S&yhJj2 zDHQ3X2-2=m#H?scgnjplR5ciLmbGb-&Z-k)ya&Adbv_1OX3j7kk}$b}Fh*&>k$#boMSsy25mKYd)yugK+FOy1jPvqm8 zHnL}EgN9-K9<$4AWI3(OGFn*^>W={{0?z$fRFQ%l$JqsRyksH>jh+-dP61dWN6S1Z z#YH#ecMps3IkSkHOKEhZ-)WLb+33(yc0*`?AuQbeGOv^RG+9}RJiFwuN|GtXB3m__ zV2+A0Kep#9xMf+-)loVv%_5HHSw?3t8q5&ZYpNXNck?^pQJ&!1sd%f-CL@M3NzB}5P4EsHy0;3j@9mFG10@?BbQRHi<%Pz470OQcKYb#4t4 zbK)I&w-dfZSubP;2qKV75HY9i$z^K6ZNh5s5#UqSFNT&rT+#`%JnQwx=&Whub}FKi zG{$F5e8pGj=Xx3DfPSj57CKdw7ryEn#9E9dYMXP*gy))Bu5XUA3somo2{)1qr;^dflrH` z%SV>Ij-RCBN`2L#${sF$T_K#>3szRg@D`8A>M{&+NGHRn&cc8Fox)0fD-KyX?~7GZ zMGi{5Z>lvvWIm(6q`oJ|Jh2acg0JCk@H6=V)jcjL#oX!7)Iuie`4N*&v1SgEI9otu z!=6P#ivHhrZC5q1(k!?y{15P7Bk%>#ibi*EoiQ7&Yu{1l|ZI1Ow;mr)A?} z-D2O5z=Lo{5NUmihS8-*FG_14s_+Da_R|-{!J~0d?Oc8ZSVwPG#L8llo}hZny7^hC zlB48Oq;+dJok!-QI;r+kx5Dt#rY1DcgahFv%8LQ^pM#oeE-)G z_zJ2P>3KOp$LQjtyXO8MBJlatX+cgBRi1^R@@i0OJ(N;5>S7mgu8aG7~zw?yHsdn546LaU(FrY2}~$%#?q zI=?RhKY-c=S*w#ZI;|!&br{}!C<5OsZj*B|T<+{lyC=GMwLhr+D@Dn>#LMz;NI;Q*o_1(!x!#MX-8xqRpq3 zqCL2OIs#uNT@v(GNif*Nm>FpKLj-GlX8!VNH|dFbsd$t{Dw>U#} z(5fG?hBayqY+0ncDd}aM(WKMIAX{ByWXyM+cTqZ!#c3oIsh-_by40}g>Ygy%eMT|` zvaQCHte7VbNAG^M;~Q#b6*3H*Tv0Wt62JLXzG|lU5^|A%-P&T;;^jy`-1mg9udi%c z)g<*vumb&WNjWIK+q74zCRLT!%tQ;#g!PeP| ztes*^I9I5^CUP4xlv-JBiG_*L%P&`f%jh|BF-3PSqNz?%wc7s0R?OP$rT5Dc@Q6Yp z$#Jw8WwsiYSwp;VqwLGEXyS6iqM%CS&M&fJ*Pxf_OL8$;7YaPE^zi-_S3H=lx=uGS ztlh=eLVthh2Qb!}LhH>;luBP)W5sTC7O_{TL4O7?QXFNb&Aid!^cnq}pN;bO8$Mb2 zp-TO12iWrzc5Wo;Ed~zhkf=+rQ*1aKys8OmXi!JAj9bC<>T59-bw<3b2|Mi2s+WQv zTCw8z5*LIdhsk9SdC4NXlcU1swK@d}I-;c0T&baSP(6%Y1F6r(F9k!OwBLYQaF{$A zA3GELywBi@iF>pAD|LC5s+S6Fz+|RTv{zxsWl#9xMfK7B*2k*Yzh1b>#G55uoJG_| zh3DFjtTHrj5JDTXnM(AevV zKzYB6A#ty{=YTdlU+SB5i~I-t0p5YP$Z5}w={uQU7<-p;qjW~}8(q1nc1Pym^!!jn6CPil1V6E2^U7uNCC(=oa0c3<;|-KSs}X1s za-8K3wVr?41ZyTOV{ z$x+jMFj%wgI=9(O=-v8`25*6z?#QJ`tV21~Qyrdk!eTE5zg>NQR+@y5p}Kw8agIF8 z+^`e0=?b@!;ud4PTKxJlhBliwE6~(0IhLx$lp_E7%<2v zX8AbQ77#eMhN5H*C3j4d#)*80&C_VrjWiwiq0xGH2k`Maii^|IF-|a)KKPJ%funsp zbaK7g2P||iA_fV4k_^tze3Ih#DoKVsqWhLub)0skF+bEicOP5g zna)#<)NZnkTnC>*3%Q+ahGqycMj5(DK%K+zE66g>X>?qe;Z+sH_&Jnm7Jn7KCO49+ z6z1v#`3bpNVXi{uvs4uYj*%uG=O4gqcy{`T$s>mk3g4Qxu3F;6mH)~%(tRnyJAejX zNLW$T7kUg^#04qLN9s%hA3c_9wHS7STR?G~BqLVV#axcbcu)=eCd#Pg1%_e;mPN8j zXZ1xV?mkin#os4WoH}c&OKXc^!~_hxfcDZI;w*7_K67G}cWpOg?a)T?5)7}IFl59_ z&ka^JIHXCX;P3wO+h3+Bya0b)ZlwQ6E+KQ7ZJ-^aka%(!7U`RAV_u>oN<1&Fr2+!2 zvlv{8eCj0ZiKHok1-;v-C&*+EVKQ3KJX`+opMSwO#HM@V1+scOkP69n8jU1F zzuFYO1-ri&Pi6wrotL&z<*zrvEU5V1$M9yzcAs~IU0mW0DkEr-HiApn@kyt)aFp5* zAeCYI<WNN=ImTNki+v zz-dH2mrZ@tMi_-|ZC6(#6`2=lmqCvLmaBtFC4*ji%IC zJ7QO8&yt<`{Ckh*9mm^1p0B$?PkIL)>+(`s?=JtIW6LJBEj;nMdaB1W7ZA;w5EH>>c)7y8j5C^F(AiYPd?7WgJX^VtJO6Tn3XnYFYbm z{ze9$Q`Zf@QeM5$7jH7eMbD{yZ!6GDsWsI}h&5_u>#y@Y4- zeWAlxzzU3cmz5l;$bQVZiMEaM4J@c6&7#rFyg;o3YhU^)O|;?qli_LGZ@&W?oxsz) zRwK(S!*CXTl!X0wIn?G^`+Y!}J`NZk$0e171TzjJ%E}*<9NEZM>sUlXG0n0B%kv5o zs38!8fMv)GEkWozLR3!QaOV?sDb6@{keWbevz*+?5)}!y{HQ>cel`FB8$7~cMo520=~mF2!%WbZbve0=2#RpTB7<$M&>;(sre zgM7n$BPypx1q&Qzqfce|q^T3swbQ>wv0?8Z4*`t(-D>TFto1NZtQ?&pKd>kzY=|xo<9hfM#o<>&a0sJX59B z8aXpzr1hFE1>e9nh*(wY5qAMz+ze;KDd!l~cTJ7mc7DtLdY7uwxV~h+q0u(=& zGzyj!lVlD=N&a^$!{BDVfi#LVXOS2_s<+v_Dhxi$A13X3$>=i4hUkIw?t5YI6@D#v zjgBOr$?lH|{)PNWEZ5G9Ysdc=z%!xK>z0T4h_3O=I;(yY}u93|4r&wP+R) zF3D0@%;R{JI!3b!u7MXt{N%3t`P1cUJx7HFWP(*=Oti_SXg$BI4mWdJ;bXlYBEec#9y*mI^;}(dV8yM)s^Q=r z;jq#>PX=P$p*w6+UEN6iYtVgCD|Q~GlRAZZ$EsmP7Dk4SmV#bZcma*5i7wx{yQ`Pr z*p0$nDZOe!PGVYNE^{N6ct6B&ivf& zS78_TXoc}Oc&rAqBP@J0=&@9B+_(+;=!8r?5PT9xidrhH%T}+dj_eGN{-UJ?Gz4Lj z2_nW>-K|X+9EWr_EUTfb$fu?u^`(D8)aY#A7Mvv=IqPlDYYOZYr{lqzY_;io9~!I zmfC^Wa!MNk&<6YIGiVmy(m^Vlpt7aFbWrJHFU!oSGv zfVfN|AZ9xIl=!L8ErQDMFQr;I*5TwiyN8QnX~>^vBUR6*lVD4M@FJ-~cze^YjKaYP z2bk-mFSUUjm`u&yvvEy6S3I8UxmXZn{0qTybhBB?} zT0ycUYDH^;F51rGKS`=8h;8I;nW<)LMv5hRrG5T{gl~SXvM*}=K1q`lD>>G$#({{~ z%j_Le6K$*hu-aA~H(wDa6-FT08&hQeTD3?$cbU`_KPu92NG-C7TMJBTBFm;E#5@`Z zu2+j3=gyG2&X0;TACN;Y7Mg&~Or)5MgcvcdZi5P(!>?Ca5Fx|M$Ar81y;|RD{wg(0 zcvRoDOX?(S{QAVa*A?QDd`wtCCuqD5(FY#ZlUv5xzz&f9#td zzf{fG8im6&s`gXD#H5hQhQ#I$x4%`pcvLtB#?BsODT+)iuiBu?ShI0J*v9xWnRJcB zXSj>>q0$DdKxnPgv7vwZ+PDaPRSp(fkN8laEvG=v7i5<;3&i?(!JfTm9 zq!u>*dtP|GJ zT|xJ0ayp%%>!2ypxM{m0R1q11v&&O4E&X`?kkXPBq4VM{HaR~bKRNuAD7fy@Y&(wF za2;Kub@85fhuLgrSbdT`M0^a`J;1fOD)KaoZLD4A&9dp^b7N%aS+YXK91qZS_Q?*t zx|yv0fq5m8lXi<;1pBDTY29PGF>mgvdFplJCUFyEbY%KX_Kc*M(5>&t*xB@Lu@Q(| zH%Ztu1nGz)2sc9zelr0RO$ukPaQBie#L>%I)i7G^+#acxBQvupDlLPIVs`sK)Fr+k zZDNht0fQ+gSsUF(Ew@7JFCFI$+39*?R*E6IVHV$0feYjtj59sa;z~(~b@=|13T%+? zaqf73qR*QgGm7?KrJ2Ock2FKJAKtQ8s;EYl1o7f5O6MQ;N_?Q#vjfIogUe9bFMfnH z2cQ-#Jzg)(b>-oJro72yNc7bK>S`%VEj$D3VMJzEt*bZcs7bOU$Gdy!%iNh+iQ_B@ z@m8Pghe`1sBEY=z#B0OnLt5zd6;UxBjk*U%>3}6Y-B(ah+`03h)M8V5{82aonnc$w z1;-o?8@~(W02yx?(rZ9!MPj;VE@YRXcsXE?FY)B~-Fc8F6?lprdHh_6TMI?GVmgtk z5e%U=f;-8I$5817`V2))kY)~;xfzbaZL*0B!Xh{W74yMF`19HA5cd`g{u-uifp?*# z?{atxmcaY)#6WLP=d|L5fUU0RMf71cQt&Lg;!Qv`m!$c2!sls#%xk2lfh77tD&s0z z0Np1g`Q5rDknJ|uT}zZkw!$$|>#)1*j^3GCRtua!nvpTFNOJROx>KO((r+a>=_k-- zun9yC*WLY+vnZ*gD8We>d9bARlH%ET!l&)bWX53U{cP;JXb-o>2g*JYQ4DDDZznHb zP(3-^;GHesBT3r%nk`l8ta+ZM#KY3Fl|J{CY0k?(KL}-rGf56z$1Nx77 zrkH#(PC-F@yx#wtnxPm4eiM${21$(1KvM=U1-yY~{8|7$jv@su5Q3gU-FPw_J6^>5 zsebmixU9msEJgFpdSpvA2-cJspUnTf5QgtUH)K)LNRliIQNnp`@0#1^v8vs0TY6yA zOMM+?ogJkKJ=45N;h3un)E1N+7o@AU1lcUu-N}!6i}I6lA}&oX-^9}phm4n{6E<%V zW#_BpjHIlW{t887!sPGZgYZnLxNY!neCxtO7(nER~K$dULZEe&ROuh z#q~y&H8fQSPgTQDk>Okt4_IlFg`&*n*icWusBjD7Pe^Aw_RVyJy>+)A`zucGkGkwP z9_nEv1d&PJ3BRy{R?lczK}RhGdp+du2X`}wNK1$U#pQoR3rR(9ksVel``{BYE4i;O zw4+)Nsg+@!ptRR!vTM5W9kAC3)w=YeIu{YidfKSt0z_DqTiYIjOP8fX zGF3Q&W%Hj1@lz-iZX+^)ZSqE2N*)fih1+a+cgMONOvMmXwnB4F(>bZQB;Fq2ve``A zV(2=dt0$fgaG6Gv+mc3>i*C{^$%(YfpyM7 zJxN9;+>*;-qCJenOd4n4I#c64F<9Q(+!pTg1-ZV!%p;G56Wmc0tK0LhTS}KFpb@p2 z#i=4sB?=PlK%|bKWeq{|q{*ttrldjQb)>|QNr<9FgTV8YPC|&IWriU{8bB}-SQkSw zW<6u%IZ`X@^@N#4p_9$&#){nKDt^QxQ@ge{RVd^fRJ=8ik)4CU%7xMO=wH6Wy;Uag znC48Ht1BUec-Xox)kSk5&0Xz$g`YBlo6~DkMulIZ9Xg9k`H^Xbwl-ZP^cJ08A|-*b zvU1owNpgLaw z4CtG+bK){xI)TU7 z7k%o@=KhbL480e=Pl=qyuHnPh+N#EO<>h2t!BVb|%da4mq}Mo;5GRPH82{z`DO zaJfr#o@^WYn2B+EIDP0Pl?|zZFq0!Kcyc@@ceXnm>qU*B{zJ0*l9#)|xhTGaKr)55vR;UWeT^$U19`Ym}DeCozuQ;ZHz% zVoF|GTxx#wUD~=$YFRA!@ONn+g9^Q@&@qa`TYgQ((HG7Li|D|_%Af83+q{E zF{_B}qK+XEq8tN6n&hp#b8ys4{kgdT)wCa7q&bqc@xWN4{NuUMI-fy%Xcr^p*?BoX zYT$Y6VKT;&n`jp4ONw`76uYfDBNNi#>ac!b!_8!6S95d37ACh2VlIn6QwOA!T`D%y znKExPvr?*+H-<1wz}nw+bJT7%iPve?qGK3i`1Vgdv3{Htz;>>!;v$AD)|CdvM(e({ zJ2F|niECL|(wQ`())>XRBl80I{nQ=t8k;&kd>u0vYZkDbwYY+{8509$Q&Q+YUQ*pY zyrcGHfpnaeWRFXX+~%uuzwYe-ekR`}EhAZm1)c|upb=;e7={&q;su(B!TIaz#%NLm zSczc~&+tlCrkMsaZuW*c_4}p8yom!! zVl25{jWHv-HYfj*j1lpGbd)U^knWGMRoYxF)RLOctX(v`7)2psE8T!Qm$9+LQP2m|- z=GtP_h41=REAK5=lNHHijX30;cU79}MkZn-n0TF}(Y$^gQnNEHg?zCwqWyLvox;yE zq)5qW9SE(484%v`w^#PUyxHqZ!CBxpNLGCBAuy~Q_Pn5qh1b*vHP>K1V-&RUeG)a! zd^^oVofYhpu(Itg*+6?TTn1h=Xp)M<&NkG5yx0DI_^e+MuJiVDmpIOC?eHIpG<^~l z0%vB8I$5IXN$Cv0W=P^iLd%JYsQtzhAS1Dlc5LKcXw^V$OnQ?mHk5YM=(`kZqgLd< zgh-;o(ErLE01u_nLcYG6J3odfEn10lSP^rAugyXI_q1^d2i;cp)cJEJ7V&idOwRxZ?FxqTbIh&PEYA;4~eR1>9+4B$~7<%in3`nA?BNxJ9(z3y&=mR#XC zfsN4_IGdf7jeJZ@j3dhfIKwsmJ|L}u3Cst=Y)o7tNQ@QSOcWj$s6Azj`2~AZ-?!sdT5o zmFCjNgj`$stJ-&kOfN;38OA09WfB1tNrK=+3S|uo-8^uZmfregAkMf;xFKppB;_V> zf=>4M;~XrXl^A{k16Y&s%esNsa`Z4d&B}o|LGUGrmfn3r$~_t1iGBB`I^&ofLwC7C zmm#5}Q=b_1kMql{mEm5^MJJ!B|56F2>aC z?Qj*Q-_Qk?O7K43^G#rkq@6DkS3)EoR_LE>#TbO+@Sxw2gCJb?fAckWYt2A>rO}F7 zDGRc9wF<5-#iZr6kn!SceP+pCn5h3ei)2hZz^!2HlG|AU<%GC0ymA)P| zRWDZ}GN;4L-SI>A{SzyWP6GN0h`X18c9h+N(e>nz1~Tt3C=@%T9UPm0Tm=3HU|C99 zo+Rf0J6<=opzI1Pf?iJ-+=aaHjuDz(#;MdWxwz9dNLd7lK}es_^*Cs{61~hTAmK1D z^MStz@>*aAIG?q8sz&rq@9)c(iufEZN!#BXhr~ojcGuEj^P%gLi^+R1Xh3{FS0B?3 zFeL7Wf~CODl%IE&C0BI!#K{9EZ-tC5k6D+4H6zE{>5V^vx3AniZq%qRAYpPuHPr)U z+}9Disf#fA205F$00+rr?QbysHhcrku#L7XpuUFt6E;Y{-SDisAJ#dKGyw zq&HZ;tywkxUBlxjlJ39c+hc&B zsThdF^5~Pj`@e7dNh#C`1y*oJ{|xou=_d>@W;%UNv{6u>PU_PgqK4>bV<>$Xuu{hAv9twx5rEeLe~M z$J@lMUrdTLtCJW;j)|{y@z-0beuUY`?O7Zxc={h|L4_S|LnG%=>ETP3cdjl}FH71v zMF<-a)&(tCu=IO1_VzIzhf&K=4V`A)P-hXxU>6$Cg0E|uMd#@jAJ)a_NlN@H_S zreSRO(rlU9m@=6`bo?wZ4j)T9-7yk>{j#uTQmzwko(0zDV<>M#rJ(M@6>5fqfavv_ zi)Fdw11P5c1%rle1d2Wi%t~PEfm;RqY7qVa=opB91nD@)?||lO(4GKYiT-^stN~*; z(@8M5gXI)hPlK(%{wHvp0p|zc`ZKuCf~U%R4t(b!u4nvONLUAn4UlvJ{NFS5`M0*QH! zJ_;QjP)66oJ{3z_wqqq`4)U%w9M}yVAxRKDdXwH`FlcNJNynrnTNo6_B;Z0JJCpmH z)gp?F*Jil34F(wt&3R0&R$tsRw}>CpH6MwxKP|qS`tBeF>yVG`U$V0SYvA}5#@ZH8 zW;c4}y89-^<_zS#XgRb6oYn-blQNpvLP)h3JaT%H&&-@QtXdd9JED>^px7ei~ghbxOv-^77}#S7uaJ z;nYgxKfmexw)0zk-@N(F{PSDSZ~A7g@BD^u=A3Unzg0=tt^A&=e1C%MxO91S)r|5; zz1_x_Pb#lDv=tS%FF93v>YY=w+FRPcIQ3?G+o=_&-u1OFRlaK5ceL+1^-gSZOW0|D zOZ&D{@1O!)w!Jl4w!Kv;sU)Z++gqcFdmlOb|DwGW^$Rv_3T{{!Y-$NM?F%-oQ$Kh4 zf=!fcI<+F;X0{BOgX!KSsLOvurd0_DtgaeYJ_Q-n4)_LDDr2geQeIwDIUYI7s%oBB5YAVD zD^w~fuklTrP+l{&vV0;6sA#p}+XWc4>hRb3P2VoS$fY2b^5;g3SjzVXr5dI9)T&7b z8>^;NP7O6NW2)N5ROC3gNS)xS&NUrfRYRC?7YW+^2MC zV0qPZ6UJATS0kIUKzLA9HLv`a5hb2md~VgbRlak}&Mi5&@!axrYtAhT{n4zX*JIeZ z4^WR_iE+r%oPM7222KO_ecaX4P|*Q!6JTPyfmnr%fuKrU)S6{TAMU z<-VciGs=-!!O|%cr}_FF+^(R>!M5_s8PAv3C>S|q@}x=?Bb5~imr+JMp%OW-y|eXi z4fWs8-tqmc55J$i=lfZ$-_PED?f0!eY~O|4H|pQKzVp+c8b0&=v~A9f4Rd@qme0BI z!JePiuKDS`HIWhEsjCe4r)r9?FGij6$`E>1D(I=;?6V4TR)(;%vKn;=wyh4feH3il z5o}wjel81sUK?!N5Nz8SY^zgKRs}zw6Kwl5`1zZ`wvUxRk!>Je?Ma7LPVr4CpEP-j zFM#X+YI{luccj{PqQR?8JbbdxAUGs6ReelA6?9JJnnpgFD|0?pPk& zxfgZ%-w_3;e)iwdMae!7XZ(0xXjoG!eIe3Z9VX4y$ljx}O2v7V9y}kW2Qw6Uf^0o1 zqmT%tn4y%#glERo8P6;DRjH7aDKF0O^_W>zIlXG!%t}nJCWN+wvc<#uVSQ*nIMl_g zoD^B!$_T!Vt3+90io88akK1?t`)s!O0+BVyObH=G7~vIs|LVgKvQMn~A6BX*yi!Wy zyx7D@?MmIq8ln-H@~ZSt8SJj|8s)6>j;NYaHND*Ta`afjKZjRUKc}GK%yMOoH*XAX z-WS~5qJFLmZds^))&@84R(|_}o0kVSf1;*-qULA}r8cTrb_Tb+spiH;R+8j!43T~~%u&r+fTec~ms4Up}`(W#b!Pd`$ zpVb9Fs|~ik8EoAaY;6g)t`4?-6l~oQY+bH?&R3xuf~}w8^v@OqTkF*HRVZGeyOS!v zT30pE*T1HG(xgLMC;qo1x$xho`P2e@`bLiA?Wb16Chq;WP2qcN+F#o?RQnDs`D@!p zlOq*RoiOdMpRXF{>sCDhnH4(n!`8Jwe!k;}mStDkHvPD_@rP~iBR$ra__|N1oH8{M zuE*QHMqvzQsWtCZR#)AYAL1@4hkHwV+syaHAsddUrrk-%b(y-zr$`+PS)Mm0J=Zl! zmqJ@PO7z5O+^&I9PXkgbv>`{FL1XuYgUqYC#~*7)6$TR+(l3DVvC@V$TWs?$m8f!s@wM)%~! zr=q&~cYnPWvaQ}r&5>*r>$B68H>#}K_b&{#A?^lyTwFqBK4L+CIk)E@SFxI!y+a)n zrLm6yKYn=fcE}p|F0}wz+&anZ(Z-DN$UR)68F34^P4Xl8_S`#PgsW?#4~f#qN7bGC zNUctheD}~zvh;K)b>91t)GKs@EQRIaTlH$HQpqyrn2^xnQ6>AA?_0ND1=KQav7O!h zaipHb%o-Vu3=d(2n(9N^!(1ajxKH;$U*F@F7nj1La$8oYqgTr9V(R6HJbrFjr2P|2 zi-^WQ%D!$xq?t?1Vp$p;N(&7s4v?ih|*u6wejYGQ4{Cd=tCM*&G@%nFOFfoQIqtO?HIfb&}ulJd`xo? zUf2ioU{TZ;3RwrpOOdR@8pbyumNVQgn?cBW8`jWIo96hG+n{V{U%iG0xsK^ z+9NO@nxU5bRguNSv%n8?JefVx{%mq#r$BO^xd&enm<3NRgGVmXz#g9^uuJU91X^F6X+ z%m3RuZ3uOm7`x-*Sz00vT2II87A9o`x2Ep-$X+m{<`39$Y}skC!|lYp|l!n z$WnVX0dGihN&0{@=F$Cq)llmw9Ac%6Y)Ob008kPa^{}xY?_a)&oI~{_sPV<{ zA~tXM)4%A7bmY1MOQ~X#un7bG5UpsiYw;F?{%` z2Wl#^9j7i(i^<~G5)G`ywFVB6QYM+%`#?;5ih1Au^ut5d|JQBm3}Z5TJZ4KcK&Gle zY}R0Nt-JJf)@L#L;*82MX|#Afrm#C*39D@OTh;dk%nerJ3?=~?WBm8swqu{0&CF@u zllX|KDLRmkd)61 zv^Tmu_e(G=$lj$*H03Y?9TUki*sY=m%3aDmpi`6c22QBl1yfGLQ#Q&%TF~gxnXW-5 z7dS+l-mj&#qL?hn9B6s2M?!SwzWcK}a|uYlgFCo@Fq{{YVb{ul@aF|NnYs+qEp z_p)?{>7DQ&pwFiTTHqN35?$bXkuZRXGxQ!5QYNX+BR{~47msw8g*t{R7u`%8?F~F* zDT-$KvH9}4FIC^SH-skMVR6RWtuAlWqVL_d1)-o==rH55q+~nIsaY}c1!jMbODpj8 zXd4&s_Z^U&+%JUl6t>scaz?Ekdv8GN6+)mb?Iwf9%NatJIyNbVU{>9+t)xo;tKet%*+6ug+%r{AElrDIb^+eYwx(uOi7){*`6u(4BDgDxGq8cQ98 z{yw@v=vmsNL4zQ`mb!*z#%C4`D$5?*c~ZY(S0WoAo_5xVPtqQgo$g2#5;IsQW0uWH zc4J3v5lTi$v{y76qh$Eu=j(7p0yh#jxpr}6DwC?+2vP8l+c9`1G4nImkh*J|XDMue z9#O>Q(qj5&@+cV&llUctnyJ+ZiwB!4OG~_Cd>sPQynXxhv}X-X8Tb~AdfZeZbt2w{ z{=1>)VIY!>BRD@JyFG+1 z-$A#hECZK8X&YFd?70H^`3u<6vBkub^MTj}CG(-A9a7dq)?7e4U>Wop>t93uj?Z|a zXQDe>v`i_?Dl}MNcpjhM*w5A+_=e-8|ABH;kI7K5V+>fsD| zo@$5tFbjT#_~S5i7bJC_&;)TKGdIG}^+5F0ayzLCwrgG zDaP;X-DUJb@*75BF~CfY{rTPpTi%9>z5jO&|G%_`hVU8^WAB`;|NYL7Fng{&K&~$u z`h4PIU}q%t9iCqdjxsWkuH;#Av$=g9iLWUZF;|O%QH&-+ul)y9pQQgi;RB>+?2|Bj%Ec8%Zuu3)9Qq24Baa_UhU2HjJw3!aO$W zC-^I*#^Vkj$BO(UKA6 z8CLCT3YS06))%-a(xiy5F-|MjE>_E9!Hd0|rx_kPEmxh4v^t;Lm9HZ~qXklqS~AXE zq?WQG{x|MgG0zNRipeI-X#Cv%ak$_veno+Wq77!6iV5@4v`{TL8udRQ)ORe_j*MFk z153Ns!hosFSnYgpP4bK#`}};!C^hAN1;gHh+@7YA1aC=Y@(Xe@Jvg;@pXBT*M2WUj zenOH^lsS=lp&u6GO=Z+C&`qiTlfN~F+ds=6%eRGICnZIv>*w{6>3G1eF0c@U%Sw*vJA35>|as~WA8va0P_L0-HpFq#$VA%(y@4|@QPd@SNDg~P} z_CrY!IyT|$mwgp1%gEwQFl0ZJ&W8~N^C9&p^cyKy2TxxG#B#_k=`*|zJ5fUyP7k(?fonRN0;a1Xu)9D*%-70gWP zT%_3wWjWLrkhuiJ{Lxu)`(Wgo01M&qSL2fVBClCU)4cHN2k;K8BY#iMre3mFy)YY6 z-k{zA*Q-PS2rJ+{7_c4kwt!|K>0L!W{vlbl0iLUxF@5?d@gI=UG2?6a88V);4Ie*_ z9XIqO_!4r3&bwhym(e9m@6s&aGxOjL%PLq2d4E(SK_%~ya|%g$?pLs`0OuLfiTfa731oJ&y=opeW{UnPZ&ioKkHFxq zpmf^Ty~eu-W&?^VsoF~JCjSQS!v~Ns59G;#{7lEQ?AVM!x|+cF&aOPZVsu%*!p-D> z;}m}v((aH0TVYzJGh5gX-RF|8-iL#59Dc9#?ROPI8M|MZ`MdC}aYX(`(DgHwT3+s# z-MPnR$UX$b)72-)r{!6YxDg8Ta`(e(XoN{kFk&&xh0)JihEP3{C}}E8?cE5EFD227 zBVJE!g0c%##YJ-D85r>Z{61GZnBsMmluU$4<#*f>Y~^)l(SQDVyFw~w|6dgN{}&3l z!ze&gl$jp8>W9a| z=gO?kcWef;PNTPI<*4|xVx0>2A?a?{dxlJrkI#^}M^S{Z=cLUaL~?8_X)yR`Dm9K` zQz9n}&aw9WNRCS-$MlJ;5QyXWq}UvDSE)HlP{B9ms*-RfGG73DJb=cj->bw zo+8~7-ehA5(OaKj^b-9m0|N^?smJRQ=z#fxH|OGE7NEq2K^L}M@b_II~*qC5C1 zc{a{e)Ok#{Io+a`8j2s0f7z^->V~o!Mjy`go8#??aRajY*vsTnqCn&DXG^TZo0;Pu zn4Tlbl9$lxN)!xr<|n9C48kuC-hMk=Marx?_^n`QZ%Zfp@M%vx_IRh+@OYckKL_r!^}B=n4uFUS63qO@$yNJ z?mn#TAGYsp{~X^u{@YC%lDkiy{9W`1KH()jS3eGmBxjUqd?^o>}r<3OXX zJ?!DGxg4pW7lAwq??nUaNMONir-e}9TMc&Cx%K-M^$RsBuCmP~h~bgIhhHnGisPUE zs=^f>r;!Vmb}MB0(3aTxmq@u5?tH1lX$&$i>Z9ep461N5;%@S713tkPNx0al+Kb1o z>Qy%e!qL8yS*}~|q+H>uF_L=8-%*i|_5FpGD<|vb`3`ryi%G3yU zH@Dl45n@2Z5D_CHM2r}b#z-SZq%k5wL>dDkMzoQpX^31zL{u7Se0w_C$NT!e`~CO6 z`}+Rxz0c3@3ujfWwW@a2sFV;3mIK=P2TG%quJXiVtZ*P&mzvPe7pDr`mtOldirq{ex z$Li}<%G>pgWd=m^dQPP*n-^cKX-X_n{l-zejz_GZOS%(zdU>M%MSa^ShYlI626YL` z*3c&_67Z|~<7Ey+8>}pqR0HH`g?=ZFUcooa-Z5m^p!Hz2c#wVuZvPB~4nWfy$hLq; z#V_a7!m*#hL8}2bIyE+-h#KNE*MpMr^ZLvx95HmPGbbZZM&HZKn^V#XGP}T_Cg`}s zJ~sP7>x}7v_uw3lV}4O}X}|fK!KYyUQ{YwbIa~ogf)oD$=tsbWXTa~klOTNC7}IMa z>A^+0+hBG7`J&bR3JewZ6YU7wS}^DdkTzjh%51WHM4$K^dOdKi0|U#!;wjrf&UP^D z8Yo(iZx>aFq5|uf3n2I^ARYo0kAfxcX3)1uR7)Dc&{*Msq1Xy=SLFv_Vrt4mK+mV& zkvZXg049G8?C-+zFTtEYgR)P6V+Az53dt8h_!)pd57LJBUjYYv0x~WD=2zn{fTQ4P zyb*o{H^K|xmn*>>T}EYes)@~53DO?{Id6lF;7hOy-ZRHB{&#KJyK$P2mp zSR%B`jxqwnJc!N+7_zLEkWgA=9Xp1o%+p~rGcyNybBas#AzL};%QQqoL|S2lDT#S( z@;bgLnkM2pCah$|%J+}HA+F;${ai*f{JHQQNNeVr=u+Yz0 zi^Zid+VQ)%`>O*{nLgla*e=CJp~3sULUN~QdLj_B17P)>8hgEzT^Fm zKm7`?DntKibS4>{cno)$9aE;E*v`evUQ&zTtf*>eEAcBQo;B^}tY2%E~?BQsKgvj>$a= zP5)t!h}=Wrs6*js*>-^R<0=>2J!h_{w~A_|^u+1kS3Y$k<#4Km#_H{QSkzeecD*Xc zgo!HcPxV`L`@*GSe_2yCippu5*!T}!yHq_@3gudOU-g2(=<3Bw@2{L!JwJig+4Y(Dmf8nqvt{~Q zHKrBXCgzU0%{`cLjx|jgk%eVs4k@&y_~^1&$&k1_XVe1uwz|yppXncw`zx^m8*V+l z_CO6$^&vp}KrOi=dx}5f=gbqpF*GB6-rxrc>wtgKxQt4$0=S}gOeh_|EwtPfnT|aQ zf(c@x_A|4OQb%|BHc}FpR*6%$$*n!U1yyeJ3`; zpOxxJ&C2Gpoz?bCXSR9jgpt|V&fIjXGaJ+QO&#cuTGPYXeQjE_|BJ_7y7n9C+H#Zs zB$&qD87!b&f(Cy5ut>~-(DL9BIMF$P3Hp=-CY?W?+3~5ILg$qK1{5%c!*x2qAwnS3 zWa4tJ>vx)^RxxDR5Lg2Y6wU|~X-GFxdVwNnO=)g;{+nk%mD1Rw?ZI;Z&&wapdK4by zG&<|+{`#$Q1spsN9SrNU)5x1tUtz1R#c8D6#9a!GnkT=I7!D$?C-`7i&==1Pc~jIfBn&2}nQp!M=lUX&4UloV z7~0_^wV;xYzh9BYWJ1KXP>ota?d-F!JS#FW0u|JUJ0atyAi?Qz1A1dxG%k@6v^1}-IKdusnt#x1Uali@wM%Wg0^rZ^c~uOqBV@n>L`X8oqz zDh)ZVg=+yK2s&=!Y#fOrw~ioLoJlH-RsZnUQriL)z7ob3tp{agEug|eSa1t%(7B3D zY=6c;Qlx7F7;4Pc;u0P|{NtwI%IhO?hQMP!f{3aQ%Vfj0<~x}KN&kwR28iJdEXyao z;;XNfsfxy6W8^3q=$qlN#+^FWWK_&DgZ%XHn*@$cktQm@QZ_##lk$wzDDYI|I1>@| z-!v|-PdAKo0?dS)L<5i4Gf9Quj;rkMjnvRgOu*@|4r&%$*O%|8%lTAf8y)g97{N0< zXVW1orlt^)+3vX{w<|)C_0cVK3`e4cYXT06FTi*m)Qf9LM;alE(~J?~%64(cX)Q0l zqYhj&n}OSxaxMbIR`lz4&XyUeS7K z2Ooh|U?pq@?}MVRf$%J}{{X!20q?Jhrlt%K#x#p|(>@W_3@VR%fGuhrol=m#hRGz`q1v5ALf2`P)D=$8GcSfWbWC%CTh@ zybFGP*XYfl1v~?fiX5K=#g0^mpBcr>&w2w)8RPl@K6qQvOwl^(%TI+%y)$(W0sc4U znU)to6C6Bc1;~37+P{Rke;{+;!R?>IqC?R31Ceq8Wa)IdB7v!yf`$foK#rg9b2bKS{KkHt>s9c;^g6I` z(j&0!br9bS#*buw2L`!I4p9}yKw#p%PXbqEf0Xr0Pm$iGLy>I&9R#`#V7$HGZV)b~ z&%;4$py@Jf1?_P38sZcpaTwgD54VGHLUcQr zKGwV%h?WOg2lGAyOPD;cjB%9`Tzo2L6tJDpbPa?ITR`D7=SE=n&?fuhm*J363(`gE zrvSGHI_p94q6vGz(k4)xwdBsUC55(h_xyEmY1Zs%>F$xkg56Mr2KzgzJ_GyNSHW1X zbtPzp)qCL7gK%zD@g_KQ2Qan*QxhoKCtBukK!YgpXIug~mWRM%YAasla*-kEvga8h z{R>Ql&o0moSTu|2pIVYXEu(Zj7!|;>BB9$+NuNe=?+G~VG;kXDkSpuKA;YH4x^o+7 z16A|NM_&SGVAZ{6K@+$R7B!3Wv;_jXkO46efGZ^s`7E%0e@3Vs4Eiwj~(`bJPZHghi!Z77!y!<=lo zs9MVUwj`})9;`^iiJTOIOscxsw(YMQRl#0yts+hmX;Feqs>j&VmVoc9*jF*lLdT~Y zQL0uu@yzz#{*|XHM51wTqMoBH&6{6Hzz}pj#6)@z)K+uJ0H%MomP4ud*`cCZyDt3PTq1tP&*b4;g0Q0+` z*6aFH30_W$aDk*O97QLkaB5hefUm#%Oob3IQk>V2q^7kuCg5A{?yd-MhBPm4Ow}ZR z$C?EE+})Qd^uY|PA(XBpNFk&+yPj1t+=;l$ch^>$;tXE{iqu5YpC!81&uXm*=uA0& z-k7OP)0y=zsfW(RS-UEX?tt0g@mjPD@C_>x{Tr%p%q+1Ak-iSKw4@wg-1JcI(5f3N z14e_-Z_+14hSsc0;P0wlRT?7cI6dYrVd zt}H7LNUHz|EALD=Tt4IP|3w>ZvX>*!1-|b%2*LVV%L3eV@AfM07GF2f=M*LP0(z-r>BCCd1x-hjgl0vk2k54dj6h$mB`>XvHE~fTTf>` z+N3I8tLAjiFe04v8U#P#zKyAEt%ZvrZhCqr%aM*ckYNmrudU4ZpQ0{6)#L0X2O)r5D0a>M9 zwSRs6IXSt|t$U?i5I5?)DM<;w+y0UmRn2{$&G6|>A+N!hJS&|Ej<(*nN9CxoL*huv zS9IU@%Csd#=G6NOE!w3?^VtN-!}sl;X-CLrqiMUgaeEF+@MRl;bp3XJrKo2to?BIo z*ujey&8wccbn$HDnpj;`dH<5Rl?z10Wny*Z{c~qk2SzTQE9y2VJsGx8dO}sLI#njj zo;~;O>Od@Td-dJbizJl>IsU!I$do{Pd-eTGDwi&pJ?umJL+0gtF5L53HrC{7C zjs0vsvtV^wk}g4BY<=PVZOVL3+1^hlu%Zf%kd_MW@ofqC@hNrv5U(?EIzy60@c8xw zyk+XHL8g!y>4PR#3t8KIvqgpPoO({`&vTrCOUk&vS?(_`?C+-5527iY)C;`eFw?a5 zgy!{cdU4!wZV*QS5|L^W4cS_K{gX9&9`A)Cl43Xtr!}YW>mMiJXQnk5cn8XciUmfaouda}PC7NWZ?KrNT91LlAis}z zl8F1xEZ?DRe*aMSW;wsh&1qW-WSNi$EB3Fb{pRm6X=v-G?<(|J8J-|5jt?6$(a>Cep;R=DWmL+{kb_FcTTq3ldWac`D%j<4%&_VDe0TzE`FqoqIES3Jey3HCm;zv=dab_NzTIJdP|kX51)n7?B`; zX^N(39A|XO*dQ)rdg_e?rVTSs=UaUS-r-h@Aj%T+sV5S=Hq6{t=y6+YZkO4t%#NJ+ zY=5Hv-kIG6x`&Xc=ybnTof%Zu(5o-<}P@A!}CYB$+p?$nYRi&dWs2| zDJEjIg@P864O(zIXfX$6d|C1LG^!<2wh`G^Cdki0Wot$;}|y z;l%^|ft&(03zHzf#rs@tBQmqCdPgqiF2FEPKBf)s`x<$0(&WuvmCIO%xoF!^r=}yk zb#sdfKYh=cJTiL$N95e6Fv?4zw{NXU^xrh+Y%ZpEVZdYuTH2eht|$6$n0p|fjOLJ3 zB%9IHpUrC%{kP0rlN*Vb7KT#?^hv4_vN{33dhhi-SXzc*14luvrspe-3Hagr>hcOE z6om@Q^Ob`K$yG|$CE$$r*ubm2B{AA+yXSnemjOyJPo+ zMq2zftBrL42jyV;qdVX#;2Z+x89a;!csQ4FMEDZ8ttxs)G$QIRw1WS`%|CR121I`U z3&@lL=SEq zep7}IM>)5AYambQ(-?r#aE$VK8QRYPTn8|KGXRhj28?EsxEbUWeS3mIP+aZwjZnq4&G(Ggmry`Br*61f1M?_9og7zX@lbAiH z6Y$Q!HdsXAo%CTVN0B_`}rpbNLql)=c*$u7yg8+R-4w%}@f5KsCB>L|CCW4mdm z+~0|)?obCDIa3^(^tEKM|CKy6djixurVF)+G1Z1o!JLrUlkHE`%9EsK{mKMSP2nAQ z2G6CXb83z^S&FwmDZ^cexfa=k-}fu;n54|1XJw*J4c1Hc$+}*$kxQ_|rw{b?8j@bj zc0ZONdo8*TCqqU+g-t|K8oS36Q+Yjl8j1#x!TyublkWNid}C}M#5fm*@lH&09Cpu-uoRc{z@hzbGEVVx9?xD4Um|OhUNnAneOLV(^5;yzdOzo(Gta-Ne9j|j2XP@X z!p((8dXh}u>j_r(q&MI~tlX~;kMn5-l{@MiRrvDE{ZI(_1)V>Tq-)eXF2R?z0))mc zTyT$S1^i~z{K|W(7yl|ScR`?1DvLMw{=odX_gBuFd(VRESy_RhOBXMesz1%DTv8d3 zf0c_t-Mvu!`R*kF(YC0bCD|1t%O}chvI4{A-ZOVe<-C#e7FJaUq@*BK)zu3`^s^T( zo-ehXE!!Y-@4tU(br#YotW^F=amn%%moAWU^^`4KdVlq@zwqU+oLTuIFX}G=tOHyG zwP474V6a(CF5W{l65%^gpIDjmD8Pm!mlVK6L;OE%uS`2u(Q@*$?{2IBRYOo#H{T6h zWDE}TjCTza%IQ4Qq_k6DSq&I;JGCDA*8}T*ki8zjIs7c9oYkZ_sA&7$dpACiqFnzM zar81#TmRnQ#APuSm97_RA?e^O!!v@s(Ztvs$Y$sx_yod~9}C7wA0yaM8A1$Uu!cxO zN(mwGRDaq=@JLi@e2SoII=}WwrAqud-ATNFL$N}EPSIp!=Sz(${EBWlUcjQPe8eWj zF?M~K=-(r3z;iezl${6-mf@|fYJdF!gD9hOBK=2<9kvPZ4sD$`9F0l28vYHucf1?g zYJOOucs~qXxXYST!SgbOOyp}cu7*4l;`2}%NP{kB%AhhTiyrGw5JQXhjEpvCNyq)_vNqU-!_@+2<5l^JLKOyNZ4pyjhC1v zF)<;JyRNBMhHM5h|x9(Vq-{XWH6{&C30%VRq}{L>~*$FD#eSt zWb8#Kvdz{79T+As7)JUqjG-`0AHcA<8N&>@;@_GNQu3j6FPCwNbhp@#Ll?k!28iMr zU;+^Z7TQtd^di{Tn!~M5IcS)pg?c zYhRK-)^f*XyuTg!`Z?Gn%e4LAp63-39gd4IP5@IB$Bao8)GmFuMH%{O$5wUdtG>DZ z{@Y&p>~bE5cTo7SsU$H}^PsdJ|9*>tv(8yZL@;0pVpx)lZFo#PcZz zVXz;Nhek^Jal=RQ(4zmS4K25khj-&xVt8%tb9e-TP!uPU(yg@DCRjP(uEhzL3&)*K zLM9`Jd)0R*X7HzQT87Icx{u2w#2MJ<*`&_E{;v`<(COWYV9Y8TQWR~>|OqSFl{+-4KtOXVN#_|me01_pO6Ko>h>I#Y*qW#;6Bp) zTW3mkbnwK&>Ek{CFw>N7F!%0>9nU!7q-{n9R#)oM9x8CG2B_^d`=_*Y>ARQLS1 zA6z=^5+$3b4nGZe3_=0Ja2tjp2f#c!aqstqAYF^EZd&vH8^4qewA1)CU}GR_qA-HM z2+l-F1sriv?sK8roV;o`O1C35k4asmG%Um=U=p{Z84$_00&69(WR;RP0O<)Zj5|mx z0zvk59scm46Y_HYDV$bDB@MiDd3W1Z`9)1TwF$BSayf_&gh|3Gqv7QQ1kcK7qW`E3 zEw_{*$h^3x_Z_0s5r-3cnEnGF#4L?|MGA~EK=hY~1$+9WY;o4aKc((VzCKt3Zt zbLmoDMO&iw$k7CepTcPwE|b{*uuMYyaI5r3VTse0)z@Q9%Bj+Dxb2YqT~F$_zyOJ| zf)t%}rP9!;g7+9i9fW61P7WE9((xXUz~c8MM_d-(?_5E^bC|Z78TrX*#P?xn6EDmy-9V7o>ReH z)*aBt;08aPZ1Y@sLItn0UjlK5J15oZ%hh~`9jjGvoAV;TZAP3ho1iA*t~~aNO53>{ zGEN)Ay3BM^_*8=g4vI#$`y?#Xr5i`(P8??@Z~>ZdK`j%qZ{IsIhI;oZ7;xxqe!Ib{ zjlKT+9SVW7?i#2oE#id%g`DOs==!$jkd&RCKknTGosoRcNa`M4A~T0%=XXH4FmV#J zciK-Y(o9rFPW!jOVNRTO(3S!_!nwgNik})HbsVMh8%Wwb$Cboic%i(=@4xKT5(ac3t=Zx9~o&)t@?nW@b zGv+FFqD63F;@ z$9rtby!+lUF>eic59Iwkv=&fLL3S>dZ|hrHc^rN=O_uQ@Skk#Z0 z+KkSmYsRv_1Gy^H4 zn}uYU(|mayugGofh`r+5WnTxTEyz<2tgZ_(ksvZ(4eWPt1|51CjL-?3fi&qBDNU{) zepa3JdVj6Mke8>^=jR$UcS8H?iLbKVztOI91S|%7(3})t_*!C8_WHYREU!a?&7nh_ zJ;}yAv%PnB`0H#o0#CD(R8rVZ`*+Ri#P9caNy*zXQ;>aFeI(G zneCm)&dZ6JYzdsTQxOMFhV6ugz2^G&UnRJJzLSH6|u;s~w;HrVih z4H8xkKv6Pj#p^mgY5AsIx;8UO6Il|gD7qtq;ei3Ca+zL68k(=GgiZ!KoVp@W0mv`Z zX@nZCB^Wsn+GLL*E-%XRxk)w2zf8clrth=qEMco)jwlg5q#RQHCy9w=I{-2$hxyQj zmEy4}`{w@1XSsW5<>JK)m&kV8xauWy7S5V0ayE3%(#3brS@tql{^P#(XO2o+(2I2v z8$ens7`74ECXwTV4-Q`q($@h06<~dkP2_tOEvoJCEUwE!khBC4rFSrd(Lf=un`U{t zc!a2t(VR4`-5(#{Gg-=gxecDAJuIYnoN=WHY*JRU?k667bF!pd?S=aZHa5kE!jtXV zrakkCgh2$i;T=eaIKPC{Z$+cajW2 z1uZzsh$6^9Q?iDih|TCYFO57K`L2-X=%|6>%?#_b(X=(Bql7FY!P^nRSQVE&E4l2y z>XFcj-)A|!k#q_a@*8m0Z7_!WcnQj(gA^ho4C%5fG_2C>UjIrOxD_#V^eTElnx9u| zo_0vX6+hcS>LBIO^ER3wC^OQl{(ou6Z8t9|-{lt7Lu8SJEt>*KVc^|8>UXJO>WJGQ z7B*m*I}gABPe6|r+tKzHX^b&sJxd><^#dRDG9d#_+C8LD@DfOq+hq!JNl|HNBDDr~ zFAhp#5cZ7%P0%&{SwbUHJIU5kqs8wS6bRnPken6KM(tj@`JB26F0tn+aTQps6q)22 z>-tpXc{SRF!~T5$=xfF>qxio`uilX+r$brPP%?n!RK|WDIpfq>7r2~X>R}c z>aNM+8SFeDbWpZBkjjvmW=N(m7;ZNK+!<2q|H?k(7o@f#*X{b9RMrGDXAU`a&WtRN z7GBqRL2BYg!Un@l`mS8Rjw5ITq|~Uunw)BwknW@HwCLlE(AH%Zy|mx4=dwV?fA}J}Bta zQkK@YY?q;zU?=TN4Ov}jLFH(KGUgW*=w7^sqH>2YblyNU8LC`K<~apgORQ%=ziHyW zyGzjzkkq$kvx=EGLq^?!)R@Pgrp0meyevZPh&n*-Af}E=Dh^nGY4c$WS;G2u6Z_O^ml~6Y;qbdyP0sZ-nW$lSyeo-)@xL=B^}QFWRjK-`HF$ zXV%zl7RsJcH&KzHJTU@_}-W{Y-R zT=R(tjUdYbatmom=WyOVK4Oe}bvj>IISG-pM%p+3NL0;7(+-kNFwHXl&a7#}y2Ra$ zTbx6H1)7j)SlQSrmn|R+AuNQ2pSFPV01xfcdv5DLJ#-u24^Fmwp<7^ioW}%0I15gL z+aq@}b&x3K`ZxnYORD8AZ9ZOn`ug8~^WRObcZPR0oLTva>=V67*22;N=SVS=$jX|+ zCHO5Uy^o=lsIixh?p-QSP1${|q#;ugIx$H?_I##Hbq95ru%?uFE%9QX zwhNk%ics;$y+obG7o^TgpK;ry^bwi;3p4sf!gm&ynk|@#Fz`ur})X&5u!P)eV*eZxD zJL!F78p@*j1A*dE!Dv??E2i+(^EYWXi)4D}7HAH}?UqoAL)(&_hm=V;!kmYxDLJ`m zY1wMwY-z2w9TuS>WZK4DC+IZfabYOaDvJ0-c!9)1^Vx@0;OEDM|Ng0a$JC zD#K`E_Y$~)20#!9(q}B8r!I*sXEcyjOv)=Wak>IO6k0!b#V6&3i3?F?bmAE25_1*a)Qwy+QAA~ zE+~IY!Xo)!!4*;`gY`+^M?O-)U7(FFFwmYtBXVko-dCTf;LpG&k_)97gmAh}(;c6B zNTq!a)Kfa0$t(!Qr1umTy4Bv>;Wgag%dqOb>Prq;A3F4i+Iv6TLbzf+t3B+uXyDBW za1T6%J4ypOdp|#~vG&U2DtIH_i3=kvI5*r%Xsm61LIv-|&*Qu=qUXHfr1<+E*Q?;O zcn8jhd@L9C@|uG5{RRmv9%s9WTHLp2^kJYlDCO&gEAQ{SCLd?Lz=VuC@Yl7QmeEdRt<#kS&BYFK%*Vs}a=l4%wWb{T;cSPKl&&mUK48@{7A zQDe&b=C~uqG~=-1JJiGE{SSYTZigJ5)Gk^lSfP=l&5YT=*+dB<=@2!0BA+Qll4+U+hmf^natX$=Z z{##v3sw&Xr!}(cb{QY$OsA9)mv;G2B!Ph_=7?qJ}i3Ub3c?8TEIVoCT?=OV`(7X<% zng*ANnw%-jOmz*2<>uYCh;@;rI^Vz4f-#Hq2HJ+(C|lYLg~Em7OP2lipDgQ_JK4{W1*^Ja!w<#X^D*4JHLaesNr70aZQVGw3{Co!~9O z52)@>>1El8D;x<&K_fIznjz0zkMUoeLZZ1Y@axVic^vd+?U>$;UQ#@9?X)aG!t^_Ns_X&T2j(K zpGx3pfje;4;^P@}f`-K6u^kB(w!(R|$H5@C>a>(cu=Z>M+zCtc88N|-9!>hFPk)!d zeh_YhWRVLp`EFc;KXfPo{|xTN*-#vzU`oE5l>Rat$^E69Z|1B264l8_YDX=w7rm3lIJMYjx??;jtWpE|#rV zqXA?#zW#K@yD}Mrv}eIoT`?0h7b)PIPn7VtU9grpMPP)`4ML+xHe?8NCnh@!meDCJptT&Y_KjLX4& zl#h1}Dx3WvV^a{U?UCtAS|529210=uCUJZ9o-v=isj|V{j2{G{&~ZY%De9iOkA?Kx>~(3NJ;Y8 zPpp1GBsM27O#FNBEa`8}dykA`s~0Y)Ts$i$O2PH_==YDss2 z&)~`T>b0X?3d+*e;Je6UU~m}f@Tu9#2XB9LlX&tv5m$18)J1%}5cMX#^y`$LEC2cc zE=nnbD5dn;f_;UM3Vb(#?}(H;)oY)X5-JnIe|Z{~z;`7K|;VuU{&DZ{r$p1)c*BAjAkzz$(Zx zh5h;so8+=_d@Hz4m>h4&F2gQG=uffkuT+V_x<3OnqTJ0 zKh<5kAk#ewR*~ks43i~4J=vf-qx3iddc+<9X_i_Nvve682IjIpf@OHIUZe42x57aS zJVNG~j0O2dOTIRa7f*jFMbC3BFpsfE5bX*lm8$#r{c@@2K6nCV5aif&oEoEX^8F_Y z-jlE!&@K-{Ih{!o>4U=x-lK2o@^W*lwqk`bT9&pI?DRFlntA*eV za29Y;E<->-Cg^ka%9!gLr6na&*-xB@bXpo>(o>U`&BwU0P`G;5D&3Fqu_*5b8g?MV+K44M*d>JZ^umtrU!#5D?#5Ez`rEIV2-T) z+iuB8eEWYDp{91jiVGXQctME|Zv}O)kEby-nDkKv>@%*KsR}BAmFlx}{vRM|9b@*8~9BhZN|(3^*l{H^8sC@E!i!pWZdS#?Rfsta5V&+n z&uJT;P@qT1D}*at5Vwa4quT4GGy4?iCaRGUGW!^GImJm|uHn7Sl8oX`Q-g@&EP^ab z2im^u*rNb%vWucav)u7v*&fXc+`Uf0`x&}H=Z{Qt=Z#45X|9a+Hi@u4m-8xk9(G6OeIJ%s{faMr+c`vL9cNov!Olbsz#T zOE{66P6^iCB=#;vxi!{1-vf1kMYI46gunnulLo-M)@usL@1(z{s#iG;UWc0)FQG{+Q-=Q}&9JnB_#{th zs8^mhZ&t})aqfYJ>`5Md&P2E7QosH?g}^rVIp}t~oF1Q3ap+^xm+aoAKzlrGfXuyv zrShgCjrHqI+u*Xp;3ttFLl@4UzjVReCE{PAPPzD>9&yTz6!lmUEGxkNQTJC?RnMDO z85k#`pL>5wpnUP%`IRDb6Yrk0aN)dVhxqazE+100T+2q<%<)FcPkhFhq^=U5QMTyp z5^JnlsirE(8E#}v*0Gniq?h{4X#=QWSy%dym@{jzvL=uOtCtHX9>7nqL*mxh;1pX_b92?W`{);S88|bZsC38f`oH0CUb8h}Z#IOiWTTh>)Zy%CVRkjbf3bIN{15-?knC&pQ z0SGN1)(nJt0Jj5n4bZOw*ai^$rDZm;29OKFcMQlHmA4Y~sh%=!!I-_^Nl-B=HWH51 z=eozGPbCXonQ2DlWbw;RrWe<*+#{YX^Z$D(CLBzwpWJ_KL#a=UvP?CW}}P0^`#r4Vp5ePf=N*x6zfqUsmjt zy=XhrQfN_Ye0oX62y&N98yy8vi z`W)TVT_Pt2e>L^Dm1pMtDf-_(v0A3L z&%Bf4!U2|#_>p#hbY>MN0dJUhadb3?Wg^+U_Q<+^B`4v%Xgz>iM-}O9WrZef92c5a z0|nX&xiLdnGW5S=5dXVRa%T*!oLwz0&$+Yiss5kgYnixY;nF2bL_=fj!iD#V ze=gfEl)u&R!e91EGO-e~l+x3P1(s#8{a{47sl*j4aFrQ`#UAv;*MSj{wD|bas=PjB zu{%RmzD42`p+;bIQ4XP`w6tVwMx4r_e`yba0PnKQd7vQA#*0R!sH61T2Y)`xJzlpF z8h`pkVDbM06cg(I@>_p@v|V`}bc;AaI=vCMBM@|H3-wCdiLJk^DnrF5_%rN4`(65n z0F%vR&9OKgcDf}dI#-cOATebV8R$Jdb+KyVeb=i+4TM7 zE;^L&G1!7}NAaCQ)3q47w%%*joKVLm8MmU&w0RuDW3 z?$Hzi(K`74KaHk$F<*LfwX~S~p;QS?5i^hI2Ie9*i^wpD(WBxKQS!ggxtDOuC+lB(RbCS7yjuv`5Hc|OVA3UM0ec|kPdfbTcl9U>>a=ec;gIT*SzSp*#aoX{U_TNL z`ff5K`tmx;2#wb1y{n|PHnCoNeA@|+*Jknh%;uzr#$77<>%JBmdR-9nxH0XOUBgZl z-0Z(hh|07sWq6{ac$&c&rNnk5t+5(-hZ``RCE$@1=_EJbZ zsAA{*J&ea0xA$R9I?9T(bK> zRw1l;Lu(E<@A^^6?-IDd;=v-42oy5fMAfhT;iERGcr?E&v=1+Ky0VKr_AISHefPU6 z^Y@neyU} zw9qosRzMHq7vLkJrT6wPV)8^IybfgNL`$qybb#}jZEijY!*tl_FV4&@^bQy~*Uakm ztQEHscHW$qT54AwXBuQnFN(|s8-+AcV>Qr%!z^m|DUOtpO7NweSLVge+9tWo;3>Qd z`8^b)7X*Vvk9aAop37>svJA;;AE;-G+}?_4X)M{xfvR_&-&WTo%dW%3WyU<-)c`zq zR@_-J+b0BIsm=#i!wMcC7Sq{ti${9hQ;TsO!6AAC7PAeTl!&jnwEFd{U83w7`JY3R zN4yFW1>?KEd*ly(ImH!G$GTE28Br5$E`j|MJGOJj${V4oDQL(o8)mEn;d}dz7#tsC zc?sx8GHU@j!PGDGB4_}Gw%?GMRElK_M^| z68$F<*kH}X@BUo^ew@8U73KQ^#RYD^=7?x-Prz@oJNZFbX4imBlT(vW&0Qb<{VDm` zTnpNw3l!Nn&MMF(r(-y)UC?r2v_Jm3w30`o0gd{71QFo|4Xy#j!`^~5aOw=w21V7) zMm&HUpg4nyCbE>I3I-B*u9g6- zd252_T7Cx?&W<=EIpL(kt@F6dvy@zi-%FK^^!i7R_9-q!O0pl?UrY3_<9855tPBUy zQG|xS^I+q{;#ksd2L%n_6G(oqt0!VImom4ynm> z6))mi87|_wWw?d&kmOkkw>fdbjxbTL#2CdirKQ!>U7NtwXgr}KEM5YbJ-GI6zV)NT zx43M)hFfqZYQo42HfE)a7*f&<0EwsOCuKb8$a~U!7LK_E%^BWE)aUlGK4?KE6K^4G zATOvsIJ(**HI{1bnO4zLREI?S_wuhc#H=x2gj3_XY3fB)Q-Z}7^HD04mmUb_X85%$ z-?m#VD*QY1Ix1X{<_hJfI5l|tjRgFZr3FvJiGp+jBwZ{vJu2f5Aw!F`6?X+J+*&b>pDuNm5nqu>z3=;cFpqx;as|Xd4IriQLT^~semhJrKr$~{4Yy)zrhdcIf6b7B(wd1=87Z4^;{!=K$R0iW#&7^`G4g)_}Cprh=p%FP~O=m=V!Po~EQIY^>sw4u$1H6l^D3b0$3uhWyq# zFIoe_6|?ukG`C>|5ciz0U=KhGl5oBA`Q@*+oRkuh|Hs`DN=?x9@>jh~tl~b)?$gJh?^~=hXu|lLKPVK$ z23xq}xwdd=%p4k+^d$1bs|p6`#VuEtTjuOT7uX}(%i#A9CSib+dI&1U26^=SS%31pDPYAIUUb8Z}pPdB<#$~!tuV@1XZHx zMx`k2wBtlH*RdA3e-YGCw1F^; zm{B!n^oSwx5YdPaC>KV=8^CI?4O|1sYy5qszZ=m~|6SnzB;bdieEVTy#dw?3rcCp> zC*S2&uJU+ks{Zwu(!hn7PXF@ssljn{FK6GJ=B;hX0nU-D%h2$_H|h=M4B zh^R;@1ZOF>I8>>%5fCCGq==9rg_I&tKtQAzkpdzDVhV_ehzKbnP*hAQMM@EV@AT#U z&OPV+&bjxw_j>O0+&{kON#3>g+Vk3Lue}E61o`6AeIMEgJ7O2})ykfl)UB7x@xyyz ze;0*|u{jmRocKloY0S)S&@Cysq^JS&*bcw@)g|GEZ`9Y5}o@jr>(@!*8V?wx3V zl?Dxq4avLZ-VEBLW!lhpe*JOd(MKBABX$|WcGvXe$5&RmMg<-sR|5YNTr-F)LHE?V zYI1*i--HRH3x<*dg+`$Cp+|cbfU;5IC~yS~7_Y1bOfv{?hIcfB9uJjo1hogz&t`z) z8vpQKv%sSp;AzlsN9FYo{2mN{0rZ;7f-|d5X-(1?L%jX-xAK(%2 zA*{IF$Uf@wr&DLaPx=(sl#Y6IGx#2i8CQ}l%kP;gEA$nL-H75lRv}%iuYPbg_z?8y z@n`Th=w6$wjz4(gixB0L#h$`>U>BJ58xXrrt!00N{lvc*V8wFx$c-ffZn)!~`=^1& zYm$AERl-DKJUb8MPP$JIjW~2CBpHfz%@O z3RnVaho^2R{pr|>ZoWLe7|(Z(@6G@Jr2T(o(k#ut-xRa{{?Dbq+jP{pet4IbFN_6* zLm)N2xPP%4uIzCJd;@Z`!We&czWvIg&y9=me}>y7hy3R1U+4LCIfR_q?P6p|vBgzi zX!^K$rx|RI@2uD#jw7--ffKf}$~eE?{%-eN1EG`+E$MbXmQUassbAPg2q_~dXPQI- z4FKNJTfg$w2WEjh*45f=W|WDu0C6=E9Z*P8E|r}S0WVy&DC-CC#%`;_O0+IavMR;8 zZcIC>xVJA`NQJC#No8l0qj5SYB1#|`%}8QU(+LV*;Ht3i*bghu3T#*xyxPXZK@~sK2U5z{82E%!xE9s1!kvfAH(pI%Pk_;Dg%ZcPyI)*o&EqXsQzGth}huxa$CJ0e5QagBD`6Z5$V9G)Z zQJ?X{RmWmamsyF~-LTcv;Go!h~d0ZuME_jzMoPD$6+DfYn8*46v z;}E!W5ax3dV|=x|tB>1j_J=u=aq|T0aT@urRqtmO@&1|>VXvR1Aap4#jU$iG>tPti zS^%Pf{K}dxYK^tqB5@W82?iG(YE%B!g)p!7O2{jTibv*D$F}8PuXiD|*0zTvftO@H z8{vhGT?p%I7e+N4c~wOEoaoWbCQxpfDkUYzjz z2r}gK^rN@Uc23&-gNtka+a8=4yFtJ5kJIbzKXL5C_r?Z3c>e=GANv%mTsQWok8R&D zAvXB&@p`>uCp^juMjXHgC)^(!Hg>}O_f9(G8Tv~5$q!pW!}}b&mBWrbGU^R5{^1Jm z1n({A7`_k;>$w9Q0Rz+bz&n}YdBdr_s0pkCx6TCNB`|pf^qvW#7Xf!??GyPEr9pD6 z>ON-Ft&#kqct2^_@TuV53H!k4DPRHk`7-d-sGs$J4m|lWDCiZ7kEyPzPUPdo#ErPu zSL{mCZdM|_^1}o}pd?8EK#@d&&LgLRXTe_mt{(AwdimUy+=zHtH#LfBa{Vs4UP5l`#9aS)OPk;9WnAq#UP z{BE5Ad%YZ0i~JPFXwe|^JV^NgLk8=wyQg?`uZMt3^aOk?CNgS%pX5;ZP^1M+P}6BT zp*?f&#J*#m1-IN;Vrr52r#s+~VdEH*(eu7G30tftTFmWSah;@&? z1C&1iWr*Yt3%>>7aPlXgz>>E>(H+Bvz2Xx-)lCAT=a926E} z9H|f8Qc!UU2&-Y?9&k^;I<^%QvRnl7_(Hj=rvnz#=|){dI|?SYg0f1fF7|{GDJ&;c zq!rO80oRPGCWE`4>@gSQwSnkleS3`%ZefR~@4KN$oCe&($Xi_X1+G4D8Q2Zd(?DuH z?9JUVv~Z|*XlO#oNOl^a4uWViKrNu)iGi))&Sp^A1lUQGzZUd- z@GRJhwEVvAWbC(~+ueP--|Fg{a!4GJUN*Q5{0Vfz7vLcM zqFH<2&+$8+R_esM@WAPS{t4GDC4V(szV8|)>0T>z|SiA__-URNxbMP_v z0je9&t6X)z48H`D>oxd|E=jKgzq&oxuh-~npbdUZyn@$G2e*#9alpu42SHxs(LRG~ z{548JFA!D;M2VD33;IP4^QX&eJ_dNP&ff_aUsit?R~_BptK!4T;&awHR}>`2UrA|Sg=I(J;^uWJBdE2M)26kCNQMmLeK_g0ovom zzX#KR)(D6hKzy3`6F3WLv94ffl@i*C8e#w0V9Y=%bSPJb&1jR@5j zgmUVhXw-Xk7Ayoq?;I020K6N(kY)In;3#mf2EF_B<%_GL-G8Rtnty*L8E1gyJMLIr zjmh20{JEHFTM<4t|JVnnVr=Cd%W6=vguru)t+45)HAm-LXLhbL;jMR0tu3Rel2VE; zb^_BkzG1>k*wC>%TlIApz%eRD0$heft^fd?Phk{i#jQ4F_DTvlfeU1LC>;)tH{+S=RSHE&GL{ZAfevK_AdB29z>-)C*wGt7?F4^bc=|S zi1p)xJg&Z^+w%OM^7&H6~t9{UQBb0*DoD5>NX+({AgxL zjPuk)d3SYIG`qjq;3cCEl*B}(Aj;WK|5lX269zcSs_mn%bW=kvpGOWrl_9-E*na1D z^)FWW6Qj>nRA?m+mAi@`bX0L|zqZL=7=5+4rbu#C=gV2HyDLuGr7w;?Tv|ZMHx$ys z^^Try#oul4{vRJIBS*y{x;tjQg8?H#){12|@yTN*SELzrP#&w?=)~CCcG>`^Sl@*) z8_Pj~IzG_=c*IjU2RJ6Ld$&T{u49E=$ zsjP>nGsg_Dmt~DgTm^Kf>;aqX5}WMmu?va|`o%r@y%Sz17<}tTHrZuk7gZFv6aDf$ z$-d6Cv^5#v1S_8zd!?917)wLaB|$q^gIRO)nM2RDnL+xOG;A*_&Z+EIlI+&ksbTl3 zCGV`W7G=Z!f=U2;mP6FTvFccHz;58?hRf+Roj$4w>QPM+GYHCQ<)V!bR{kZcbm6UjAH(I#E z0U!RI4c<8Jd~urLEAv>cn=>Vi9~xkTJ&fCuFAvROq#;SxY1-~--*2%xernwMq8tp% zO=4J>2)aj>Yv%JA>KpHwTvD$O zYcB|TWNoMyje$wCo*nlz73DH~PZpySQ4%q39BG7=4-A;WUw>l|nk2Ep;BmK%{mIyg zcJS(N#GzZyy?5w=hL-^Q9KbN0x3M|0>fwF#&7eZu0vbkC7WFTiP&Z;iGq`g-7&Zeu zeNPiy0Y)dvVu7NS`tiJ4=lXj=q6Du9)C_uJJ*a;uG$Lovos)*m0Sn=3a^OOwA9wwi zftr<|?g)tV$?gBpg#MNNa{8<50pE|WQdfh=9>`q+Di4C5PnPtlx7bb4JR#=)k7-p` z46E&5{o~X1#;wdXmD%e_;&Ez7n8PWZt>R=sz-I1S=l{vhK1D5aQ6+tNy0kZw6->U( zgvVHQCA-CSU80)1BQNE}+&>K#NwyW~78Aq6(x;dXSD|_xvN!s3ufE%AxE=``*!3=k z&mZ~AH2~TMF|92-r@v)HYL|?riSz={xZ<}g%!tkxMP7Z6 z9l&^beE|%wz^mT?wmPwKquE*`7YVmoQ=$n)jzv{RowNUo4EzMYSB)xaIHoEQM_ai6 zy$pPja8ijYu2hc8o#PmJYMfBiOS_)HWK_+B8;i?=oaWlAQ;;5m=bn)|^s)Eo@M~;7{6->%4$gQ6V z)_|IdrTX4VHfUk%K1y8&=10BQulgDk|uIV4r% zc%`;}+O>-UXWVX_i2G1>a=qP$Gw{j5D>@u-E`(==Z|XQ?!gbMSO=P2Mu=jfDH9!&~ z&puXSI|E+*$0n0Mif2MsTs58?&Q*R}G&s=l>Fa#<;wGz#z2W_GX?`SLQ4mdJ`4OG^ zP_N>DLeik?$KU(J*vB53Xq~r9xS=0yYPodDPzcM|1-h=dru+(j?k3(_8!c-wC7K4&o%$OSm3hr#jY1vvL}W*w9|$9Nt|c^>sjdX~_Dk zT#S!Gl!t|kwRQ+IyYjX7k%7ICyhyomjEv(L;e|j603gH=Ci+meZgut__o9ZLY|(jo z9$oGuI0`2u5>ZNyg3}^J@;rfO0kL);GCXfP*go!XMcfl9 zPdM=_ul@0T6L>-%dYy+$_IL9ZZ>Ee^uI=1y`gk9bPl95K?OQ@J{jFA+!O6baZ5F*K z=eTwG$wxpoD+l)ltLPqO4vcFhH^p3qH#;vD-<`FfSCuQUI;h5LLQ29pGG?E&pv%H19=%a?qj8_O}+N`Zo?&$YS-G(Z^2!*H`cEGzc&59I@Cij zrFe>SRdy2&gCTle; zbv;%X^d*Zz-W zz55iX9w^P!_kfrvi)5jEV2pSP8)^3JrwU+EGH?^;_vc@q-wRKLl!D62T$K;-6?H)E z2Ys5+tj(*~h6*-y!d(;)Ybx{`w-{HGn1V|*CsHy}@dPQdB2UYtjM+isPQA9E%E*(j z$J>gA4E>!EDcVeCz4PFOCPTi;2G~RYmm||&+X#%EH`&t+qhV6#7c55+hQ&Q6vb3Vg zB4a;Yx{Zap<3nWHRC-PzywsxKwB77}H#N4xvje9vg2d?ndk^Z*HG*1_5`upCc%7!c z0Cc`Fs2^Gg3Jw1J<=SUoHeTN7MV@9r_dzbJ6OHd01Etrn!*dql-K`p0wwX0(EIHRZ z8OBrA*ZI3wH9uy2oZ~$Shuvv?{PunQ;}0K7?pto?+SfnLxK}SBv~FdZtEyCW7>(&( zJ)()AG#5pCG}1YzPg|z4;2fa@3xaAOKjO%>mk!KX+h#_RxPs;&aXU0)?a=}huspXn z>>q0{g{_x=f4d=3&qD1uep@|6BYGhxTEadfEv;%$kb6->{5`;r_^~P#7;dXbp1o>H z<9qPcK=yh>$>$avCzf550XvUxrz3eefpFT6TxlxSzGaO~u$ov%hk7(zKdA2@sS%J_ zlK$-XFH?r+5% zS`gu!&hL>Cv&+zr;4;I@6sblO9^wk`+{@qmendkd8=6Tiq2dZHF-Q)wB+evMO2nZQ zLKvbQVRzqO&Fa@tt#mvb2qz-`NH$9}ft}PcDx4~cM{*0Z&W!12OyCu23lR)^+@Xj& zOJu!v*#usoJ1MWr8}wzrISg;{Z)C<}?Jx)B6tj^`;g}#n;FmEV zSahUpdM@--*ZW^WNvXM*Q zpw75{`@$W@=rr+XDK~)&G}Q0qI4k)F;Kt+;Y}hziI+k%blbUlqoS}OI&8j?l?z zY7H+VuIumRli>c;+n`qxlUTw9>9RrTG5yAj8FoW`{pj?4crEGwhBHV?(>jv6tp7->Ex~zWyErc9|q=e(5gfn?6B9xv2sRl`0 zB%r-HOj%^zYj2sMPS)d1YRcm;PP=_2jwIgs^*gX3&8n;MEy}RGq5hskC0!BdnU0Ya zr1&*pe{5T&oc{BBUmiA%Qnr)rO1DDQU0I}foLzS2Tb)iFTX2QkDY`hEmMKW&@`UOo z5K90g3;LD;A_I`mjp&pJGkHQyciU6%7%e0ZQHPZ~y#Kb|eMiiC!z{an+9q+6xGJ$I zE3@OZgC;nb4bH5Ug&i-xwsyPO=2O&aH7slS5y@5H3GZ+@5=_jaaTjmqBgnB=Q)v;=Lf z7UlKKYR%0h`g-_yKgR;NbEyv1SIZXVvh1b-BN2p~l#rwnkY*9i(tynoa55_l%(_{6 z2^UMZC@W?5R;x>RnGziB1Hvw*5$I}WovsJR@VRq0)Ym$X_0wd zXnRSAR6^28iZvvmhHnNxF0TcdIm!Wjxj3`Ni!C2A7m30LI0BP?kf!jX!xAb-2XjB~9ixelh1YRbQCx^gkUg0TDpdIXOhpd*)^>$ExoJjEiBSb(J zIeE+uAKwIj_=DhMe&`3srd+;ccnc_3!6_i*`Xg~ql8t&EX#^SVj4nergF~oSuD`H8 z6|lX)pcN)mzl}b96?na6r9PjXRsy%;wzpEojcF=40JSJrYTuZqUw$!YEQ6z9E>aX# z;<%7sUxk#%*R9Nn%=Yapz3|W2F_XCtvX;9&o)`7!GhRh;bAI#%5Z#E8Fs5cezej!3 z0W~gMI3Rx&d{iKTJaQg@MaUDb8c?$fJn$?iQ!s%75-B|P6d%UpL^OVVGRy%%U-Xe0 zEGO&2zx!WvpZR~I$}XqWzx?Ceb5?SYui+7-X+3+mTs?X^;aBEQ*2kcRO)o*aA;A%l zQgDDM1R4D{K`X`aQn@Syp4hjI1$yPk-g?IZdHzRMuQxF3p+*pD9>+#y{r*rS z3f5}n4Smm>A6qn9m_sNi1WH4)za;B^b3lhiSY;h^hM;e)ngRkh5rd--C+!#Vt%tw= z!|f*9VVA&Sgr`a}R}7Qo%|By}#18Ij6jgMt#Q6$+JRz3(v>c7G6Pubr5SIVhYQ=f( zEYRtc>U7Go`uSJ06+)wM1dj`;^765@zt1`Xr|&&{;r4$A?^>&`9{kQwdg*(8Dqq&k z%X%w)jL#vy@0?ZjG+j*7I9hP=RMsi<-3J!*0KX0if=l9MCF>S2|7&ZAw+Lr}#NmiC zRt>>QF_+&O2Hu#6+5cQ_(r6cEKuw}KkDO8Tm^X=w7W9a)6AGySBj*OQVlqv?U_p0_ zi$K_|dLtgimsR$%T~^!)+)^aZBZt#Y+1XcgsLJ9qrEU6XJf?p+|K5t1rkF8%_ehIi z((ef-0$RusB^Q6c-0V+_yaWV=nxCk8S8&LANEo!96r_+bCXFl1S~tiCq2NmSMJ+er z+_cwDv!J`>6CennI|MLni7W=vcNwX6@t^)DM5IyvYsS+V+O6Qi?4^ z`WYAuAw0`c*HkH$ErKZwE6s&imW#r^T*FCm)CQ0TK{O3u%mID3!Hm7Nnmh;!StJx? z45`ggn?J>PAdy#7)6f796L#r>dzHdk3R2O0^D*@~bEy3w566Twz<8(d@g_64Z!6UT z@>GH=Q0xaBWNN5p!iHKl-ArG=!ClHDsCQ_weonD)I~ZRhkHR*Ck#{DZ_C1N0@ePsH zprPxLZ1<7LC=fDLRiTc2#Znm)t zP`&^u0f~84s?9@9EnlZezf-55q`Bf8iZ5~4%QZ9V;xujzic?~Bg3hk{jLU#6<&MB8 zH^)RUUJQxXqxqMu+=&s8CjYNuxif^!g-#(Q*AQ zC?GOg&l53+_6l=quITmlR@itS7ZY>J&yMSTl@9XtgE=xkO#(I-x1TP(X4uJ1q@ftv z&R>E-opz96qlWv9iUZn6lwqw`QzLki((fFuqx>FlqhHL6u@I>w5`8phRmPawqc=%2 zz8k*?X^0K0q}>yXxt=j7C@o4O=%ronFXUDMZCvyz#qs#~?sw0hIc%7B{ClLXW!%}m z(zyN@dq?G{I%CfUB-}? z2p6axmJ)6hBrHo;_By561B(^-E-~L#A*kl}# zE}XK4Eoi2AT5gWWdT|CAtg!jF$V`zF5OCjW6F5uUi1H*?ajvXny(KMw&aD56xB>o1 zAoE9ygmrnKOeN;4WJ4(%TPL;aLjcGqgXl2h>QNv9S|*K|fgr>RR#j0`yFbN9E*Cp5 zwZL03OyV%i%VQWtW0>N?Fy4b<{uqW0H48)x|B2JTBY$|#{a1eIJ99tzpm|(FIh(tO z+#{3^?)xgJUJkl_2E4xpO0B>2HSh+=E3JNT><6IlFCYCAa6A-i|GP!9Jl?+DKc{Jj z8Ev4?7RC#J>IdYI0tj+R3=23Z!N2OoCOpAPqYjXz0QT@;z!k#myt9O{;XeD$qEX4lH^X+knk|*%vNt4^CG4m`5ng~_7l1^6hc$loTo-)eZc@Qup$xGCr=nHQ zT5w(L-vdsNVTw&fXeLX&{n-_3IJ_*o5p0H*a;K{Y+szBZ5pW5GF)SXzuq=y+H)eH_ zJ^>CICr!|Wp)6ML(&;XQ$*`5kr%^CX*^WFWD|q|)u2EP4n7o`Po7Lpj+2oIJeV7_~-3*i84LqSQ6Mr18Z)%?PdE`+P_B-GCeEy6P{r?IO} zb|K6{hsZFAln9Znh56#GE`)7pGty$^Q8io{addSbedr7|+JwT28jfTPt;{yO{c#t< zWpt5r^HR_w$Pq_AdFhW`2rKcacy~ALuJTYGXMKOMw+mq>ei-l0(eWyt%9@jxc3TM5 zZ1e(kg&~T|hur-X7sa^5ZvY=8M)xqDYv@91{AJnT!BMci3W*Hb?1 zLfFn+rmm05@%}OUrQT%QFMZsFaDi!I?)J-tBR#hKV9F;i?e9Y9U?x+&qhhd6Ob9s$ z?|x(<6tcc)+7&8{=ZmvJzX$R8An!x;dvL3J0O_2H@BY);(y9L(xyz&REz^W>4!4ux zSdPLdKSg>;hzl_qkosknry=3dC?_}UzYcdbWCp(!ns-}~;#AI1%Q8aR8z{&mEikxR zyS<0m^W0K!!=PKrigL0v$nSpK)VxK9>n&&!jzNvWaD@Umg8=De0=*;pO);F5{%)D$^XiZ_5<+c%%{5aLihuC^&zqITy1)nq&_KLW3SyJ`!2{p9*u z_bvC@obvlW%)k$`^9UoiNPuUuZsg7LGVR;VokG9- zQBmzPqY5om9${R5w*4spL_oX0Q+^(|QSU#WS0OTKhyJB~8Te7|FevBPR2geawB|v) z`^d9r%x5I-0(W1jKu0ThCgCjQ=EEj9pY?9%CzT73qY$a7`c%2}QS#9?s_C$Dc;B=3 zY+d9xL9fJ1Udfj%iNtNYRzrQb|Jbv3Yvu?oAYV{R3o=r&*_!5k8Td9~KP--_{*ssy z$bxrd;2VX5z|E*p7cXT!C-2|&thM-Dox&!97E*pSm>Zy(Zpmb2m31h@&4BtxuPq*D z7&M&{E&)Z5y*?Qks$yPX5b5lNbvrWEofVpZ#)wfDD`Xw-yWcb6B|6&>4}&~E(B(;j zmKafCX;;`KLX`0Mt-t+uh+X;+>VT(0}SPIm!&lyMF^@Bl6%_;6VJ_3tED|) zF|ggscX$5&`@fsb*(gs4^J3Lc7}c%BwK9Ocd`cWG0mTic{& z5NA9?5-cEdSSpcZ>`NzOyudWQW#IkrXTv}Bv!TO08+x!M*aguO=czHl2mGsnG8Y7^ zq^jVUA$2$P`_(gx!O-igyfGpNM37JLc#8%*=Q!5T`~Pg=E*5;?fXT`8S>IH&9`zhq zGQ56F&!T?vDE-EVGv&43@~)S^w&vZF_n33CA3w?BqJEAeiG(DF6K)Y9ibaU?P>_r< zq$@}}=1KcIr`U77fH=nLZFJ{wWLBVo#&c7wGs<&`n9O-4(M_O0swl+B2)Gl96)ll8 z_H4&j8A=Pui$rN&AYPFUX4wbt{yYP}NN!@hN}|-K#>=vd=jUeNE2vgl3#GhjIBlD} znh|(E&cHWOQ)wlXr|;Qxmd0}bCmHx&>J+6#iou$-~ z;UAfB7fT+X7m|Em+lJxu@4m81U7^pDew?`}fY_TIX5RT(hU$5G5m1y^(j~`pomcI) zMJBwAja;EG5;xBQ>5(~QA}ix6CR4fLbZOm>OMU}f-5kH5OJ865aETFfQ(y&`Mt#4Y3dy;E#nv6DH$dfkyY%i@S< z2^@!EYgIAkEAWSzK|aD9qXmlbC{(O(Om^D|zl@dHwj_gdklh3F@?4sZ<}RzqFUU%2 z)Y>%>+D11DwS0+P@93v2LXa59mh>w}QpX zxDtPT%8q!w!s7QTOB|M90b3vwxp~DpE zR{?1WJD3qxarf_Dym%ZL5pNr{L;^t%14%IqK-Af7yI(a?s@T{}cMDhv)`Q={y+j+h zrwRW%ya2w!e>Lt|xCXq123LT)>%cSpQ2!aGQOM4Q@0bZ8;vQ ztQk4<<-b^h#v1PpY^0~ggnL+W8fCiLK0D6<_h9o6`9`P-iAGeIhh(XTQNjeS1#l7| zBEXrJ8EQzP6x9mSEtw9bFPMe(eqHbmQV|^pl1L)~mX+qO^Em_Me}E2*8G8KV#&@O} zxyYD}pl0l_R8euC%xidv<(}M)G=^1NJdt~X}*)OBOIG#V5VxSbOp-bRA z66qOWG0c_4;B{ffqn`vJnVbTqLVXeTgE@B?JN=D=pG-15lv|Cv^h>3h zu|woc1HtJ=qx6$kvfZiI7DTD7;!Yep;e zD$c-dfI*1X7(N&iZ5@os0=CYy%eBL=VcKPt>s)D+(?52=?Jz^EbA{Dq{t7$?j1VL; z&1E_M%x<;`U4Sk6(Ai~{*=1IuqoA9cbyxbBYz6l$yG#>02XgItI+og%FT&44FvkA4 z`uR^M8D{N^@Fi%nE`yNP_pMW2own38YtI5$Nd|U&)bx*EZ!`_Y+wn^fE3!(o{lTE* zW2qzfRIm=zccK4bx{2=2f*AOxo6H(?Di`s~T~xL$H>l_z=Ml@0VSHeod%w3oE+MW$ zkhVX5VSijk%z?vcyAh}Dk5`Cu;C90LxbCm^$92SdI0&~Z`qKEQbG!{i(bHvJjXgcZ zY^;8SHj)c;QNUVvyLUBzf6V+knLGzFU)$a{zZ%afB$gKm_vwbDs%|v;0(Y zF6xPcvL47xUv4@En^pbg=%Ifd`S&PhFmVG1!7`Rc{b0MHZ(0(Wv zjQu_RfU!;WrZtm00AX*Gwhzqe4S#NO4~TLF56AfY@z$a;4!QXqzcUvIv5_1@Agj!Z zKO1Ex{T8swb+O!7|JZGh|McF8KN&mm;d>wZp}n-2TgFb9@Ko%&u}@7p$PGQ+vBr3* z&0)P&r|7tXQ(nOpS6N87SVX#bcYzZg6l*A8LrcI_T4(gQppl5-JQB^yj4$R@2};Pe zM=*S(0@EPY3~nAC@Fmdb;FF-guV&zr!=7G;wh&py2PgituGLhq{O8zRXXx4muNW3_ z`YLHbOUQ2BTv}y?mSxJhPt&DFS2Nzu@q z9>>CKc^`8v6JJwaQSt`_F-uwX#+A0L@4u!^%Qdnw{xS7_f_E8`BrT zWIr6_IO6h~gh6*9b&+xB`#3Q~;k0NQa+{*^^zla7-PB2vAt{B;xLTUGlwJJ{SQCAQ z5!@k(_xZCD@+>C}*amvPE^kEy))kf=*nIN^dnesYDnXfZg_Nv_{App$JHX4rEG8xkp{OGIouD13x9QLtHoZWcOYk&Ax(uMw zxHnB9Mh#0eM-i+7AuAxnN+eElPB!P`?^$%GicR!D4_9!bTg-RdKi0l$LBAGvGX*Zn zRj9F9c`&DMwxCzVGjv21JVA-~Ixj(6w^+~x$__FeidW_Z6WtuQ@vUnt=n7>4`NSZ> z^XQGd+sP!ic(o3#U}IO6uj#t79KRT6ahYe`UI8QWQ*M@1IXs%ith**>2y&gjeR0-w zlVY2?j0n+8PLN`g&IoNi+hJNt9#z*fK3W%2a6%*i6Yx@OkOHQgg5b1$*IPPv9_zlW zUS#;Op57vNBK%d&8a#!yx1?)>-eSFw(Z~KoCyV%3?=e~VovT0SfMcb`2FkOCP z?CzS?eez9*X_&cFTSOHENY2Ik3woqfEA$6zB&%Ay${MZ?Z9AC|m7=(i9kb=zPOE%} zYlbdyVUmnt6)6m}x{n#db9`gR{{X|zzp+C<_++iY*2~yr;sT1h)u28C6ofQKAX@V9 z6z}0V7ei1y32jRa#!9eaTzJ6=T_m>-vewt%|8ONV<4%H8uq;#uHG?Irc zNw60d*izAoRhh4I&>5T1GXaZM~Qv*sXP0fMf0kRe31LmWxf5yrf2;2 z3-7=DM#K=AE}%t7F%q_$5A^fR%6(a%?W*5emZ^Fwz7ZN(l@0te%U7MV`nFpCirEe7 z{GIvL!_pUsMTElNXv+*|wymFY*%UUm5f>0hFc=!0gOR`V+qr%V%+%lS>8;f{-G1UM z3IaSCfHqe)PovJL0Xsy@Lw*3`IxOosuPtT3z9!DWLI8yVh-FzqwIvNvWjE1^ZpK0E zCIq8S)QkBmHtAKmS-hQCir2wrXi7#$F1#~WAEB^O+fFnT#}c;!m~=9jeEWyj^-@t* zJfSyq6v?dtcN4tfLe*1eUq*DRt*4vzJg(nt{~ZElBABE4-uW~0tekX5iHoof2Z>q) z<4%~6H|M-*&D|-Y9a$+^(U=2^Hq15W4nIRIL3MDB6XbR&dj zz^g@uYod0dmI)wMEtylQZ{VVS|+ywSFXFRwxn<3$M`tvm)uybSG2gao1=i- z_1=lMK1B^B|3!hWg*WBx^F}^Xy>SP~Rw9hVpM`L4q9bUw6q~b7w&L9oc~>PQMmcBn z;Ud#en>vFB0j5MUmR;6rDK+Gpi_}5fEMwjkVKXf*bA%}7NPme)_#BC)wfm$mfAFXTo`H`{ zd~lLp{;sj(9(XKv-2-DMK6dZKM_IY=#IZjg`*5sF9A^0e_ZrD8CtA5I{Wm^3e(Z#M zV#6MJxRQip7{NC6dV~ud@{U3Znr#9&zGxV#qCeQVD@N)v|ICdJuY`vw&&T5QEVza396%NuqLKtS)1-R z{MWg&;66d|2)wFgiC*8CsbzP=1u#Dq3K!%Cv%Csdm_D;-;6mWnRBu4FpKr|S=9?nh zId}qi1y=FNOqO^0aU)?1cOH&3q9nUyM$D3&O{sMeY6r!sK(r+7&#LYd(-3bj+5p3% z6psjU79YE2N_q#-DX92$DKMa9C2rft8|GM3@dYR)D}}j|TI8&&Gyen)3XAq4eFwyh z)bhW5Ys!>>!JJ#TL!cm|h+DJTV9q|4UCmtrr@(aJ&$A$J?wtHL)8_NvK&)-Jde`y{ z|KG%I0VTKC#8$7i`Tt>VC8!)`e_fgRdWmZRB{$n%;43m;7w}V^uglD@ZkArdFF}XE zukDj){$DqIc9#)u!1-*q}4JCwDD=nJ`{0E{K<)4`P-2(MS6Mmh@p1 zva`D*LsV*Apz%QPfQ! zy;UNW#p5xf*R#Mz{E;5^6ir?>!wkf-1h(MC2rn+l=vYjB+OAIh4jwd^QxmRXn4phk z7AILg)liYUPQa_s4Im)_=KQl#cO%HTa2sfP9L%0(8BXI% zaYgWWRWUmsu|3O@W37RX3Gj^(OGp61Af9jnzhJx4u6D(7dr1)Y7y8L@{D7Z_+(+QWB zNNOHyMM2|4{&v+-+%!ug&H~x1a8f{J>(H}~U;XjM-H#gwdndUKdO1Ew>5{!l15&2# zh$ChlYYFS}-V78$R8(HbG6$a?*5xs|lUawzo0Ra7+S>+{_N{%`c1`)){71D{BG20WhQcH)#D|Fce1@76)~3CS`5lg2(#s)QRgzTC*=#Vv^U5&_r^CjPci4Y zLmbZKM0hb3Wt<7xw{eOw&(a)el$7?dh8I5{PD)ws`E5Fa%Hqf5IXZh7s(<;i`O7U= zO76@6&3`fK)zqj(qdfN`u*u?hPD`Arkn+440deH zg3r%goFkZKILc&LlP+>Y|Mh)_Wu?zRol#e(b%yQO%oxu&V&qQ6 z>rqHj6+}7Twl*~9!()^y*p0&BNH7wylPj4I=`{@l*{U6=nd!y!ir;@@^>aYE)w32b z%YnbVwzpIc{s{PTUtYq01G+~lfp-QXWG)!xFJo>-jxytu->rGQ6*dg`ze*`19nAco z<=SS;J^1E1U^19gQ2eW>3N5~*8Y4Ns#o9hIz$p|J87(Gd=P_uZj9u`|UR*U534kjWxun{+;uxaC-UpOJMeFK_coK&oB04-#ZBLQ`3bjAiAxmDs5Ftq13FB0eiXLr zFfppqQp{md9SM_npmlhmR}7ZuyTGB^lyB5{2{i$CBo*|8b3=}`!oDV}#wGX#RPN=y z6+SM@+pX0+BwFxw$ji{0kEOCAa$L%3$Y+Ba@CUpY2>URMVlj-60p^h~jHWQmVitlK zDb@6d>A<&ua)kFvK+Gj#pvZY_?eH3`{}{dz7Rl~@g_5UlW``ImjcaEO)}J&Evh$#) zi;4A8_;>}Vtb;|?b=tVqFaOp+GA5E(gELGd%Ch0C;b{z*X}*YM&`{HPDMu}5T)cP9 z{o{_u8$2vKN3M^QMRKc}>@b)6j=V`2jAx$Qg32&ZR|;UY!+5s7XfU4cYikuaMLoA(;8uRwezSF!MbvYsvS+rC;MNwn%3l6fON)Jr8B_pS%4e)IE%jm z#xWRRY5f!#-KV7DzA6!C8ORZoLR5$SUcqgI`LcqEV8*q5Dr`bO-UyyIq7Iwyn#T^l zFu;gOcL1D0zs`JZ{mlAGj&286z-a5^wars6{ub#(y1rUmx_#A(=UV<~KJZ=uOVK06 zHjPgW8ann;fX#zXbYcJFRTJCg01WI;cACUioYoKKHU|tTGpli4C?Dm?w>fxLIl$T#1G*x4r&%T`)=M zs7GKdKGeSJeqo^2vFSx<2}*i61xEzO(SUICoEFmCya4N=2|-?G_@zwO zSE9O<9jk4{aigh*$rS2DZoevde2SVCx^Sb}y?VB26TSzSZyYqqyLm?AXhsoef+27r zSQ4al4oLGfqQ$Q866WH&_7}6f5n~i>$MYmwOUqQ2iS*VtGxWFM?a<32ogSemBtQx& zM2(n|Ar6u+MV{cMvn7VvGU_Nrh(IoZdqH zCm2tzef%U(>X#HAk!n|FCC#vInSL}w{{+4r7YH>al1f(kt!tZ1ct5sm2hoHi5^)ku z2%5eC1zL#fqo4$g=so%fhy=-dDAq+lQUs8+E{9%&#_}B|jdC{nHQw{So&+C~al*w* z0f|9$$_-JTm!zuW#+%;|{irsd_g|W^Z-y!OE+v`>0pWs}u|K!MGH%H% z@WnebLw%6kX)XwXL`G}~&dXA690(~7MXJUyL>StG15(5@sn1B$*62`Xrl*o4)3Q>O zCmHWtLu^@od9&GN9lV6B5OM>&oM&8TGT=97nPB7HkX(vV0_is9na4?i$8o7bMq-d5 zJObh@6{ljz{Kxm0HR{}>m0Aa@%l1(FL-#G;zincl*%kD<5B9` zexvLUuM2se9s2I?*V-40+@&aqfnK>7R_|;9tRc>7_1i(1)%h=E!ur}&B8;n#^M1XU z&^aD;44l+&@^yBs!46&E^s(&IgZwy(hq`>;%?l}GNa@YsnJ~%a$0)YQ0exq_pwHD0 z62@Rd8YvJZ)vgGwCe4r~-7kVsh4j`%+k2* zGBwKQz$8B+^Fuh56|Lt@Q=@zyYyob7m---4mZcLHEuDBPOk!Ah0)rJ<@dNw@$tCbf zKO?6CtdyIj+cv$$H^YT^%FVlTJ=wgg(e(XY2^T_LR`<%82M)_I{wq`4v_%Ih07hkq z#j=8xd}9K4zym-7rf;t+%Q)h%Ch!1U1oe3cix|wZ$)EkLsi&HZI&?116{-ZEH8PF3 zW#lps6uWtUiN`i#Gp``K!aDy7Ek$!6Cl9Qvx;_~eRL%&$#F3O&3+IY#9hz%|b5dib z5#J}D8?wAUDm&4g8sjQdY1^U0v`F3+HJs57p>|ZlATF2j-Pc`Y@&z180#3#2&}9SD zV@44)(q1S^2IQ=Xw7J^ZCDKg{Es^(5=Urrd7 z2J6I54Hcp3Zo{XT3lf!ce&d%F(lL)V!i;tDsidc1CJdb>aDZKG1%@m%*x|Z0Q ziF8|eYHH8qJFNFQ$KZC6o51L@Ppgsg%)Eme0O;P^j_K!6S-$m<1ltz%D zRGJ8zCf>DM6>5a#uUHphiGZghAxJJm`*fp(fkTHREoeS@?gix9XkND^MN{mFN} zSLHs(6=@;DSPE2!3JdO_*`Sj$CI0u`)aJmgwncp@Ngi)<)NOizTwkCoSKMORl2MQp zO3h6So932}b}7`^d8}*HEQMj#JsufT{ivFXZcKIUBQ=w%S=YePiljZPy859=N@QSF zZDh2n>)J#_HAfH)~J)7lAzj``MBaUD&`Dh^F{}MI>#>BTHQ#$%7nB!0HH(CPt)Y zjrtT4aw_{3-*(gJdmG^40e`tK!I4VYQkTKBn&2(aH)_ieSjM7?`^es>Cg<*oNrB!h z;X}=kA(D;=&-&;xoToh=k-kfmu&gARh~hjZ3b+*w1%{&-oFFYOA&+7yi?QT}T-k<=P|v2_ZTONd)wV$?y#`yDR71`Atd=BSU#X3KXI%%8XMB247 zR(c*CpxnI-&FI|g`qLV98XcqBVAzemKWf$bcE(ZE1}{IaO-7wLx=dRQztj4cVx4!R zQtPM{GbNJtcR8tVx_yVdYTU#{jQFcp2E(PwtmKZHyWjQJJ!PJ#~Yu} z@bwzi)j)kP#1>GKja4ku-A>$Qsj+YKTVub;d2BHqTVDOQu|;=ci|E)w>R*jbV-9|m zw3QmmYm1dG#`jW={>GH`(n2=8lR89lI~7$?@OVS+9QW;5RBGWZ0cQ`+H!e8xQ}Ho2qJSrdP3kvt)Gj%o(+Hx{*RB3hgho|D*lg z_U)1OX#@1F%t{zu2ee%r6fZCe6nwe7~x7F0%ugpgGZAe&p|8-msl_P+nR{_b^gcyojq@<$qpEg>j$=3)oX)z)qTC@r!2Wt%tp&qDzH6 z7>axBf0xHTjwH|9`7?PwpQgAysRx*(C%E?&7+gLsb-e8v5KZ&{^`(cN z{pQ`jn0cb%s7gFqALI(uS9XrW~K`tJ2mpO;nP^IHNaA{o3PIsU}P^ zr%1ak5OhfXI5Y5d%>!*avtP@S?I7Zl6Te)hzrO7u!(N(+_>9*#-E%|pu-(HfAp=fV z$nSCnO`&DpJGv9)Rc06A5^Wy4Ai2#aoO$o+)P>w}Iv`P!-%7{5;cVKhP;=Q(Be$6i zjL)g|1P7(&Y?Lfy{)V}l#}xapa#2JqraZUZ$S;LPhA zbYz>h*X!Gr@rSZKcG+5B0|e@9BU5iHTmqF*DnQaMsw6x;bI{Z13f!>(uA{x!I#>_S z!D@H{8etvmL2)pzy3gv6|Ic0BnDWVUF|XF2xurD8hFt^`ahe;tc8k8D_568CbR`F@ z&NSW1t<7W8)=mw2b-&O-u-T~;;jv*vAVMO-N19n~-uqDZY&|G6QfWMClSx}yPaCgW zvPgqX6EEXcqVj*1!9GJx-F%}D6td!ZnB4COjXa@hE{8*pc0>XM`Fd}kPW@EuBz-*P@^ZA(d{Nx=Pn~*2JWh$cRT4NU?w}l9p;OO@y9kLQ zMb#E$2G@4~=MttOC!V+Np+#PHbBye^TPc<%Z6203^cGTG*S0V8eww8QvItoci(?Lx z+6*t9*Qqj<^>5dHeND@X(QIob zJrXB5L|Z6qr$mABDL*!Eqe+CB{>ks1>qN7k29_N%qjsihepf{N|J!JR%*daUK`5DlDq@bW9@X-pgoIj z!8SmFXzN#Kb@VoAiiWHF%3at}6chq|L!!T*nJwbnkGc;?qoNxpQG9VC&BU2b+J669 z)exms_#Py1c8A?o(my4VtY3k=2A+IfZ@&WH4IIG=EJ?-b-JL(^)HV2K5ICBXL?-Tm zwEdD!-HfjWfsyPyE5tomw*RV!!|cO%Ld53{1-+i2`Tfm{YCa2iFQ>>@T>=~D>(Khk zG0lnMGX7Y=msu3_=EQ{@Je#Jr>%b>-Hj&|FA#OU`e?6v6=QOS&c}9|DIT#n2+^4(K?*`N$rH;Npt+0f{#jq?Wnwuv{SLw5vq^D& zy(cuPbr<57AcHS8a*$mAx>KB(!MZM!8-OB1X*kC6iYOt{ME*dxtVfYy zoObU&`%}kznyk5yY69K)uwmy5+jUUTF6vWADh}A9B?c_DX8q`T@;I(~E3TpY=;>=*pxIAccF)ER|YzMWkK5syD5><%QC!A;sPqnZsi zb-w%IEX@asTY;E>i)Q_XK|o`U-G^^iVKn#fb%CB?E=37>1(?@_w5zR+EnAUa0u?|)pzWz#btMtp`9^bj`#khPDJT%mC!G- zZ%9t)6SSI7tmi(xUCWUn>;S(#Z(zWYTVZ||yFb2Ng-Yxa?(&5D<=H&ReuDPuzc?jm zS>UwBUBYR&ZC1oH=8*)Qv5IQr`u(>nf~b5(RGq3ljx07BEphoW0+*}CpwErW!$ z2?}IuUZG9SH9ywft2E*TsRh87g)H85F#TNG-+Xv>GV8CHp}sHHOj4NFfU4R^iYn*V zRn4lcnqJ3}6*H#QOrJ6PsyOoNLvMe=Ppo6_w`{QQh8Iv`IL|$n?1ct!Bit#O84m_> z(~`HqC>iHP#9GI)_sFu3^$?!qUim}9L%8K&*#NEqmOcrSpMtVK!Fd{tIX2l zb=r+Ao0`Tv)0CN-)@XD^ z2|Y;f^`T@w`M#%tA;LyR_4@x@IRBH@d?(lDFXO26a-Pl5GpeiHujz+f#u83hn|-3& z#!)0vE>xK{x1o8TRwuxU3#Fg^TsmaaHKadnsFCRP$6dw*8>Kz|9ES8|vxdo*)Lf*0 z)987uXNA=2D^P@98d*e25trS7xFFz}H#~JHPGjaB`(tz3D=qPbkcDzsP*Ogq4nZy> zdZ6i}*r@AmtDTrt(bS|E^0RiJHfr>{*x_yV(|%8GieEW$!Nk9?PKV!R583ZbdSu!K z=u2{xJ=y6OiiM8=od%nF1wT zY54Y}Ie>1aa+p#|A8B`YtgG$vW*_ob;1Ey~0=taNUEK#_^iSo4>}wK#`UtXAr8m+1QuvF2@GYS+**C@ zvgur@)%URM0!OPeiV_LgfZ%KSHFn%u9Y6a}uon)Ia{W7}HSmyAyNuJi*>TFd3(|9F z7o9;zj10%^KgAZa%dyIb(v`)g4Fr9$nx9&`MlWI$FE}8(%VO$tavKEo2WvgVzEp!hWIL<=oNN%9ri63Zf z6h_zPT<)?saf`)2z+%bpD&u8Zw7xazq5aj^jQ2Yi`uXg-5SKGk|NKQQ`t0)<{ep9~ zCy(PYb6Eq|A1j|B;D~n9z_>{+T^mPBfY7u-tvB1pk~3%3K2rTS zE9u@os`4;!N^Q-|y4mmXBaa?=ZNn4lbAF;_DVD|sK)L3mJ|ij?g5>eYK7OiaKr|~F zNOAR%*x1#nN^x2&PGB=}XHF-~-U3UJ?m^SBZ|O6abmTnjFrMX0C`$K63Qf(Sx#i?` zJ)q<=)<*QXnf6g3BQ9dTMoD9xi}5QM$hdq@BZvhsh3jLZ88F9&3C%~|I{nDR2iS2d z=o3f)D~m~y`=p0Z9U0+6L+)CLHp7Sq*bK;`iri&Y+d(z9+QG`$!%Q-oMfFX;B{@Go z^$VB}-UM4JlTD1V=JvQ{=-|rK@qVX;qvOYFedqIUAJH;66T9$?lH^c&aY`_5J@Y%a z>#hlV$%Rz(_GBsf)-;>R%R4Wf)alYi@>7z^5qtUW#6&wvPB74ro;6nOT0t$wkdJY= zXhZ~f+7{$2L8rxZs@=b$W#J_a0&2hTDJwrpBy&Bg)BR`mDv zn_ANTAC09;Ti9-dCu0LCj>0GuHZJ+b4O%}cuV&lGk`#AhajJ2NYtrwzue2Xs!!v3@ z<0UIaP|W=Xo>80DRz(P8yU-f2O0Do3h}PGj3^giyBCGBg_3yv%@#7P-Sg*RZ=~5Co zjr9{&%5E1@nM^!8Iv)zK4D~I+roDq)dUr9>(G45Hqi_@_K&mOUH2(7W0{xRa%^d+U z;=r)56F0^2-Pbj`GNUux398gBMmdu8q|4rNGvcUeMeG<~<=R0W*-Nn9QZAbDt8ER3 z)INeN*T_GXfv|q*fcG_DPg{SDO<@;*7^HrQjJ0n9Yi?MF-ds85yZH^+BOLNnPFEf+i!4e_DJV=!He?%ZqOWV;ONt8Xegr*`5V|W}q}+ZQ zvnKP_LcJd?r|R~7YCp=N&+%u#LlO1}BbWA+7(F~h)?~4#4jHq)%+Cd+W}q$XiQ>M1 zKVqwzD=efEInRJF@9l3w4s`yfQ|Dz=r+5IKfeO>1uI-r0p;WkHu^vyj+ZyhDFJ;%s zHtl(+{nFOYG`4a@Xhw2k$Yu*0*bce`^h|7OJH<|13FkNZWOlK6?Ty+%)Ots%cfVRa!o2);>smX;I@hr_QLWtJVwoaaB{NsxQ{s z|D=)C)f1;y&x{P2G4mnS2E__vYwGHzRzDu8sI7UVn&ob)s+k@cQ&(GET{ru(f8^6$ z%YN#HiCZ{U!mLH5ItJb_pMa2MW(ZAGJ5 znw9w+JaW%YDBFQXtU|@2d;lKA)6=A0L+-l(1uFn=faH-kiT{F$PorLA9&y%@w`VPY z!*FNGQsDobxfoLKl5bDUE5wE_g(qP4O?}+yuTm8mgMn zJLo*T3ti}2EbUM3yK8zp&OHU|;Z;}-e}`7!>Yj&3f+NO_cm@XD`VHKh{0&SIH$aby z`7n9#bpJ!b2JjEcXO`jrL7%|5C!w->n!8HTw))M7+wX3K!GBI2;F$~Cp&q8UK;C5T zE}M^XDHoSW@xUvRLxIgx$oG|>0C0K}fWSGP2~aFbk$8|Pg&SINKP`B?VrIWei_@Lz zwG%e5$^I3v3`X~rtjJD;6N)Vq$&IZ{w7M{!5}o2DrL)W)PRi-z%59YinQp5coRU8! zX{>M$SxU(6sGUzD{lIW28+YIHHPG2q5^awNBe@id$Cv2X2+QFJEP|_mXQZCMjw@PV z*65VN3H{S<4Gk{MeC%mh0p4L{gKiTt?pqFG6J#Gy_IVDZ4oewkcc zLeVQAeM5}Etb=V|!N9Lkufjhs16SgCrFP2wr9(#${XCH(x~NA3O0~di4--d5NJ{ikPohsf1gUDvM&q3181~f7SB&)AD!t}$}K;8i4 zgAg4FjQ;Dezoy(*H0%>-gYQujY*RGrZLl8^BOahOqWRE{=D}j%=AxVn`1|+)_y_cP z5nNxxi2jd#k2b&`Fy%|A{t9{1$E8^m2J;={*L(qADZBaxgg;09E2%M-nZe>)?)VrA zZ+Uc`qScRiIC~rP{1|$VTL%w@$0&QT7hXl4XMtV|_NSn5zH*+PKrg|A56Op?YV zKiFe1dbsKnbZhd1AH&Qau{CHJ`r9usy2qVgBJA;!H!<`FlzpcxIk*`7dte?m7wn_I zhB5CGll!kgwly$r;4;926LWSzJvt79>){vZf;VC8EV*y$q|8xc{SUe8;X8Z<_B*i} zd!IOm-a?OT18gnio`ssv(EIQTdKVsi79Kx}zJRid{n+;)XO3=$V;Ff)__iltVMrQPcA+kpI*K!xzD8_+4v>J2%0&dDtiDE10$k(l>!LzNB(QcxvTCw-o)2TMNOr z!1q4f^)-05A?_s%@odh?K!3yE2kg<*X}Oas3wv8{ z&FtO(!M_BDO4VCnVBT{O`2eUF&|h-HeLq9J?}b<3B{b;|Ajc~o&+soHD&##6&nsI- z{T%{-V`k3y3VMk7x#d;ZbBf%z0A7U9EbK4hEvfxwClCQ=Bw;xWSOp{Nrp$$$y+BrE zK2r6_gOBz2b9yV_wSDh%jeG`m!{Z}g1Ml6%*^cB9e}|;rN!7!jR8|f%9-Q?YjC&5) zzZHK1#F%?tg3&bvFM{_K7+hm}3i*m2m?T#Rs~9NClA=ZZ#9n#rP`VR40i7VO2TMUx zVp5LP$4X*OQHtuTM5cN6!o=DU4{U&YcEAHCAk?7TG5!uHor9!i<$g#w0uRr{{;~tj z=!8*A;3K&G1*m)rioXDPE%bVnn_2!bfJcx71L-5n zZy$Kuq$Z@xQ%z6RQ|c@hErm5@i5NR1Omag_`Ld}?=~f}1SPHBA*vnD{N6$3TRGm8N zU(v`rm%_zfP9dk#C1wvYGX=K4rIYKIK~pa~6CLVclZM3^+22&i$*gn3GPqI(QZh#O zO(89$jKF0ia%MC@g`e~}%x#7vy+S<_4)-;ja^sC#TNWGISoASbW|5(jxio|j06McFV$ zDl8kPT*-GP41(#xp!D0ahxq&1M^N|m+zv^ji-$2$lrmyFxF!>mO~)k5gn3`Q{nl41 zKB{eN3!EC9mz|BCo;KlBZ&l3QParZShJ zJUU4#!PH2)4(sHtufVk-X*iaW3@FtMpK4vIbgqoQU={2d62L611Y|)bPW05PXbRFx zpJ?g!x>v)+fr%Jdkbo2U=J-dCd~nn=aWva!#dbK|N656@dh45zTG=E21GqOc$)C?< zGtYxH-xls!{G4*xZ9-4NTQFu)!eBHh@+Z$G6nY!@w-g?rZA)0w^H09CUEP*UHgshT ztm@UzUY0as=;(3@L{d>fmjlVOq==;$hzPr1YpwUHOWfWHzf}w%@Lv6Ktfwh|x9mBf z&A+P^whmOWlkF*~PV+FlcTAoC!|c6hHo@**j4)y&@1jn73ES1C{PPb9f zTBy?3N`J}+zj^~)8$_`J$A}`!@Gd!!;55Ey&Ghr`0qq-U+yE{8a&W9yHsHO@NwGzX6K}%Qj!YF1zE5 zH|JWq7?pha4Y*jQ=957u)@8JF4iuYYRft(z2Xnq>+I|f0DC(EI)Eq?WF3dQ+2hF9bGf|eqCXly@wn5-o?&urc4~e4zx51;;hhv zX+!e{4;ehHcx3t#s2r3&tbAfkC_N`XC8;P}hr$il*mF<6Ys|7q+(XR+1B0$({<}uy zpM~9oG|})^{z99Aou#e`UBssXIzA6Qohv^<=E> zYN>@{3yiVawYphsXos{N3w48Z4#axMSdUmm<(A1r#FJ5U8&?LmscY-}VdZ(4Siu%t zvF)VNNnE*=FsB!{P=hGUo`l=x!%)_-0s@Fsf&eH1CS;W3gt3Y^RiFYeBQ#o_b=n+RVY? zM{L_QpIp_Jdj8ip*1Tn%IFQX>;n;@)6?_p^CV1S^AK=S&Sv}w&?~$XS$U>N&Q6>fC zyAqoeK@g({>;;=C1mF{%-S(lVerQ|exm52$r~3xfPuuIitCJ~Xlb5<0iDmdOM>G=6 zN{l8Jm8O)qiZb>nY70X=4S)68K0r)m8EQrY&~0JOrnUbKt!)7tX_9vkL^)#t&IJ}y z0t7+ zrrot#-!2wED4!z>P@D2ajZ(cU-dexnk36;flzb(={7tPqgLTx~58)LU@`Mqd7OT+*Y-Z*>iyP4Xc_~Ju@<{YN`r< zHmJ60`lOnfhI!37rmAMD8YfaSabk7VbORiXwT`Qq^x%}LX)`sK>7hee`lcB(YHOz7 zKa+L*50cKXnE^AZ>LPbk)lO#Z17_7eSe-gEGPtU?N@3z7>L%yRew81&?ZCcO{KUa* znPpT3f^ot?b~oTdB}dV=RFL;IpZJByPj{;C$^bC=C^X8B$4;WIe2w$icNeA zzr~AK7XgfuG!4VMuf*CP;JX7n<%n>!J!~%Q-1b=ec7AWb#n7^yWo&Wnw`lY*Yg;a! zquGL<4Pckty)wCSi++VQHh!^Q@8B3e*Gtl}Ku|_LYORB|%i08F7C+86C=yGKQnq>b z8}G~yYPhJva%LK@_q6@TLq<>C{0^S+MmRFykHcHue<4P{${!DKG%N9hF;&fV^xVbR zQtO4yoRHvQ#6&k6hb8jwSo?*-!ay{U;}a5C&b%{sZ`PKoe6lNqExeE`Vu%b-d`5bl z9liZhtdGOOafB84F_arZ=7nAVn`COC0Q)A z)nYN+Q8cl)A-0!m#6vV|K`euSGwDsgYwh#dK(lp&*BO3nczXY!BbeJiBe5jGA^H4r zMn#&p43(?V9!^bsI`=}`k<%KVIxL>?^HN5Tv!;hkkI&XGVw<+wdf63CPKhL?B`28g zEA2mPn-XEgPV1+>yXHb}Wc*W*7uGm7ss3#3f7eD(b2VC5dmk7$;J*7S23D7$-RiT7 zcD|Qt6QVv4CMwGIktM*Lo;ftY9EhGoiVAZu4cyc z^2p3dQ)bMV8ksp|#;mE6Bem5Ur8-hKBQi~WrI}PU?V(vSRkvjIPKb=1@#yr3`oDs_ zg8Updp>pap6)|K?-Hcgvb&(-8_fLt8(K^hEjH#YpGoyC)5`N^`JzIa&agYaHA#hrz zfZ#D}P+_~6mj@z2MkGgyK8ZpoMgKf)`h75yoiImSK)wX;L$1H-Nf`Jv^j!wUw;V^V3b`XX&Z}S42k1*9x#P-heZm* z0#=N22{=s?i1Y|R1Z-wP=totE{*~w=!6%9s5F&wSAB9mohFF>4l1BMV!%+uPf%Z1y z9Vj_!w_Bxb3irEEL3WlNX)URc3@6Vy)TGUO$fcMokl@2{o9Im_(%nV`_1LdnNUQh8 zV(J7&vKTIh`e!gUj%KVO8%7oBpQfb6>ddDVEjO@$I);)X7-8i}lA?JL$7EMV0zrwK zJ7_YlOJ}rUyU0(GD04JM5IDt2TpaeBQbCz~D|HBWWCcYak|iM+vH}scnjyd2=Fw{4 z!_U-lbX8=1|R4_RbCAe+fuThy_$*g!Yas7T!wPY(;wVMPQ)FE|!CjPVfRn~WH%&Qh zB;(JrGJdmW+i_!!>;)7d_|h=R^)Tnv@tIED%N|g600LexP~`Mi`V5x{1cqdgS)3CmtF>WZ$Z%)XfC`6L&{T9BfSUx4`WXen{)`{hrP47TIuNFra0+AXtxP35jo~vqL>U^aN-=6ARm%>ov5zGWqKlBi72x9d1qR3H z{NdTPn^ojS_6j-$rC4pE#NQZo|Mwcv!Qu3&M0hzZE7WpC8qwR$-`%he(aLg54B)97rTgi{h%Pcp&&EnG(+d%6^sxQk zvCe>exTKXT`_ar@1c9VQH!nvL?M@>HhL)l3 z4b4{IV(BB?ab)wlXBd9F%YXRbfR=&jn9|m7K^`AioI2KpCgY$9O_wxtiK;UxCz`()#e({UOAY#7VI!1L(&V1Bb&@9BYuQX% z4=ql%X9+vof9f zMQf%MUl9%{#b4_g1kV4e6)T7JXF*LGaldATx%_)6Mz$uypI+m0nX=$1$W)R~d7O5K?cscu&z##XS2qh{4SP&IvqBHH(#Idg`>VC$4_(+1o& zG(9q+W?D^M^<8h-o7-vTe<93^GU0@4`AgA zc(J7UG(0!zQ|cMmOcfPiLk21rO^U&koh-5EXKYnP8Td3lvZ`a*`=4=YI;!2>*qX|e zP##rL59bb8Gs@_^|5Eyj{3R8#NKRX{U6xgO1~@84`qqNvih+_ z_=vuiq(HeikVww%U6ma6=O*P=7KYR9`2{Fu8QL`Ww|_lJs!102|B5ZB42Yc1%+{kp zYkhWH&8OmEiPOJga|V^6Rq7GEynMsw+etNv^YQE0h9P)Tpf5etU7YJLe|)%n6I;#b zBOna{_u~akss<}8`~y2wkz%p<6lutZ{ku zKGCWweRckU?W_n{P$+1DU|i;*kF^T9Z1B_{*j1%3h)@;_j$16eRS`Bxi-lq=7Q>@h z!yw!j>+$>_*v1NFU|z6T;<7Kj{GnDMiM1`ihMlUEl-b#pnUS$b7wwBY`GHnRVeJ>L zWBUgs@IA47Z)z^|H@D$>=dZ>_@4SXx7|eTkjPVMjX(0LRxYkDw>s@^vTRbEw+a{(L zyKKDNFFz1XjiluH9eQ9N#c0gw=oi`#uS~4-n)1tu3{J9??DEQXfaen#ZsIj~& z*RahMB*Wtb&k?2t?4zr(3T@Z1u0fK^Ay}REI1AHfhhytMcpckO!61S}G*9zZMp=Kd zA)cOmqVog2mjlh%bK@8!TBSK=KAck!D6sgMx zc6Cng)pw|svsr(4J-)m$!zxBZg7vsrpcu?f6C8m!{U;=}+z3y07&F}a1irg6MG&Jl znzCAHBWWtFa-8dWpQ)^~>j}KRLXogp-hz95h$`zrkh&Z$sR7Vye~E3#z6Si%ph&Nh zUWsynCGLm(<%#*PV(Jm=Zon@L47o{?BzTFyaWd?o7)A4ANDL#)wZC`esIm5|4fyH` zNx7zI!WD4J7^SEzc9tUalf-L*lviTIFMbklsE{od$!0M=0UfL0vQ{CPwJ)B7HxF`I zX+`6deZ^6$6W2c~&_QNTsMVBPuXzq$U%4N~=(AsTQTrP0EU|G8zNgF7pgEtPAEIe3T!has*<8cp*(-J1zaE!OH1m&f` z?O-Glrv!?M@e$4ackQ>a4{iBe{BVT>ki(83E@{}w|7bH-7}@%{_?!yT6|t;-?iexL-N!4^!FVM>k z?O^bX+R0TcqvFmEsH&SXlalc%?gRX3eV~YBb!dX@vVknbAtR7IYdEL z@dq4Y;ef)_5mh>(Wr`+w{_x$cszASjI*f(XjCEGYZ{9b}^9}L>`Z(rEk2u^JVY}&l zaPBFUoWM%k=_{yT0OU*?=W}ziZrNmX%%cl>l_T_GJh5lCpW<24n-g{ER#goU@{l@J zHGdSn0!tLRK!U*g;{p@cUC`%nSQ&(MmwG5y&o~oI=URijoL!Blxq3}Yb(T-pjk+qU zX*+rSlt$jk?ZAAJ?DyJiA#(*C-y7r(?gS=F4!7NEi+dNZKW~t`xD6OficW?w@||hq zu1f~_XKokfkX%8#)ftLwebFE<;2ZFWEc(M%15sBSd;1xKyof)6rO0wps?A92qmf(B z8RQ0GALcI^kQgZLpJ4ixbnpE`AuF6`kN7EG*aOe>Bt#BKTLn4J)bY8| z`Zuu)b4By~?&R!HoOSG=LEdiNr;r0SdqT|7UwepZH^}YM3e4f|S88+hk3+fcz80IB zZ7Y`Ma%ZI4J#pFec0YMdC!e;>!K~2?NlZw!ndI$H8001LK`cwQ7i9hyNOt2~m8=}g zPv!NPH6`7KGc?Wz6XW6#IzD^#U$;(-u+HW3dOT4~!9$#A%lH$?u&_u?>ZQ%GJ4*-o zuE)fr6iJ9CTg|=g{9Nro%@`{;;8J>`$oP1Y5VH+{6IF!T|Fc>}>7i5Jh;fk&kq@T} zaR#n~26?XiFyacbSUx{9F84#@VS{|iehN{M5{V8MTTSx*4ujn6*o9d$dU>Sua(7(d z%1MKK)v*w>W%ThWWUnc#w0~oeFFIFa)|@hzoL%lT$t`CL@&flM%oX&=_K??R9^U4& zvDWTGD7zxXms6SSHbcYe|E-W`_hQRNj~%DkV(L`u{J1GI6fwVQYPG63Oje^Z)Yn>t zADe`V>W8Xo>r@1h*?X9g+jf5bTek|5DfSzb;7~+3F{MvgLfEhyNd}~||wsB)fDhgIE8HASKZ2r-I|&r?qGe82a>Db<7^9YBrXRnG@Y`%0}`s;P9g zI#euxg$l=3jpPiDF=kM0%ZJITU)UaeKyOQ?==2F5p`ZXV46DUYr$2846`W-inQ|FU zKyubk@C~G8YJAb9DiiN*-}f&S*$>-C)|R2Sb-up7^YGCpd@5l5a&|u=!ink8!Ffq~ zpC`Xx!KjN_%^n6ZoyCO=1~X$P=UuyI)$O6JsK}A?r+j^mwQsi1UMcd=Bbgmm6bF0C{GqRI29N2V7rnhwJL2d=8Nr7z? zihBm!_79zUoNETwnJ6=^gt$|*c9TwB!Y_xA#5jUhHg4SO4c9g5c76}gc9x`MW4YQB z>e&riTXv3UDg5glzd_;DI25gazISZBn!t-Yz(3-XSi3it#Z}|m*Y|v+*+@U-_d#AD z+CSHu)X&5leQ%#mJ*epQX>!qnskXwY=6!Q%okDf7>?-TjQ41ge(yfN~-H*y|lg!F1 z?5nWkB|!!6Z)pM!`0G|Kc%feFv<{$R&r>b#CwM<|zVO4#m6j+0v6`be`KcUYHz zZaaQ=<&~>vHE^db(rT~S;99S8_%nI#_D4Z4v7CQtVxz_5CNK>Z`^Y`*I)=DU`^zymBY6uSe9t zclP}%sGaV%-(!pRiO5O4!zN4m?0`a4&x7M2V4ge@d9yL|w)yNsg&JiY8$GMQQkG${ z40T#8G^gd(&}&KBn*IS{DA#=xrSRaN?{oBNNEGKRe|A#qQ z5e4qqjwRqk?g)y^p%9*tfMdEOMruGn``542Qe_ACiWkUi=cvlQxr6P~sBzAoTXWk**%E1dRRnxSjLm9vlB^s``Eik?JdHJjoccA;r9vko(H{yI)=5Z32g6txJIAP zDXs(MIIJnTHaXQ4D!Si|(O2?IFi$3pyK^YQC$Zv2VKqvVhi-&a z+pssF3{|OuheNYioZGPP%k>(9c9YP87mO==6YlUEC>YOmZPNSSD6GJvo|NJwZ*r;0 z0Xx3b)|tk-&IzAlCGWy{n36v=I|)ncOA+!c9iq*ft*+>BY)9&?*FaH9amEpE@Mt}| z$XLmC>sBN=0}iXpAE#i{pO4Wyt(T!sh9g*>Zb;Z#KK1UCvHllJJ5k7$RvdJumY64G z`>7khm~;kZIefh{ZQfocz58^GzQwi|xyv$SS9z+{*F<>@ygY&Yc7Lnr)`TcDv%)}YM2MNG8oVVkT$2XA1a2am0%JX3~{OY>CRQzXU8X6 z-wHoJWjkyDCN18u^pg#mA$YTU57tXy(|Yq%a-6dB`E#%9PY#>i4Oj_8Jfmj=_s4YIpo0b%pxqJJO=Ztl2@U)>&z#s7YeQ|nU`+t7j+@fBP^m>@^=RC7TZ`|NrjuEyDft1rl^BA|yjnTJzuL17Mp)hYYZ3@=)hn`&@qaVlc zND+aB3&}W)mQP~z!`}VK5=jF~Fx3+0r*$MozvA73K|uwH7gl1Xhe_*4G5R&{T+E^@ z%MysiHfwMrjq3bnm;G-I+p-odJh-ZMa`kj0tqe=wGQC=bX|0>RiXHjEW=;0=u$<)p z%JOFo$qZx;HlxNZ8s;~48XV5i!xXkR+$24F?psZ6nS*ZyU&JnXgO0ds_vQ0CbtS$V z1zh2%+a8D$0X}>CltyjG_aKS4x&%&)!*bm84~3e=238PF$d#KYN{olK$QiOTEm=@R zCjxA#aqRQ#_sU3$^tz9ngM2LGax-+CTlxO4leJ9Ho z0uz?Kriwnw(hgD0s3erot1uWTk3$-N<}+E{4{mfvLOY1(@WVvQ;56W`6b28mA6;qQ^ z*6P$ot^uWavIeKRGl%Fuqsq;XE>oyO*piLhLgJyq>E(Sg*>q++c58W+yDyfXmRe-5 zz)A}$#zso%3Qtx*j!Lv_Ehrp|`NUAj6{n(q-Por2(J2CS3(5-k(lfo@G?NFu{JcJk z!+Zxy3wTpf{k~*V!h3ekOWJ|B#-9O);E39JdqSMOc#%$BA{;|$B>2(^JkAsJ($hM1 zr_co+t1rzfx#RpgmMze!hlOL{ai*j>U8!*%64(D|*JgEDIE5mzEs|h!gyX+jx$$u_6NOfgLnw#Bzr=cDc+#zrnl)wow`@-gos;qC3uYJERA^_{Z*$P z6R#=i1SQ!iI$qhhq*JemO~{s58j!<1f~J5t?>`DvkuT4SR}=}s#hLOI_J7zZ}%1f9qaU>au4QyXCmhl}%Ul_6^d{!1z48 zkm%zB<;4bf){t+Pysp(~k&YuragNMI6F5Q^^gB^hf$P>TeO(*js_h8E?(q&;WmV2LiVI%Gyzh1zy?VNeJoUi8#TK zXM-%a6hc2kBU%X^ady&e+t#WMhRTQDhE6CS`Uh&^vDePOqI~F4)_NYlg56UbO%L@Q z{X1lhQ>0Oo$IN?2YpTK$6P++5(Vj6l!I5qrkn4K3RdOey96pw|dl_@%JLf69)yd+k z$wP`DHBS#zSg_&yS2T{sw~;GR7Ek!H1=?-y*xKn@=5z7_1XwQM=Xh`2S)HokF_U{> zSb&QR^&5JQc7<(vKuxQ0T-b<@D*un74CFd*$()BaK~1LJPWVlY5u0%G+KLzds$q1} zD^Z5Slb>#P7nq3J%U=IMvu_-s&p_1SNl&uJTmP1=)2VB?YY_5C_MqG9Fqy}u4=!oc z-?;PO2xR%~{>*^+na+Fvk}4qZOZfxH;VnwDdkW(Ol}#4{Dsd0rf_x4}^x9d$T={!l z0rjPSjc^(&3KDV#<|k&~05#K-@||A(QJvbpS?ET-be?u+2$Z>~v-5(g*tA_Z6~oZ{ zLHqTUx$YCrfy8b94(|W5L4#$!Xl+7_izgArlQ_d+ z${)h?+uO9{V;w$OI)NBD;!v)JIPJgb%JZ7#V70UaMMWW!Bp69xwGoyr*4x%AvMJ*e zN!Bl5asK01^|mW*I~Co-Lz8xQ9DZo~HKS*RgK;4VXM^!=JC-h0?OxI@xf{HLYLcZ? z3|Rm46mwTE{q~i%x(?eRB!tv_SRPi*-N}cGo#rXn{6UMcMsS+7%@98E~bNfD)NLom|z{^&sh zAMlk>YUHx-{3BM{K+J)dI)CnWt<=sEtBD6njl%9>l&_BL zARAGM(e1NGzq6@7jABLsp==v9x znXC6S)rK;{yqF&01oOK&y8OCzVlf-N!0dyfA%D7u<;(LJ!6_A2-ZR+x|M2zhaW-9d z!}wln-`BpLeeRbz_jBgVnfn!E3~`r`AR=k*vYK z4pnNDdsw?!?=*~rZvI7`tVjGFufr>IRr^h>%9UEt!`Xr! zmCKetIo2P2{C3Q*>x^<0&g^-1%hFR*G1=HJVzRN@3X6MV|Np!k!aui4EjkJN92(T* z{6gbr{pR10Hh__1M8vT^jYSZS7-t14#B%rsuG2SF|LQvCkcRgPrS3qqBIL@majS|o zVWeDt_ambU)_(a09A2%ts32tplyxuN{cVTwc23LffajwH2o*T00jyeRC|2bzc?CJH zG#T!Fhfk;AR&>#Fqirz?Zcx6V?(vQ*9^Yp`zg+)#-|U3sF91{NPC2sJpIp1kWNkMp z`a$=K2a0X+vvtYU0-O%igA8j86|$QPNMB5jzVzt%s{FW6q!T5u}~DVZRA zcT>ROuX3sToT2nvt#tt<7vR*4-%&by=VcSR%e@Ht2M_WG1`Q6_WpWRH_O$^$>OBBa zahBstGOUgHufF~#<8sgPwLx5ogi(@6NLzT$NPGX$ip!ENXZ!Z~7Q>NTgb0y!!QQFy z!#qNiyxppJyYRFB$hendzFGQHhe!pKubQLH)1(cNZslcT7K{D+z<|EVY`=z7#$ic+ zHT@x|wi&~PYxOo*=^fkz>7wBRQ!)(M$oB9*Z&K3+BW>XL5%C|~ zGHCd?_@Lppj2$;*?48IpXu=CqCSXiBX!3I}yzux_Q&9NsCm)+&q|F-g=u|UYW5Og$ zik`MX7=8Am<2bA$f)rvMDUOVgOtOMio*89&^C6`tar?dJNv=i&Y_$Mw`k{;Vs*WGQ zWojU6l`6s>QS5TiPR{}^tLACb_Ls3R$gH53P-PY#oxAA076XrNqjyj?9{qGa{#oyH zFFl>A8EA#p3iy|E^l7rjLUz|A{L36>A6aGn(xOgGYrcK#Im+d)t*Gr?7$Id3Rg!Ax zUlufK!w&3&yN}~`>zEDS_tb(dEy`ZBi2Mw!0U6cHKlDnE4*aWkjZ;{_?Ikrq)?BjW zwvkxZ{xjG|QaylXQ}2QqV8FO_U?%84#x%G4FcRF^X)KXCh&o9_2*%j^)Q$Id>)2aw zxlPzl&H&3npNe1VY-PO_m*X>huW(Boaw{C7>cIp9QBD8di4XLKF(hx0_EWEeX}OB| z;3tLU27=?Uck!xkyZ$^CZ}c8%CH3QbExq{LyUkgwmgdp*aE^)ImjC^?mrSg;Lu#gb zYX5B9-+pcSdmQHH_e*E=Ilqs4nD_EV{B183?~pH30wK|YKn9W5!v`SZIFXWpOp5}N zs2+8*mB4l3Yj0fFZ^&(^SC@R0O6Mz91FdT81~7R)2>EiTPG~I67w7vu`XOirAA*Jn zlb3;M%fR5DCX2J-MWEl~36r@F8%~@{zuses=JV9Or0gD8p?Lb2+Y0P!zxa;<-K(yp z88H{6`NDur##;V3oxxmZv-beS6o(*P79<^7vcDJ{a=W*U&K5^QnUaE_jTo=ZEx;ix zN4*yx?+(fpji_2U>@xk)j12Ge!!yq>_;3mia_R6L zB?F;U+#6(Qn)bLEj$>`d;|;GD81)Bz2Pn~{B0*Dln?c>$T3~Rm{tc8+T%*V(wW=L~ z(z4|>3e%v~fo59K7|I=>Xp8&|3YPRH$>Lhd zCJ9}C=q61}wucUa!4|#s-Q$I3FS?D+sMFy4KQZ}~i&N8FQ-7Qleed@XR*vF5sAH6H1)YFv71|a_AgsC|BU`hP$$&WqqwEn{j)+ix>pjvQy;s0*yIT>KBoU?(BuivK8EChI~ZI| zw+

iJoS#mu`6S+49ZcPRQQ%8h90M){$PrKsdY>U+C9=v2V)69CELOE0~Fy`5-oc zZ=@>Fz(_^pe_NEAE}eJ>+by_*^v4cu*jjB3Ie-C7NXV^03BpeG`AC_p(7aM2ifo>g%E;*FwI&a&Zkok*5|D7+6(w+y~B0l1zL-hMO^XH zuq~Wl`}-NaLml6*lP*(;@#Yj(^fQ!Ymp9@*j{Neh`AMhLL9?2hrM0jirz%VZfP|k) z+j48x+oUBlDvWSKF6c;`(>4e9p!3u_r0L8&@YB(EM2Dz;oBLaJ^4JBOc1JuQ9irkQ zABYLap&MzMg`4A@mD=f$%&I}Dr<9Z7ATiGZH_NA~hHN0wuh5&eS)2{+*4$ReU9>L~ zQvF%KLu_yT`i$9nhO(HBAR$-4%Y`;y*!~X-JWshu`N{`I{bg2?T*JWCdh(Qc=qr_L zR8mtSF_-L!J8S=^wY%GtO*BX8*Cphwx+QEWcQoU`yR05gD_1C1%c`6^dEYnHOZ@Gxor5`T)l2Fj#+~(>=3kv6LYo>!V0iA_^r#6x&6&W#I+0 zmzAEyG#$-xOhKWeMr!9G3w+MIoz78oO@?&FEFO7V2TzOq|5=o#%}1kWerzDoFhaz= zS%0=Z6Ug+bCr?6?`j~1@9XK+Y^+)oVP}otp;M#vMe$;RBEYPUGm4N>viSLnW+ff6l>d<}g zMbK=|T?q z&$D$EgNu`ri=^B^j^rhgr-i83;8~4G#HIhl1L)Jcz~(&BY|veh3E8``cbyja|iAs zjD+bj8c^Yn_b(4vRy)I*z3A^o72O$fT|Ic-;K{$+Vo*nYN}X~pQ4`UUwPD4^4P9%j z33tm41$A*PUTbL(4f|NryBO+0Ot-uo-2Y=MJ>2Y7|I>zDEnLTyJn|555+j3> z?Yh48GDb^!zt_~;`9M?^{V|8v>DK9sOz13^hY#gdE?nq9Y3T@G{Y6A9QKWCzs8STzd<`Z_tN!V0BA4Cv#bOK zSzpyaX_iC<9a>!Ab&>=6hbnDP*WtgXY_J#>oXP z-oCP{KRKmf*P&~0K2-mY8V*TOrYh^uguS~GTb^{}j=#8{nCN@3#xc#$@iehjk=#i2 z_W64Cal7kmX>jQ;Ok2QwY8NQt=}=z3^R_;^?dDbvv%_2I+3@+=LH!(rv%71}OE~JJ zi#kYdhpT&{X=lFiwyFNxMt=h<0_BfZ`l}wX<6bXazX%OyGcorH?odCc zHu?~}zlIG>-qcfw_3B%%r?F9{onA+pMwvBVe`OhEPSHzX?|5oJuUNXjT|Q#&%a^c| zhJ1x?Bh&u-XMu%zQ>uav@<|(Xqg%s zQtI%6I&t;`v(Tn^3V3-TuBmFq4uf9*>rNb#qns0|DgXz@2qNfat*AajP1=3Z?0mL# zK<|7&AT*@EMfLD8U)ps9&p&io+z#r-a9+wwCn&eb%7liH$~3?qnwNRY*B=;1vr?Kz z5+cnIs*ZKE8c6ghHx1Y_{%UDwr!mzoX%{30loLe%3agNi;m~og6FXcn-$)&RoM`sD ze){J|`h-PtGYKnvfDj|No)!UI6hY85LB@KSh@Zypy(bQIVi(Hr0qx2en$?TK-1*^%PRgCe)Ot8^w@vY)szw{38}&2pnakQz5)xt5%M+g zh@};L8+*n^5Q=W6$G;DfnHrBRVPE>yD;o@>Hn*KTPW`n1)JhuzZ26<1fY%Y=Ww4f# zqDfUQNGP@(Wa5?Gu$lC6Qrgd}35Wmhm!_-HK5_;rGOnCJYYqwO@aKQVT1;ciJ>Uul)2w6S|*nr*f*du2AvSI-HSqnb0%zWmpv| zXsiy#``JphrGGM^-_XZNrKBOC75DSo;~vIs<4B#)ET-eC7);7qQU7pkp!o$Z-*I@S z{zVe`X0ba+>G6T{XZK9qIR~G zN~g<83txDmTFTyD5*TO|eJ(4(RA;3*&o%5JDx_$Upz3m@SzY>;>B4h{Z6{S4g%pMl zIP$$Dk^E|n5?86<1YTQm8@qMm3D>dQd+Rq(er%sO!x5f$Qng! z@H1>M%<<-$krCP5Zni(d@1WxDNJ-2WF135Vw9tfJ=3D5hj3-i=bvu+fJAY+D=LlP= zkoVSc!N7>S%%1UmI@_j0`=H!6%2t+-xeF4pKE)Gmd93s`P_77)tN4!UpR#`FzUMO_ zha-uhkJ-p!;XiwxsrosE^7Rs5)JL|(wDqr;enegBagr%%;OU~ioW10mGvCqvAKdmU zVf5LrE_7|jrJ53R;6a`&=YA4=8a`d~OGsqy?&k%S*;^`7Y60Y3@p5PWM68MdpOgKD zCSr|4l5yKcckQE#zkLa7N~Xgr&?5=1h)auv6xCOorbGo56ghMqo$YI1!aZ#y*K+xQ zH(%uSIlTGy?pvyZt5JM6xd+wvRr|oZ+QI8osBcZ5hHyi|lMpjRpD>RW7CLhr`pXPzN0pB6#^4*QB0tK6HF@uZ8$-n#uLW^4?R8rsCWnY-C^#}Z1ApO89 z*Z1bC9Z4()9jBj!8c)DzS|_<_0NgrREF59V6|#{U`|sB5kI|c9oFda+K)EFSkF85v z{ZDKC&CEPHH9oH;@3LZ0jFQrAvn}vx`aH}Npm!lbI51hqMGUS*=~>KCD(p^|i^x-e zI8U%le?_W@tHY;iB;FhKx~wviyrI)tWc9j)xz40WGMc5J2_}sN{u3`>r;1mYjbxw= zjJl_CNe{PmXx5g+M!@7YW)4##1|KXHA`jSHYtyBr)_j?bAOne9jsQirYku2&d?7N( z)4^N=ItN1#98ExYP%I0Mz_%gE+`UpbwLPD~^-Lo+`j+7gWPvaTNr$noYLWx@2 ztG%<$>R=Ar$uw|uNne&JwlU?oe_315#?EIvnW~UCTOPF0RmV*WyqRsLa=hA5h?KsL z@=Wus$_4ODynqZXKHzd<_ZN-_IVq_3d_Zf1Aa1+yEAhtYydq zLlAtL1Y9Z>65OBsTa?8u|m^?TMC3t#MB!byrKsH!B| z;cTrPxCb44!##uSJtiNi9c$%*H?q}jeOGV&|KQ_G{OB!v=6!3J+TBDOP2>Tnk)I)7ha2Dl&xLF{WNaFyt|p zz9{z^I4w7}#LMe4hdYI6#osGpqna(eE=wxs;5iV8HvxG%RGI-}_CAv}@FKaHt__EY zpcsreq6|8|`45ku=yY;6D>v3lO21yReGj_&W7q<62U8-@;Zm6k*(kMjh|XH`i^+5@ z?Qx0ajy?}dI-*P;Aoo*<=6EOof#!Ky|BK=o8WAEy42Kv*Ay5xDK^;RGDm^d8uGh&G zdLxFV^siZ?5wD{f8Uchn9D|_P)5J*M`l}nf&KyfeDG$&ZR8-uLr#*H; zKQGEFLAa{O8>%h|*p4)m+jYcL-+J9LCw0gCs4q6I)W4U&%J%d1b-Osqr2ZP8gELIsdVm3>@@c$BT` z)e7z&Osb45BbAr|5*xsX+g+ocy&`aR?_^f0Xb*52uP11I0K|X0|x@MlDupT#R0XQL74O+eO@ozM^%p8M^!# zY^d}``r7p7>{10AT`$CLtx`OVm8!d+y@gwrD>%{0+T>+&BC`#QKTREjxtwpTW4Y~L zS-qc5?Vyk-vaBQ_n-&~iXheW4$j+jDB8~v*Nj79SU%i3FG}rEii%jh+;1c*4-f?#U zUp>YOegFMlpbAhBK7RBU#`CN50^uZ)SjL#I#l7=r6k# zUAu;>y5_pc+2jk!hX#xo$XBK7D+XjE6YD_s7VgJjkn})hEaQDf=}+{+q0E$p28EZp zsWN}Gt~6B8%ce;S-}4$*4lH1@gYtpQ;3B_W9c0ypsn}Ix4QQuD9_lj-MS?zSIcB)e z7Nhl1aF7i^;PI2rM4U4}@?tNIIk1HVbO}k25kOTu&4Ed5$C)oylP3p0qSU*$80v;yLYy&0Jp^x_AJkp$wUH#FXqd z<}{t0L5~aY={x->W#iUQe>ZhvFO)k*9??4|36OUIf@1-od7Q3EVF{S<5QL5-Wl5C@ zWNY;o{@$yYN?m@BQ*vp`}e_@KU^rkcZdPc@u zvxeWr<`SaJ>iC;uMVY2FPb%*AQzUkZcA3ft8T%`JI(I7G@a^a{H{|Ygf&M+)aBI-R zFka2R`Ag>+ADuz_=(NPBh(uAA;?$HJ>}Pu^ub*vvv{_ir4ylc#5XbQOILT;oLC&s> zbZNmCwgD7w;uW&RgFjg`H z8b9WROQzyeyCQT_bqs%hEsgH8^=PXW8TW98c$}^X*WIIVkV<%J@3VFLH|I~)iM2Le z>SB@R6?vD$mEW25mW?+)2^ZmYw;4;?C9a{;gu%Uz?M1*lxt_}f@jx>dWAE32>M{|346#T#)~PnfF*@l6B5m?Z z2Gu^%Y_{s~T-ICZACo+7w&Hl1mVr*>O|mW0<_!jh=kW}^m3}2R`H6I-22BU-U~SUC zV{qb2#7n$~6V*tgrVaNYjzdtUTfwcZFnJoNnveM*Z>1LaOZPW-O&o-(76iY8{i#9V zE)`Ym0S|KdSAgR6B(o0=XnYWiePlcErB{MSJiZZoK?~^h!|=U#InegiHXEb3>gkZ!h{(2E74@k(lQe|FWSbafuexq&-rZuWog$!1KJcj zLzS`Oz*0_dlyzNy%7ku=&12a>f@S`RkVjk?HVfX4rF6KXI$Hs z73+DOQfwAS|9jp0*DO73mpn3}l-(9qOY6Z{YY@YuiMl3U2DyKYyo43z7&Y5aq(x?l+#g;iXhYv6p5?9h=7$>E+dYMgs~;eS1Hd+mU*M{;DL zxb}-3M!f+g+bpa4*>lpkDu4DNvzC?*zu6NXZUYmaM-S{0Q88c66$Og2BOcDo27~5- zQMW!eNqft_3F-TII=@NMjq0_>}}PRcPGZg%FSeLh7s(uu6K;o z@bY(Xxu=rjJ>f?vDGnVR`lX|H8*wdgkrc^QCNq5^3M-X(<&ag;hr~|xJMlO=B0L5U zx&zUm<}C;~B4>8~&)pcIw33@$Rkx@8u}X$idLoy2Y>$|EO|aE zw8a0bmvxvvf%D`x53C&vLDEGKD5Hz*o#2;cDu<1eFK_#0rrwNwBo9 zi08synoIZ?dqP)t8QY?+pxWF6ioLPYI7upEz;tF(jTxQ)0vE)RS5OC)X~BClHAM|0 z;3zvU02^0dvG%{Gi|G%s|m~w-JZKTyQ1x1FI9ox769^vGju8Z5Sy>nKn&R z$`l_&$UEIy>CA5PD6jDIwGx#N6)VVLgE;Z}S0o9G(H(#9_hWb2G zd`D5LFj$({0$d4yc*u}c=BIxE;c#uiDsW4szaU(BOXY;pN2(tw?RDFo#iQJ##6GjZ zpFsLGAQal~cIotG>kaetp1?Qi;0kwiNTtt_)^gQH`eck~gGDMe)DyRE=5BMj(}Snn z6`VA>oR#meiPWk;>QFag_k^x%>%nk~o%=xlF^Hr+!F8^Dbt@PnX0a2c5y-sF?Cn}; zhAZhx4^L>RVGg_LP7}H*+~ppw(}`g$*T?2(PrR=~14z6PUap}jTs~BfEHBCv@0so9 zWwwh0RHd<>BKNb`wea#WewzA!yU0%a8$bH5=MH^q5)NN8?ak(Vp2CbHyPy%fF!nku zFH5G&N@FS8%WNjDgNYg@8)Y#da1;~mx_Oeu0?6a*XiqBXai= zBwA8rgSV+J^(n~9nD<<>; zR*|Fbak!6*a2>^aDng>S(r=UC)gMa}3z2^ob)6c~40^}4gv5$ojV8UJ%8b`6N5UF8 zGWOu$7wS85FI^9}Tfq#Ue0%=ag}C$i)OVCt5K>*ypkhyO!-jhe2PtYX-3X{B`$6)F zdU6j;So(wZzddBg!^|!^N>cFxNESFe1UBJ#By~1>nhZ2Hc)h*c44@0Gq;UA*ZQW*U z%_epY?c>Fe7YUA1j-6}n#lUaa=(SD*G5_OS)|&do;4`P_6$&X*`sQL!V}+=d+z z#;JR_MP$9A*7s3qKLVsAP^8yJK&{sU22aTCqkt+yooWMHki6FUC+rk0PUpAN;s`j1 zPDsU;p#Jfi*NwAS&EKH3imc=+&&c+Y&;8LD`nY@?hy+un<38REfhz<^x6K!Rdf-k& zlOr!8OM=+}#i2}pTfl9(GQsHHy#`bW>fmxw8Du}crKj)I`8{!;XD=ueDhHLPR7(}I z^yr=XYFrr5>i`VA_`^kD>>My@fF&B8xl@vI!?*P$PKc_Mze-}oLaAz`){f|P^TJZKEu z>fb{#`6`+%E_ayFTDm6~NXx$jRA`Cu<*wviwv^R2>(@NqxFvyoR2g;8$i`&a%6H#> zbppPlt)UrINjy~{uu352uNh|7@Z9jV(eI4VKKgbdD~!G)UG5Mq&Rv@@Erk-dOnU64 z3C}({`Kf0o#79kdbn4{i;-e=&^$f1CW0t|0_8mX^+kc<9dJXd~?y75mp;e7XqMS-* z3iE}W$&U%L#VCujz#5nbFkb{Mdx-hc1)Pm_FCgv}hpHvpK%fKoTY<6xD33ebpZ31J z#;8W+Sqqm_A|Tj0UL4wsBV!Wm(drvI9tqc{xxloLahESEFbr~wBquNuDe*uFNvz9` zAG_+tn(LM9URc{Fn?bttP*zr6VM{9?VYQmLg1rLkQjuJ3He6(*TN5=NWtUJj`bO8r zSqFC6;x-h|!W>c+-62Kr1Z_9|n|>3vi4-MO6lBGbx%zC-kaES1q^hVg!y?Wb3i@qS z{n1R;=e_CfguC`%{uez)R}By5s-;y3SbW_U~t8_~K|6=_iQdh%SI2g5X00A^Hd+q!5H!3JBW9vuBqs zH+MMJ4U;5QlK5XCtA^hcRaoX zmJJ{twThxGJp78`+qNXJ7={Ef5)=i;Mjzg2O}l6wnU)I%C#1+A$0a?eL;Z+3T67## zJn5*k)_UrivA13MW@>1_RWrn|RoiUcM_(A7qP@kdsV4By@HZUMN^_5`(lOCAV%mpj z^wO7GubDxra643WDNrLoHUXgNw?UbR4=Yi@Y)Yf}Iv0r?E<&sR^^pEp!z;jAGTa+@ zWNt0g`P^ag+PdOd;E^e%kGh>6Q`dGH`q&+ynbJH30mU2f+BHO$UVTVsX!s7e1U%Ia zDxdvc6=66i{Q1K(IM1SZ1gr!l6v!6?>oOWgd-%JDFdkg4vv~o5;#fuuNu0~XDzp)y z7r;1m8{9#bg&7g&ikCQ~|6v8cEVyZkG_@|Qkyp-x``QM(NR4NZM-W39k1Ju*tad-1 z$ak;pCKVA7SMvgb&EE2II;*sD$j_n3AoK5=SOJ{+2`~pmv9zfb*<1&sS-`63$ppjvP8yC>9cd+tA@Jib7327 zaEtlAnw25ea4J3gI~}T{?K$FQQf5gy?$WOz=}WT=#o#(^0_V-xkLl`uv#;6e0gwdD z_ynZyvZbc=zt^GqQ#+(?0C|Q^A_zQg5-GFtzuHXsNHLBvtROhqCC?I1kxS zI<~-LB?ma$^@g#jtE=`>Nk1oQG=oIm;|m5PTGFL|{caQ(`bdMlIQ-Qc#>kyj+ej>Y zxRKN6?!*NX+Em?4HKal%ebYflMu55Jb!ZL+&QxE35y4mSlN#2ov9y#{7&+ZjRLzCs zz;|9W`&m%4mCVyjwuqq}F4QN^n$SHpoiIQ%nxCT`Z*}gWH~47+;s;KhGSw88kBFnU zv~B*MCnqids09#%d*|+nmcSA|=YF{V=-`js^8wKg&@3P?09DTpe0Z=gpoO?78Ff|c z1RG(|XgUN#D5Ux}f+jFJGLqU3-0h%tr0Yd#By8X|P&>ej>50ko;NI<^WN3ZklNIAC zW`oBUgT-JLwGm{A|8i{xmE%*b;I@JO@#VY0Z^0(;YvA-e)9K!6aR--GP#~l7j&Pi7 z|9NArnMUx8tA*22RRLGF(&6WFZtpe=e%{r|sl`E6qwSt$BQ zaX^d#yq}W#JM!Ut(9_Qf&q^v3O~r%Zbi(EgyT3BvI>nmrZ{w4940z`8pV;{6(yL$m zbE~P9@^5ETiL%Ocy42!xjXI5Q_4M8n*vLeJ@pL#4OE_fKWd^(ep<{tA=AOcP${!r$ zkQUmG{r=te;KU!GVdvxX)iFP=?fX!#`^ra!GvU5J-vZu+#ZL!c@caT)4XGGamRSP| z9_~LK^q&PDz{M*C_IVf06M`<3BsPMd-`aO{^-xE6=-D;j&3q3`{27{bBQ%>E;2EqA zh>Wf~4Rm7OJ6~V4ueRBS$n=HiHS1`;ULFzW=Qw?ip3r zt8PU7^T{!U#JUBZ1z{whR7GlFI9?R0RI8~qTWM8S$M?`0#4#q6BcFBK zk?VhK$FB79{`gv&$*Cbv4Ly#Dd|&CT?c4QRt!%2vV^rbrl2CqFY0#ErukAAiz)9KD z+v&bFeFn3Qk)hu=@7#WDgV}sd>HzDbQP#`w85?(PeZL2OD0PMNWgAoOO#ie^$vQfE z=Ko!)o8d)OMuOr9YF+(l54L+M^c4xys^gC6*d^l66XM3G?yM?I6(pY_0x zq>nO%$;P3%M86?6d(r(#4}5xN5ta6YYf`R=gXP+~yJ!9@Gc#D1D0@^vaNFWp`;ngZ zi!&E#k5^OOK9^!Yg{?b#+Aq#*)ZwD&_6d%3#H}Cnz}vD*_)vYFH`uo}V3WwzM|=8T zo;^d!;gGCE{EoCnTR$|~r;*lL)D45#J|$zu|9qMhU_&78unHYDo&`>6Tey+-)s(os z)x{o%it0wsDBXpps8qD3Aze`INR-*p{H6u(ES${*vK29ZrabP5#{EZ6`|E|<`K&iu zQ|JpjDlP8)lW_}i(&gMNt~?Z}stATFZQWq^nV$Buau;YhB(p+L;cObP`f3k+e{MS! zRJCYGaTVCy?2(q9`F&Hgf)k4CTyjY-hv?JwanJbc@~df-t`PWCxoFRC!v);G&Z3`1 zqYuCS{u?5eDw>#P&rNzQbRzaRl8%A-%GB|L?`;Bij=HZNE`mn(V~iBP-ENgg2kQ{_ zeGjXOL+)rj{@YC^d^@?otuwM-k(JH5AHc{UyX4Y)Cj2`cE>N@^k(|diBeyN97nh(@x&*v@`O-ZJ1gPa(BWoA__Q7C!w6FiVGbFa6M( z`ypzx(&wluegT*R z9^3?82lbG8(#R)$(Himq)9jYqDld90FC;^~cCPLF?c(NXlE4YF%sQ%}ub$fjU&F1` zuuX*H6xD`rc)bTco!{XagO?P~2!*LvWygni!9N}s!|%4>~p6zKb)2fkWZ?yc?{^42s2t?P)dQ`4V%;IoA$ z4=*q*_Jpzbw{1rce66_B)epdMBLzZ^`F+&`Zxx%gn7~L;k(BNA@BMQRe5<%aqe)KU zbo6f*x@bGl1HUM)b`_J9KTm;xWB*QmKYwYznqWw8lBRsNZlL2Y20Vq_)8$2U@g;y< z9yUvtc(bvpUUsdoj%{yh#v#g0^gtFSZ(%Gyc!N5%{<8hIdM6pA%~#uLPnx;CeE4mH zD^aC4Sma=6x?eLs!$?{=M+p@JWK`Zya+E!J)qocwe~WsN7Du_BDjZh&Dv*Zc`V1X2 zan$3EB654Tn)5lRY@#bgxuHss`r3H1rN!u|012Nf`QDyjLtk&Sk1fiz{JLizN7da_ z#uu&0x(jL@Ss7*-@M@G=tsS9V3qj>GcibKGy9?+HlhHDfSkgZ_s6QlyadEZwoZ42r zX~?#R;upD5&plN1CR_(@yYFN07f}5!^uG_v{|KC$vC>?@g=o7LASsWZAsv{c^X7+} z3}wg#e)RgSpIH_!Vh*g21uFW){pI%N6Z(evUTUGYgG`n`4c-A&l`r)f?EX=Hnj^}! zY01Bvg1Ah{4uV#)Q4kyYiGm|eXFY{s zt?(Q<((4&H!sm5l*51h)saVNQDj!TY6opcK?OaW!KHvy>n)GLK{y@6Wd;kzXpsTWe zPRbGb!J*;kt(6|7$jw>#5j4C_9|dsJi}V~S8;<4*BVmVlKi6esmuI$-)z5(fHdgzb ztxY=dt+A9ClCHDcsY&taaQwabI@J-LH)k&XAdciFu9dx480v1wl=K?#lzpBHr_Z%^ zqm?^H*F#X(hlGx-Z9B7AZQjJU(?YUT5mO??xa&1G;5F4Yyx|a(!tKvR5BD!Cj2%R@o5sn_6VC9RNNp7C4D5@ zBXVIL8!L~AQ=<7qpr9}rv~Ts*661iR%^;sGNET(H37c`bS!}5K zp7vfki3>Vvt*-raN{|ph3>sW9E;_O7d+v7iJEx4iPFK`}&{sS-?kyYS@Q&_YZ9=!Z zI%v9NC`T0!VjWQhe>!O>IIp-Ck(mJv$!!0=4z<>`Z%ybCR|ll(>qxR!Ep+%X|I37a zuC0S=d}KQ5@A|_sW9M)9mV>@!k!(Y0IAa^c zk1RW71bNR6TxLc;VAVT+bLAUhBiJsmg3QL_iA*BqsEc;)6LU-F2RG8Jta6;BIPzn6 zer-Zm1lQ0ZH^T)zRzXKIUDM8GR`Rb+07X=q4Z9deVSz7CV#e~aF#4;-A7R7SI{^I# z5QnO(P&-ho&@6H_xIelU4tzMW3*5dA)Q^)#vIG2sYm?O@{{TGwxpMRu0AB;(zk&38 z;VU5V1lyOqCB77-e^7Qu-E$4Efs(l({?odzAbK5upU`)QhxC8ofu|pt3Bu2LUj@ot zqb>pIB=9eV!#;(4zY%|c%9x_RLE&Sd%>|*?K=NDQ`4~ih1S*Pj|c)#@FKpy~rQUHIx=)`j*(Y{K#e&1Gh1YeN~cFS}Dtpglp}a zSX`g;I9e0(H%Le!1U^w+T3TJeRZGQ#M!W)^j@{|>SU-q|szJ#k>}hvYlRZ?H5s^5& zDqYrC7O(LIB66H+2g*E1+KBY4K>~#cg7*=Gmm>)OZ2*+n>d~h4 zEdH>ao8{w0mS&N}yF)|kBAK9<(8;(!Wn)%hUMN4@ACr`e6_^$K3ip ztKVGi0CyzD-PcpmbA6Ygemup^hBU+d7kEAwR`~pGx3}OHUJ!VReSqgJRu=zU8sdlu{leHry^jlMjW;wn zAqEE}1yciQpy7_onEG<~EF%-p6OQ~ApBOE%IYiju3nO2Bg!lGw$mU-dH>6Ey_ZP^~ zhNx7~*PdF-QDb52gr-17gh-*(iaM98mu-&gK4!FT7FLGx6g#|#2XGjLK3d%8@7#7ibqp3Mn1qISRJ6bQwJz5f+DXygHx|DgEu9&i)c7twc-2<-SBh zDUDbW8hiJ%SjIdjo)7WNBgkS#Ke1j!lejrpC&@LvM4{4=eCjK!WHYo!IjLeVogEdW;Ez#^I;B}XQ^FOA)9mA3nGBq1{dRY4MjSV#ehB*;>R z0Fuq*w!dL4Zm~4apCg&ZLW*{{SDl?*hkM!~Ee?gT#|6RUIRLdd30#Pvixp@k&@mIH zeQgZ8TsrCxkWgj-U}XSB2@*Q_f~ub)O`8^Pkn=Zcm>VD2M2EFp<6MR#RR-yXw1t1SUR&M(t5IGC$|v0p#nD zcpFH61Bp_37$I<^2y)5-z={$hf!b0@|B23vkLUjjYC3L$JUwAZai79L1%+OhM3ExV z1ju6!4fd*oH?A)LI6`^>vjgf3YalEJ6`J!(T3AEAR8kkTe3q}+`li4CD}bXFchOB$ zT#gQ7Nk|JMU<9&YsCmW_%$8nw<==sc6VM%N72+rIZz1E?1u{@2^iB*cuj^aaf8dBo zg;hb1pYrlN%MW7z8<0hk;9^Khs`Azh8ripZaY!Ip9?;pJP|pc3>sN#2hP65-{n4h` z@4p6&P$+sOOy5-xUNmy;pVOy@)66k9xOjmq$D)#C6YmozXX+b_6TLC>`H)}Lf&s;4 z@Bfw)80B1w*e zN(l={uGGZ{9OPV_E^u&=Vi`yYs>yl)BTixm?!6F&=BUTHUfw4XqlBM=lfYBy8N@xs zy$hJhw2!)>NPAjd#|A#LlzKD~%9gMPg(bGu1yprGS(>>ulb z>Xq$8X=yTj$zwvFtCb|fKTp9vdzcFka!k8Zrj6hg5y1hnd&abRx?G~0$L^@0W zKOzXhL)cD@JLlm~QpmMZI1bK%`n(T$fUkDAQ0ItpTHQ0NE5c$bK#>tYNjd5}&wb5W z^BQq48PR7DCJ2wMbzim6+PQ<`4!R7$GKs*dX%gd^eS`tDcEUgk*CDLFmFBV-1f z$bmLu+BWKkuJiVngwZ<}p8luK+y4NKCia1LaJNj#P-GC|R3c4#f&&;$MjCi=#PGg4 zgkeN>aN(nwMnXoS498Z_1}}q#TXYD8M5qSGSKnWJe^D8w%FKU_=^+t$RB#clAQK}i zCl=L(2k-;H{fwp}53w0MJ+WY--xBV=X#TY!=3IfNsC2$EpDL^>wrT(2=0lXe9(4t^ zm@2O?Y$zB2MTBI+vgI7N8eb=GP!%Pm73IZc6bKDwiv*C@ggLJa?wvb0vy>BM?_XiB3pGN%N1d zTmbHx0q%bInZ~!l*y?1Ev1QoxT}QXg1p1x?R&sktFE6<0F|MhCppXhTYT|ukpBU%} z5a}?!#nyHDI8{{?iB^_4Wy!hAmcWUFQB5;@jS@8h$(q0+IqYG1x9W=sh~aSf7y}Bc zMV6uv3uuuIC1u_l9%?ERggoB(-+f~6xZ9X!vbZiAFRLw#IUVtqnBpb7nk)+?dKU-d zy&PM&Xo-=ns*RsdKSKy2h@;UQJ{KlHMCgFvb6f0T>j83N11dSgwb6veLKxTit)xIe zofRZ}rMht9B8VdW-)?~brTVjyYD`+ghjHr-<_vdnT@;Kq0ubv*Il@tYZO-rpx0O^m zT2@#_vQg-z-z+g~On8RS_0nAE^GB5={W)Nr+U^++uhp+F_ znI`ly+DnxIs;rbE%N^w+ZoX-bD_nj8Yz!PG4L-Eq8MI>X*6oYpTa!D~7#!0xOFKpmw}`C*LZ8_OD@ zsQY&sDb&vihbWz>Qe3u*r!#`illv)$E8;F=MDd)kf@}mtv>zlK4(m7nZLa5vFptvr zA`*n4z+TUmkIWGkiJK@=ml11NQXvVtpopOy@bGds*hEEn79 z-Xt@!mSS&nWYPI{E{V78sJI9RP(voI3j%VQ1_A}>m@a>~VvK#kKYeW_WjOJO-H^$} zNiwFBE!Impf=lMFq^2>58a%l01zd0EukBx4zJ@c(%0wq<;k_`R9gjJdw$)m7dk<0q3 zLaE)smIfVHL|W+KzVAYlhL`c43{ z;~|l$hxaD*$86++_|u__FB+LAx#XRI$d3Ep;HD2T7$;HY#*<}tlCX3<Qm3gqu1VUgL?uxrfy#d5>tV+A)I64f;XQBzIWl@zXi zW$wJVnp*?Y0ESXMkK1&x{m(K3eXQa3=u&hUNhsy!I}#0__3I{dBX>w=Xm#PqZM|vJ zr}$q6R5-*vNK{t=Smzvf=Q-;_oZ;pJP@D%;Ninojv@E=6O=~*84N$pTS+Z~hXGgm1 zoN>vxi3|8H5C>E`0i76r=hbC+#qJ}#ItSD(29dm2hEz{~q^oO4N~cx!WUijalSv_QHtK>83*6v`M0U{k1?faHG55^olgDxN zy|5TP3_YVs!aatv75Q7NLuf~P09k$y4J+`I|m&s&?(iDpBxx{79Mdg|R8WrWV* z@q_y75GJeo@hdLYp_IPL7@2{E-mvg?hRoeY+o`qYeyR66Es7#{KK9~c&rW%=bnt|q z#BX^N|NE&Iro;z5Id$?QPfq&>KYHe}=6{;jyYw+CRT2rLORdO7q9@Q)J`A1?aq4K)FaYO6gJ8&;wgFi(0HTr&KX^ccD*L~G0y3{* zk%f~@Eso;E&jL;Qz2%p$%U`!+naFiep3o>tS2gjT=-b!6$#ydAA=i=<6nVr|s^CN8 z=$f_3g0c~3Q%9+)?8r$KnGqAc2Ze2Ke!~t%q83u)kZ|p29$n*^oZkK2H*B$rT0@SK zA)x@Bgt%9+1(qiH+# zS_LhTK6X7YAxH*+3pnOLshquHpQOd?O2~wVNpz@H_VluOryc5Y_9SFXlcs|~-v(Iy z=f#d+F1rWRuvD^|^GB?0`s|A1EW@q=CPB$ThV(J*uECG~HOsDhBYTb{>S_q0-aUto zICOTpP3>cQpg3s+FHLMk-o3nS(4n4S*McGm!v)ICGi}$s>{F-LgIG|mVZ~9^NbtdY zUHJHl4Q0ELp9%gCn6Aq6dv}&DvOB>9no5r6NZ%9wtPA*?I+R?;t;JG`MpBeXQzC+d z8Dt<6p-7e_-10U{K7GvT!A@=~Y#@kYJ>f_Dop;iqp5nT|1YW&otQh#Z4~Tcj8QUN? zK*lk@#)6a26>io?&bODi<*bUcKtdqokY}#gJJ)Va z+=%+97M{sBB0LfBI%m0U$@0lRf7=(`nGqJ@VaNl$+0p(i#9Q{H;8+&!e7%B&=YNr zKY!MK8k!5&D#GMm&>uflqHuepAKO=BtSzE!um4czK!9yFk&f9@4+rDDVP&7A{(M1tss(h6+t_y z_VO8f&fbFykpYOfP7o1qRX6GODTTdKksz9Kgaz3B<#Ixj?E|7kJp_+g#JVI@XplfUfW8FA$6vC) zmA8`9rO^yM`8zywL#4wTBoT$91n7x`w zj_w46*pQ~VRG8wTKN!6jG*Lz!t7dD|q7XMJJxZ%6tR$3bpvS7|5EW2TR8V43DnLd8 zbfqluLDU)wVU0echF~nn*JPLws|14t9Zk>*8;S;5LJB}Gf;dhe&+<}Crlnd)N(v!2 zh7tiKKyx}hUeDFC4b`EHl*$S0_bTZM2Ig)XZcPJu0sh32zJB)s{RHvE9yI0e{cnHv zrX9;ZNbY9;0mR>f;BEgAvXMvnT^Ff%I8#c+WXv!`iDSy>Kz2m;`g7APU}Is-0E>4} zv_KF(BTsj~MU5eOGuTe?l{C$gw?Y_q9tVzZeE!LwS&sv=!A3f*hU#>l)q(<~X_65b z%1WZe1sDjOJ*nDza)aC2_b#z{3SFNePJRrlK3vu7+bI$zE zB`>lD%b5WNkQ_iEE_6tB!2<|5NXq8Xr(;-3T_=tS>_RslSxhnTsR zJ(1%Gs;CogfUm=zK6ZyUz;v+21d|S4rE|XgFP~WCd(aK1m^~;RBtoeh=?IKe{ZN$V zfbZWF`rgwqP-%EX)tl7ySqg(7^6g3E210ibis9Y&AqVR~% z_2(@c54H`<^Z0IyW&reAZ`!*~UHqxFKrbri={QN`Wus(D(dLK}azmL3%ck17&?;7o z;=Rf)S`@npGSI3d625` z5eti1*}=sL>m7{n$*A2cT=FI51jFzKqLJ>;q4|PEwo=Zj-OT@{ENDFIrL?E}kDuDg z<|(y{dotJ`YbT!ltyLKRe$ZUUXVs-(r2G3DR(Z_GR)*K` zzFpiZE~TG74j z?M^Rya+hE&XD3(>Y9zU)T9$m#|I2>+k6-?uZJs#*PJkMLQEO!~;Ayj`r{k|9h?x!h zK*jxzi<%?uckVv=Z(9_e17`raCcsG58tsEmn1MgcBds4E1$klEaxmWH6LG%UJqp=j zHqyr-tMLR9`r#u*A^)9%ocpe))ot75lBJ^`frTK*IO??5#=wW$ET3%Y#7FpyN|B@@ zM-!@N3hz7Ykk5Stb^=9JWmQppZ!7J`9P*MAc;pHaHI)~9X&ifxZnHeP1A`}U+l^)b z2twc*gxR(0FxLI**67sR(be0}fc@aQKm{3uA+j~m%7zr0r-PC(Ru~yp(paknO; z5j)O+t*{aW)esolsDPN5GXfwJNRXqM7@N{_w8Ti9z%HnXE+Y+{0P|smCZ|gQ*HPM@fT53^`Pp{@^unwpr!#Un&zx-|J-N+tWtP@_3^sy@ z!D_%{4EF(lqct}TD82DxFh(&D5@b{3#i(Io!9rAW2^I;wD7o%=oMz{&*=Cu|)&7sc zI0QsdQF#(dkhO0#N0vOa%|h3V9sC$9hvA@1aWW~24CV(SPtsC|aCZi6$K-VP*nK~K z3LFF(JdtUF_J#Z`{)I!{cM5cYC;`nBLHSguc9(qc6zBkXf=Cz2_8({Da~<-TLC_0Y z2^bv#$dCtB(Y2t*e(&r46pX4AgnW&PD!fa*ZRa+dy7*J@ogk9K8q51YM>={PYS*XW z0iLo#_*vc;Q@6{ZZuu1ax6U9L>Z$}Rp3?1o4{6r*xbq(u&@ zEX8BBOki1xW+Cr7p4ka22Y!J+szr&7pMfoax7(4zX zE?z*v8RtPC#1->0Lufn~paTpS^4wf|{z_Tl(Xu>BYmbA4!GNq9n&jd(*oy4p*W7lNe*`+URzQAr7^Lp>Jb{k?!=-Qd2<%to z8%87Px-o)h1aAAAOP~G`Sglq;kgO!2FYiU)0gIkO(*BRY0i#|{Khz@R9(JS-+okHb zJy5JGEIk2E8TAa%7z&6Ssv&7#>XqJCtWr_L?>_-9sw0cFc`trr)rqb?Xk{{-`!N^{ zP&XO)=2rozD7c0P`~9!n&EAi}IxS1UVy3LmI|(fQZqX}HWXVZzN+ndNa%$W(D3g_S zD9{yx3&P+2+tG58~Gjl&4WMCgqh9LX_omJ95|F&W#Zcy-qj~?;!IiN9LK|AyA zz>qF`>(~m*&m!3M3FtSHlR`*R1cr|wmJUV*Z}s};S)H#$p;Lo+vknhsgdD6^Yf&}G z(XH@S+1;?V`Dyc?mT>mD`2?H@ng!U(j@Da!ciZb09XEO46j&Urye_VYSeP?Q6359Q z(M~mGUj&`69Jye@aVOeNgA-WMppr3)OvE6Wn#5A!Fn~ska#@jJrzhO`r!Bv*4zzUW z6j-h%AWWx0*@|sn9lh=X;G1W=T7Xndk#vzaoNO$+EIMwm{WKWR2u`;1OA2pqlepNGqWccfNZZ27$Y=^EB9@ zF}#U{a7N)I#Q0DT7rD*6cN(k-8b-)ef`-plH29pujDi$kA1JaU`1^y`z>iv(m*;Zs?8aHvevd` zR&Ol-!INM%m_#yHk7R%%5Wr2sVxtaiTU5W zxK~&CB2`4;aMHC^OtbrpM~yGF^-#~NoRLv@pAhxrGIv@oe*%tx>T!uk)yTBz8LtPs z%ky^N6EFz#Jf&u27y88JL_JTHYgls%7l@Obmf`$@&(JixKmqBePGRv^Wi^H{Fi#^S z66&54etWxJ470QsPh)`x@`#p2z)?|wQm|0U3Ldma&)?6w6VrVfbOM<`A}Q+x%lp%) zw?A#yS3;qggP;wd5m**V!+U5=kPD2$(mwx+{@)#4G|>|K*5N}$J7V9OKOXyhO>6*A zK(D{*EodzMQEXyH8TbanosWks=yjPAnX4x;B8bL*V9D|#7IzHBB$j|?Ly~nAf)Rc+ z6C!=6A6;9mM#6~QJP0;}DTFW7@rAQ^>snIhAm}EY=4ZcUH;~*0#?tu~&;$o9brcgW9?0q*Y4hDP5OhjOW(4_}6FMHJ^J1%qI~g@*2f3j11(0DDZ?2 zwy)zgyJ!sY=g)v+WCfA&xmtD(O|!a+>#=7`{coay(L`B88l{mM9}amEWY53sqF9eU zc?Rqw%|bMjyxFU1)t~KYY{YWtM0reqXhV5AE}sQ2LRLev3S_A1 zAfS*6QV8$2T8$fFNF^xgE;-}-+~tQV&AY+U*8&$y{F zB8lmAnQhzPLKmr(P)BBi$-4p5wv+8^2X{`tDA^(R^kqs87;->Ue6bFH+kat(LtjlV zr=lbtJ!E}*>tFq4`Z{_(r2&YgNq>^Br~g)_Z>IYw1MmqQqNI1fzkk4{XOMh^oKdxe9ONzVOytR)aUA(e2C<`e%90LX8k>3mq01vX~IG*}9kmCp0E<917!!_45%0mYP2Fd0^j z1V^dC>V)Sd^y!guiwkgz#b_W|5i(MqChd)iBC;~!*{I(< zTpk%-H<&f@qf>fejF0|-O^+h37p)<0E#6o14)Obk7VJ7~Z3|@`KWS8y)nrc3UXzJ7 zd-~xE|0q|#m7hz;WhohxWMAggkDeNG>An0#sD@10O48>!82sY>@^l>F*O2*Wwl)=# z3{4cYpyGmlM6KKHZ%51RtUwE3ejJk~(sbDC>e~nHu9i@6fwG_0YsZhgs`f_xo6;T1 zG*H<%yoszX@0Hg!*?R@IcpROlu`o=qh>#J7uhp{Az`lU~cEVnOaj0gwZ~${mN);ia z37C0E5IzgITB<<3io+)gJEP(w87i|YGy zvrP{os!dr*e<8rnI`qK{hZW1#a?^v4J@$k9)3-nR_(R{fnf4Aez6*?^{>th64K^^kcF^(9X{;$$-T46{o^5w#$`lh=l)mP<)1;**=Nc_HG zx+%m7EEXX(uBF8+_=@z^U=Osj-ibpZI`S~uk^2a&bp zbQCA87kMU~pa?oaxrQaf_NIPqwTkzvu$DXk)o>RGjbVI<z%`E~ zttDN(+J>^;O1;Qa@k)-4)v%s+y0>U0eq2NEqG7h;+F(@5TOm&F?zJ5$X45C>0ED7e zuGO|FuM(}6XVcrcBp_<9C5YQcW5v9JaOID<^)~hTE4bwv6kkB^V`Ku-2ofazS1}<$ zXDRlkuk(~+;)q&!T(e$w`gww$!(=EJ%>vg+*$M8qPtg$?-zGF81{l9%%Ha!h>`l9z zd5>dcQsj}99tuc|Akvt7QyzDp_v&hU;nXj zPE`@JfLY9{t`Fmtfc50Im>HnW5Er1ZP#U|+)iU3)P9HA5m08I~+-vGW&|1DO<~$=e z)QyWa7{lDKsH8QC^V#>qc$IO zuM|7g_(kV5tYu&1PV|{L^SFB2lD6*B>#kBqfD3Z?WWDqv0-zo+{Kw_Jn z#p*tI2rpI+8Ry}PBwZZCQ58I9cvci-2>9}st+2g*W|LdsFj;D8mE>mcGG1i$u?1zj z$hGi$#P!;^Vl=F!QH?AcP-T%G|1YG-yh`5%eegyv?R8TX43Y1V8Inq588Ys@Gc8+f z$F2{MCtwp#CmKa2?s?T8?sR>Sy2&C5O9cw}!EN^*vEFC2A*ziGrW8>JgeGuCyeZ|W zFZ0&0c6K9bh{~EUPDfKL6U6tPAcwr%jeCzhr&^`@=?>5m6wQdrg)130Xp#Zl!%VvJ z!YoVM)8}G+UlRz-^Z=nI3DD|#q}s{J4AKtahX1amps_KyomTSL?t@`*mXZJEM zQYA@iD#*GILSfcXOidxBm#HaXu|Y?yq9ZlyZLDqobSgi_bdo4pAq$Br$@8;)>xlFD z3^s2;Bu-osapKd0J=W@xHB1AYkj4}cGtXYWjV z6?H^!WWUisegQ&s`nNY&t9OW90_B8ENpUMhN5PeR_s+k;ny?e>BSdlp7TxisScnir zo^>-#$abLA`hfKedWu~KWd?ExFT6;}wLD4jL6(%Qq~0{()4s5l?)COfaE3ic;>%Rk z2#~cxv{D2y-WP#0@SM$$&#{)wEh-FUCRkbxMs&qQjAAN+?%-hw7C+v*1lJit`~vwBRyqd)9;+Yb)%CM%#DLY-b%+6v-3SWr7Z5X zcd6Z7bO{}USRxZe_lj(L&pP9HHn$6hNKKD~1X@6nMscL5s*)Bq%@E7V66-o(S(&}I zz2bCdtuRQT#yG<_#c1#Rz1!(@XM@lKfF1`R7=s|v0;oxi&Zaja*3Mhy)G;XRgyh5w zq^{07oh9vDUn|yIH;AxCyoU)!XxfZ2z5wr)>jO^^Piz*Z{Cobc*Pen?D^a?KS&MWf z#74*v^Au>A2A_y95%Qb4iR47NGOiP4uebs-_K=qZ9pAM0&SoMM8Zm}v-Pl#lHtIZg z)Q;!gPc0Xk^U+dWiUb@T@*!tz`jb^8fy8$DB5Fv4tLl@XO3y+6^jj`@fIcUT;OM&H zEK}<#1s9IZIAW7`Gh4}FL9=DJsW*FH?|rlTBO7pGA$LN6GFGTW1gLNoO9mMN-`WI_ zDjAQvuG;Q)cQ>~caSgW!HhhXc5qV%F%XU~runyjZUR1zUwauo#Uw*%f+pf#MvK{_e|20|%YudB{dK|8PZ2W~ArXtqd4G@6MAD9^w%Ylc;eg`|L% zaAG2f2+~ACw%Os}qP<)LRtzfS5>lxACe=e{gDBAiO7x zONXi&Bb>t1vUANF7CU`wrqy5t3bqSJxjLdw&c`3x4oVY@VO(7Fd5c|`Hp^NH-0@w) za=waY@|6so^VEl%)HxY3v zDw>8EwJuzHnR<_YU{CN)aR*kVNl~FGpX7P^lshFeq(QEpv*tjBxW2)qncHTPg?t;zo61t|ol&@~6$ax+M@4mkslgFZ(8OmkAP*|IiNlFt1 zgC$9Zr!AZdlCuzrXp+JLAt#6&!+Mgyvc2v`?o!%ly0U?0s_Ge!9d7#PcBk=fWd<~4 zEb$1OZ-y4VT|OnsWyt8)8nkhZFR9tKL(dO{%bs&YAxsd(5aC7To&LzG9M95fwNqqO zisG?$rqbg^LW#smiO#t}(zaal`Yv}GR;b4rq5{`d^4E3vW4EIx)!D36IU*oexsby) zLfNVhwmT>8xH^ck!EBSnaY#WdzH~E|88h#F z;*?*l?Xf)WN+_1TNChdrP~xGC02zqVs475l=^RHpN}dkN67plc^au)MhXa`Nbm^`S z=Rzw##~v_)%}M~IC8-b*8Bt;=Br&ukF|uRS4O>drD!c4Gg&ns;21F> z;-cQcHh9#WgsBn&%&YQ!zk-7f^v7dx) z)B_>uMxi!X$kmUfV=%&n?)iz9@jjgQx7il{@Gw-G&TOFxgfDCs%OebnbzCearmVPl z8UGe1tWXuA$~EWPF8KY*)FzbQM<29-*)*PFtVG`wiBuX(7YT!8F{9-f(oGL+v&+s( zYtV=2tt=sxun;9eU|>mJt;X6WPrx7|yyu6Wpi_1=2Ld%DfiPQDRX~~J86a7Ai|cn} zYq^7ItL#kXBwgaUJO%JpfsiX8Qou4;fFWE|F&kjFH-KfU4;=>9Pr?hC8Av1no0m|SAt8e~S#)Atcisp{I|W#yRj!L!!VUv)48GTe z6#fs_D{*C)Dtp!jBG#-8F}t_|2NW8T3Wa;8l7JRTEI|TFW~|g26eW7^4;^_&{alPl z+7R&dO`F+5G?)`<&zW-ZmAw{{gwf7!0CwV2B|g8>I*~jJG`QZML~=^TIdL zDp&A5xvh4n%lSjJoD3l$Vfvnf`#PQWd-;{t{*7n^5g0}gO|68Ra!IzvH1Mob#~FSl zZQ5yQqX8ez`ASU1vh@-)oge;y2UGg~%vF)8521T@qxba8PlyysX|b?ADiIE;2`;7F zU2$8*$UAPPbuJ|aG{K-}g0W)?SKnbIxD3egnUN2&6<7Z-T^M!uJa6{rIlwXKATkpT#bCTX=bglX1jNx=udB(qbxLRwgyT zaExHGq~`|OwcgpNJ#rf>AXbGcl2uLxGS4X>z)K3gdwj3!ue)1N-cFmGkk?t1^DLQz z?g6?a_fla5jG&2G80N$ZJ;G7VG~Lc~=kZ??BfQyQ!&}2gq-y{zu6RPmJyWt^XVPU!emqbAYx25ceu~MV`=CgUnGdaR#XW zYGzd8melq9^~_Dt>(f1;_ycAMP_CC8$L!P>*rDb@VF^=vU-hlALLqitBp8rFbd2!5 z+;8e#xZKG!(uTU|c!=X7QJ(j7wVq|ap8blQ@8lSI56}V3e6Xe^r}5nrU`Wp<(DO^X z9KL-P3P(u_OZ{~K7VDuKTWrTG_N*?~bwD^mLd^2&03qY;5pFD(vuyZ#=@+FlpeClptCMar0^341^hTL}P(BCQN{wV{6zDx84z0K82_(Fy z8dU<9tVFC2`L?gSJd}&-Y`|tXd^03jxv4_*aHqR|Uv6S);1H+*(5(KCFzUfq*1C0^ z3habhNRv4}YQ(aY4v$6FO)&7;M^8I-^lBZ@;KNlxG3Ya-wEv|{Z_{VM5&?=81oVY7 zFWzg@Gf3&xr>ZPuvH>+&AJyGB2CIqwCr>=>jC7sxhzUVD2wZPVdn>Pgs!ZN!d4vRYTGVr-lUf5LLJe|P}U_>}jH8NyWddlAFA-jiFD10=y z767hQmvdQ>kyM6_BZ^jeX9ET7MZ5e_xi7(CaxknZMo{st*Z#BR$>=l}LbdRftWvxq z<3adz{ku#*VD;}zW*UJfS&xU51!*eI6~Q5;v|avdkb`vF_|K#(haH|*W%y?x~|_C-b& zN0y=$qY4pEFz-51{(NI}4yYqxy!H!R58D&u!}8}l5?TYGYU(Mn))OoH_m|22NlJr6 zUN1|XwgX1zKg;BuDP(YbQm2t`FC2frOum>>ff*#Jpy4yLw+)p0)|I&kYsA2)YC-cs z!4B?n>FS)^N-T3Ja&A)Vm#?`eq`6@dZ~y!C&35&tvRNaRkLvN9FUf9uU)NJk^>cIW zu)#=7s@2`BfVOVl^~@VCeSUsFRR_VCS^#~)`~9F*e1Fr*9J{i@9i{dcW4(d{rPtybPiv zTW+qZFIJ4WRUIh~FWu;a4V?kj(|I$L&jd~1CDFa?t>52ak>`VBOcubJOgS&KeRNlM zFLlTVz(J-;6zZxa*_Yq1f3r)z1cs<8Ep}72lDyfA_aB&Nk#opA4u_aRV`?OUFXb@2 zD=m|VhwjJmOBu=6)3ci7|=%6U4eWyU0w>{t(NuD9DI zFI2l&q$CYqP55&IcDm&Gfiu*|$;rr=n^JDx2}>UuSm~12={-z|Y5c7|H~p+_z$IB6cKL#AXW># z4chs+OYSIj(?E=Kl#uXWNl*4Wm8*zG!Zulknod_PjkQS zuIi?#n(JAz`Z~^sjq;RB-cdahe;p-=gdZTHZYv^&2HR|ng3)vgwYCr?ElNs zo;xf{$;yT{hD8!h2qK9%g7T8m^tOM1zfB=|c|!+Q{0LM-5FyK6VwB@pK6%cmqr0Jl z0iwY0EG5Z+VZ1P>zGtjDa!4C!Sjw=XM6d!Q$N(Y2$DF$6ScOc)?`c>{WjBN57#9`& z_ZN;oWYvGB0jn{hfOS@pM-;_*^>@tsz#0Cjh9eYLOww#2!FVip@I`la);8{=#8QzL zDhfV;h>qtiGH#%wwT}`hQdB9{jIb!Ey zG(lGBfccW=2io?k^<4oOgTpRSNdlIzimhUGTTKy!Ys+0(Mf>;lO2TrY~4w0i^yLH3un||qqPgtzjRxIE) zqOrvQkc8?l34rHfoq)BHK2s7_#c#V#BC(pljQ)n}b-ul1JtPm&``N5a8##gVWwO0s zrwd)f>|*0`uqGlIKCgp!?I`@!%tjQ2pcn&`Pkid=D_O*~Ogko$brC?-dK`H0ZM(&} z>P;ERsP}4p%SI}i%bvhGKAR8GoL@WGV}H1kJIH6H@UWB`@qrv&shaw0EBQbt z>JdS!(U`6H+1*vKyJ{y0PoM{guj)0GM(igAT~HK02!h1d_3?Z&)m*x5%=fECYODdT zZo0jtO0I!7DGW~tEdOBUYhM~W`R-{TD8y(%pd}ztLcB4m8>GgFn${9;n()=8rm8gl zh^k_%f@**g2uVr>ly5dRCTN|}?;3x@mw+U(k5jEueIirsC=j;EXZIV^em1oM<@O2t z5p(xdp~grc$j7kW{8RDQK&_1C8iFlsp317xsPo0@=b!!DPO375R#-`mvk}7ea3Bt5DpB$&lLLRYx5P|o z1!^Iwam|qQi5OkGY~pNb2u%=};#kprShTg|{@#-Pz$70c6Ss~FCBHm2?7d|5&Dmo= z(Do?Z=uVETyoa{(tWqrn$~E{T?Hgubjs0>tL+PMUaa2I6X!RwC>;GVl?O1YI>1C8L zNrq6;3>T4TN~-3)XQ+;|P8|!>xwIBd7=cjIA4JxH`+;@r4s{)W!#8i5TpZqzbCdX- zUSmgH?of}@azI0RsWF6taoKwT9D06_{Yu@buH;AEb5s5ByKi>#QOdUP_z$Pu4eEB3 zPZw(oiCm3$#dIIRR0DDEse8C=_R(A1xB5Zno1^NGg+WuQq}=!zd$!wt<+L}b9;dX} zEe(3|#zs$AU;R(#+ogdnRKrY5J?W!wxw9IxwcQNV zO9Z^Wf*=DC08(+s3?LgkCMrbA=!pM-d+ea`esgA$;OAU91U6_YgKeM#`%fggxZ37n^-!x(YosET)F_RbY z8Y-T{sLg1#K3dadyb_WxfP0YzpCRP8(5fQKiYoccFpEfwR60n9b;Ar9ZseeSMV;m> z(pUD;!I&n6Hx9eB4_m^w_Mp~ECYHlM_l}k3Kf8hds zc6KbkXtRk0d=E`b%o1Qyitt_m-VNG`FZg{_w5|}2RhJ@O;)~U7o2aP^A({qf+^`jl zughJ3$78qMd(BO^HT`^o&IF-O>wGYlXqJ=!uLGS5V6Em$-`CF3&D?XzkkAY>CtK{e@$g`f1sN}1`ebIk|DNlm@56z$Q zUz2VOG%D|a#|zRo12H}p8u`;mqC)whl2S6Ui4}gk(djGi_r7N*G24vAe_2lj1S6@9 zg7=sA&8F3tK7GuB0NWuhrHZB)ECdB}6ddhrRLjd~(TTyCkK0>EoI$GrO$(_07>ajO z_R$uX&?F!$c;}2Jnp`2sY9Kw?4ZMjVuW|>p?-f(i( zA4)HvWderrQ3!e8&icRQoSpkJeTiC6I(5&_T*5LW9~Nlj!!|g*!=bLr;F**aLy=Tp_S3`Gw^^k2WKK|dO-u+h$HxSv z1a$dxCn~XIpcz)|;W7S{Zwac>8chJ={{gin?wrcOpJbWw_jT_@hNI*H4==ALceU|b|<+R zTu(Ly!V{Xcpf410(Q-_+1SG1DCT<@~5VwsZJnzHRlPtd8MXzUS2rvqZX)M+{a;WSG zYWw(|wx_6vJ`TbGGa1xE32((WJ@>KQ_91#E6a`VX-0OY#lFxr^dDo@S(DOlZ%9p=g z6)&Q3l);%=J6H?Eyml|jm!@zN{(~WH>fPcj*$}+|B3{IQg70FSx5#O+kLib{XsW3q zl5X_&#iAw7TpVQ1kwt@+3%U!e?!eBz;!tO>^U0#7qzj6g@uc~^%N*(wb}gt0^G0>h zJ(>=zW9P@V#jA~*&6v@E%rLqdN#s+$oHY|{j8A?yY?8E5jcQ=DrwnXscY3{pUk$1x zZCIroX!Yt|_Uy;@8qGwP=_1Y5pq$0&qnztWTpS3?dDYcP-Tv*VGA>^6jJC8XT{MzI} zk}@L<8I01Nk8s<|r)}!m%qf7PIgyQI1&=!K#W$?vV6oYS<;+!2gR8E&Ei#$j23RE^ zF9Y&BAo8lKNxa+hhArLh&vY{(6H7WlK=^Q8U;m>+ zosr!`!J$0NaR+7!8Ih4t;Ub`1wb-vwIJWtW4K`}wyhpBgAsY4wswvkk^ zg(M5jl-H{dUva2wE2h(eEX$%I`O-3NTJna4J)^hPoMLkItv|ox;mkF{gXs6*np<6m z$USe`9UH3M%~VB1vm)x|Dz>%$Wp6vwW6c9}lp(_rn)2P1^LAri`JaZ^W8#!&&aHb# znED9%*3tN(_*lJ~if|#dqSzR2M9pkQNrZxl@sHne$ItKoCHU#*)LHU(;8$Q`^)xVX z5&If>0o?bs&~5k^uAUCkx*!GUATd1q5#$>~)z5-=fHGRVM%@JR+aSpKJ^l&n>Rc*! z8Ajb#GJGh8SbenVIimH>|Gz&vg3x~DpjJ}MVHIl7mkeR3Z;nO(3Ys*eZV47+UyZ2} z6AV5Gf{ZR=*?ka97FkB1B<@G*_p`47?Lqk|5S<08UIs&8xFIkC4AH`a(=Zc#5f*&@ zP?w(Fc@R#$8Z{n`9WyIi=myxJ-NJGT_yB%W;0Q*2OyGW0*-To4jp#u>NPm-$!3e4^ z`tq{A@#a$dX{OukmW_a{>YC(xPwCoq$sOAkbB7iN%(p|3zR!c+Y@hb5OP?E>8Lkpg zwo>FX-l-luVUN8Eg%3s#21n$Ta7YQJ;~GO}%~;LX$Bwz%xinj>whr25^GIKj-W?uq zju*$%Z-L1-Pk!*fTCehYy!dsu$0y=*!wvaRwlNp=Vea)zFZbwT{J1`3DZ*#giJAFXOR$V(hQ+dq@@1d&micQBG@4fV3C=3V&S$@3` z_`p$no_lkTQ^(G1uT~e<^R*$vXJqPMVAHMGx9ohiMpl|CcoN~i6a!Jh^JVDytb32s z*1qgXl^CHCKvfBNP09yGx%laq_u?`wD7P!$AL@ty0+T9BbRNlJ80Sl4AG+<{uip|% z^HG?+>!8o8pyOqCu@)3p2fM<^5y2F*~|mqdE?XG``v^~|jt2o>sbiJIngoZ+kTf?RMe+KBzU_o-dZ zN=9BZyu- zC(7R+say~WMuWN$3Txi?1E+0z0&mXBeP-hZ0G9yqdS4X&3U|8tD;I~Eh9;7%FY{v? zc%#Rju1XYquX1z1I0<^N`131}coqD-ZWXw86!}M(xf+J^7SlOd-d_WiE6jXVOKqXD zvCflFd*3Y6JF2>M*z#=}G~S1s%DAFi`>8U$zv`3;vn2=$6~4^3-OJ1Lw(5l@H|!=w zXuQt%^1ZtAi~6gN$ui4n62}HS#?mvbJX0I0=gUMkL=dSk@NVtZpO8@>WL#NIZgPTGG|RPq@1F9I7R$##Tvg&RMUDC5{@!uBDjrlfgD3-xm_+$7 zb`QU^aRIOd-AnpDz-j?`Jk?r`ru*GWcNo+4?J(PvkL2nzVNZbG`}bAzoLSf&ni{^g zMhRV0t$JF{>8Cb4_q6*M-wUeqiCj$~S+tL|jV5+s?QfsN^a9c^h2<(qtziJ8S@@y~ z6By|wmYua@-P2ArGa?;84V#J*4Em74KJ5RE+sy7r8wk|Y8Afe=z_V<>eyaTak;plq z(iEp~e(aXhXOBJWEXIq`xggaPRig!-Wmv_TB;JmsJ89Q}FWUvtHW-blnkXfcf`}Ck zgJo%^+V`})>3q4qp6E&-q|-7NVgbd6cwdaoN98{4jLrZ^4NkC0_YZHr1+neW3}%ZVleHfHB*gR1yogpm7tJcyb0oG0L|RH(w7J5U^z87Q z58b&q9$OBpRMrfLq!47?JJLz=;nZOv9K`NXN>QX%M0`$zi#{k%)v4GVz$W7i6N|9E zq5iW>Z^LXuh*ueMtXlVm^7`Cz7d9kM!kej^*_a-T@fr0&@1^DR+`;ubEO-;;a(qM$ zL0GYsH;p8~tzV=oftoF^Ub*nbzcBNvM~T@9nJ}z0ksLu#Sf>F9>r+HP0ECbuJPYrK zv(L9Xy_=cn0dz~6qFNKcTZmb0SDtZt*OBOgBY3VRLIEj7ktNCdgu^N?^Q@#*B#Mq`tuU@@g>vsn5HV)QOKiH-iNK>t|N)>E&wlsg%C!?a7&AK z$6WdIzLkHo&ED(5PLKvfG*!0s*$e(IWgDB}KA2ZoEvNWnK(^8LQzTpfWsX%PwhY;0 zb1T;J``y6J1<5o+i?XWl0!0V$X5{&R>N92}EC~C>{3G#Twklz!Dm_*+^!CHHr!(IV z%q&A9)eu;T0=z;(7PAam2#DUB_^N_s##xJ&fP9G}kyy;6ay%y~Dd+89w#TYl!EOtL zCnhzG0=C!U?o&&9EW9JRUs#JTItvs?6p-Y(e08q+!`g^7y$i)HFidml5X1WL`}+4k zY)wJ8cnSVuhYZ^eGiP7dL$Y&qCRJX&*vd4&)|T55a`+1asV|XYDAcx4MvZXlFYqL zE<@Pu)UwXl0Go@kLQ5fDbktHu!onT3%s)mS7+Dv|jHr!gJ&?@BPdU^x#&lrT4GRV9 zTce(V=Wwr6^ChDTi+<@?rXm&hs24svMO%iF4s$(};}MZnRF)PH=_QZpeQvFtwq}Vr z6XbbyL=Gv#eSoN!@c450!Zj~}Nuli2iQ&w*yp&7G=3$2~e*C_j9b`uMMG(EAC`Be0 zeCdbY+K)S!N5-jex0NL7`V1r#9x7L9BqRD>6pzod2iX-l0k45X=2}3wQ(*0-Um+-BR{WjQe4CeF6L?IVT`hvoN z!?9+NQB5%-0skAp;)Lyy09M0Ne%Q!DZultAgTF6ofs*!94b|WHQ8y4qkRzzNtEan0 zzplSn$1jQ0i{weD7Mp@bT`7>e^=r;v3|kCi&~~usU=G1}FrJN=37?6eeflHT$4j^^ zpeVA@0BPYEqk?xkwcGD@{rnkF1*mH)A?Zu%G${#1j($7Qw6~KKXOlit(#cdZo^htimuTCVI)LJDP2L5_uQAHWeRt zT{<$>7J6;%ZDM6LOU(`lO%)KV1@iC8 zCbr5v*t^g+?yfYuAkAS}mKA)k;RAoc)E1N<2(5sm5h8D+Ak%0ll}$QBHjxCtH9`ZQ zEX@BMd+LprpxnO0sq>h53Q$It27w&qZOG$$F|`K8FNO{QkmU);7f6D^QWTj0Fwq2w z|IgQ#fM-#i|IT}6pZWHE-}2@AzU(Voh{z@?MNNg`($*3nR$2rvf(w7!e?*oT5h5Z) zM2LtG5g|o{h!H3vAW}#zLPUg!2>DYAky4D5!ku$w!i@Lc=RS`-!n|{qIo~<&dDq{| zCAAumIBKJLyV_Ta_bQ@E0qtzo0Q`4s38`1P!Fxnesyr03n*n+SA~gu|h}wRq_cG$- zfQdEv4L*zRQz|EF_Z~!|2m7>e32v{fN6+oV?UkQniElGvU1sI<#Cgt}Yob^|ou!jp zkvr8T>E0ek~Z$XK)Bf+-+C0VTRdKe)!->;{9fgvwfN<=7#2Ps1k z>Q=SqI)5!q#S~RL+M9ewHq!elb(4QFlKN&?v7fP`)XM$pxV!zw5mT6A>AY-%^|`KX z2`++c!dnO@;a5jr1Vh}>U%qX7irg`QWk?vBOY^to7>XVo-Jy29FR&Y;6oy^ZYNHbL zlkN}Ji@0=@1`ITO(o?GD-z-(V)Bd-As=U=P3sptz#rK3AMS5NoE|;eWXWjIWTTAZI zMUbt}FH`}4qz>yc7S$iF~P1O}lJeDBlzApXZMB(+^8~_czS=D(Th>w!2w3 z<75>5MG+clhjQ<`Tq7SFG?L25{i9XEs^GY+O3K8UEQ|@N1{8)<_Tq5=VWp22-{vS7 zX<%#{>)%=b6s`?*)xI8uQye2ZQjzjoX_jN7VXw^~E1u{ii8)IgOF&9;ln{$beALdc zK^qOS=42sUxbsw}S{2Q)0C~&vUA{6+e<5Gc`DG``cIk4Qr*jK@9-493%r=wc4)s%g zY$7o_?SF&p)h6d2h#+uT5F~;$P7~yAHQ)s9dP6-C&Si9=&zdOmIt=#Rj(sZil=BjZ zg-Jmw&`LXzdDJfc23u`Rn_Neb{l09k-Av!2-RUjg@%SXIcAW+)E>V;{fv8d~rHr_A zJ5T?aM1dT3&8D;aCq2nN8XgO=hBUwREl%l@aL-i<7iH6mJ$HPf&gYzKHj*_+pl*o zK)feq6WrNWy?x!=Ds`K?9kGsF8|Tb1_$=Gs{Z>u7a<9h#9gGRbw$i*UEK6<^qghv2 zi9}I-OMbmw?sJHD`28u zXg;tMmAccj4tW%5*V~KFt0u`jcS_^dyHP$<>9ANr z59(XJbIW&X^ZJdj@>GhI6~TemxSU@ua$$_xY|uKcBCEf4{en9&KFriaNp;Upu%>lFK8D21&4^ zL0z<6zS*?9FlKQTgbkavQ<>dNYUU=f>Yv95tMp1zWIPEY^hccf42TqZ|1q%GvSVgz z%22v-Aqn@I1xvu^i^ja}SX^(lQpB{&3eDjQyR80@A*=GJ4R?8%nFg6CpmYrBU9K!3 zUT}6U$k`SVmlL??Gknf{^D*$HE!s0Wi3m z7A|Vgz`Cy4w}7jhXAt9+L^lWKtdPMN)$>=CKQ=lRA>>nZ26xnO57r%5soNc`2nsU@ z6=|Mv6?b`sx`z)t6lE+wVRz@n4W99iFFJATv~e8* zNB6$JnOJ2k&F_{X# z6%OlSTF)}IZHKEBF+L}vy)H0_p)acE>6&W=xM;@ZWQ>Jao8C~{&UbG@CYrIy3~dBy zUZ9?~&F(G;@ti9tV5Gr&dzs%y3R}f>aXbxR8sY38PYeu26XuwCj6scQCtr<&WR z#xfyaG;Oe>c3)JujYDECxesUsJzm_o>EcwwKq>zsn<3caY9F6aqhE8>iYo1Hs3#Aj@aK?aS)pbDqpktm|<%43%lS^Nm zd!wG9A6`}Z^@xJUE%Am*n~gWVVHBpdT(0`C{oTLGfh2t>uncr=KK;J}S<_c(qHrNF_VHc`JLzDGTY%Ezozd@{qtM2a;5XW_t= zA2hi|UXGfyIyx@mzdre)=Jeexwpq)o$~*U@9jmIl_lg&W`e#f0}f65s+F4i?Sj;4&xv`XnP?!Umk{V)-AnJ3>Kzex zqB!h{7wPRAZ+!a3A>xATkT2L>5trE$^O$pP$GnaxjWFSPtc^P!s$+W7(pO`CnRsZ!HPh_RyMS<=07d*J3Xmq1K2 zu z$%y8k{^9MqIi!ch))VGbyl-VXS$2!=^=*2aEKo{v?Y17VDS|y9D@UR15TXmMT2VW! zG`H*`AFRB$*?QgX@DI&aFvzF@X(y_KyDUHec=?Z@F!mqCh|-P9sBk$=d64wGGr}J7Nj;%XNDCW_fhnyq2E1 z+738pTV%q`uvI%ZP4-i^ zRI+lQC^ED^I7Brti+G~@j*$<->3sHU){G_JKG+;%Ztj+S-;yqrjeOd^&heORAT@nQ zNKwgh&3?vY9Yhc2DqW?0hw3M->&!tV@(rudYgE}UxXk;HcT0R2n!PsAIm ze}=L3@(eN$Ej3w&m592m)3pD}7BvG87NAm!Dleg^GDGCVd;i))(&Wy-1;#`nkC{T2 zFhv!FfHLV;@!GXbua3m8U5CZW4g}G~GE#`O^c`R^tKzc_Yh^8KaBpE;%dVB-a{Kda zPCr8;=FYv^Ty~+$3^OzzU`TI{C=p`zXyo(gbL16Rw~ysqdMr!(I<50|bQLA-kwI}s z)PRjy_bQ&ELS9T?XHae-1$hOAqVD@Tap%ex?4jEjO14mx#Y0hvB8rNewD1bDKi*%x zOHF^J>kt>4XlJ7n9J;r&=YTfFMy7{B#d!z{v}(@82U7QzHpM#T5{fZwCQ5ULGRB?% zcxew#=rpfl4ltFUp~!^7874#E+TPY?%taKv0l!dc%@2oiv;v|VHyt1ycQA`t+3%B0 z0k6qWp|2Zvtn8|5%y|@`ktfU`Ls)cE?c%j3kxD;|VifOE6iI^|);NpM(+bxSmN9R` z8kmP(K+Uig>d^vJL9fQqGkKU(Hnwj%HwAln_6e()nwhNtRY0o05PPIJG4L<&9+*=V z=ruG{IhA-7|MlWlHEmL8K<@lPk0-CdZ4hcCPw*ySfs>3Obb?3ZyfB1G;NhqeiY551^1Um>u+llDg+}-x7_y zUc62xqgi>`u~fd!hIYP&$%+8AM4Zd0HM7sHSaRe@fXqjni;`|%Cd=bZ>-%bFn>O7w z;u#c61)TA0ugj3(`WpV>6sEC8Y-Co!JP67D+wy*+f9}a$7oW=_{79TnXDYIM*#i<@ zT@!D870*c7w)Ij2!wMF`87Rqic_o4411^K}?faGL=ASFo(GGJUVz>AWfiWGgYoEPD zI)y_1RDRf(WpIq{T&a=wNo!Ewuq)9g;*9H?zV*4Ydq}ozyL6C|%sz)RWX2KXqV5{( zT8(>9HtuO@Hhs6#CEKi8TKECHVU)IY@?xg{pp4fajydC5!&JATS@r7S&7!=rUtW$Z zW}AiMb2DB~AC<3IETr6sG6O|SZI`OPeHTZ%=1b9YOqa}NiSe3m;OGB+&nqzGRk-u7 zQ1A`NMK8cR$jBU(jo%IJjH%ek$we+!U)}E4Ue~0xb!Y=qVl$^p?Ur1p`Z0dmEy6LXh#A+!`oDd;M3J{z;E7ltP>74P2$jB%XFLwm2@zATOHTeRE! z3UiLN71%gyp_SE5T07_O)x@&p>>AGIEsj}zMN$2X)@@y=&0`JwIqQ&3HoHkSXm%Y9 zq`h*^TG->Ps;I2`;^G^}!$dGY2?-b27RKS>=s+am&nwH)ynz@)tNYKr z-`~!4va#ZzBU%(P#Kp94?H%I^*T9A%*@dkKDHw#v@n17MZx9=6<8 zN?Ur(bXP+XGMCbY0EXUi$NLisz_W3N%R6ot(CzE47XRoGY2pc$`+ojx4BF_t2 zk|mLCyZ*UH+ci6dW1LBL*kqI4uq#@=@1j2^Lz4TzEp2gVzqc>dG- zD_vD?87_Y$&lY$Y;GN3m3NysQK~jc0-s~M`iFA%LrxUUz6E|G?&8JB}UWr>Qbur@w zT~d9gR}Nky9c24jUBe4Za+*gP{b=o65M7xzymiu&p5Ve8`c|3eyIrgO!?DNY)aO&jd|FJdZ|i|KWcaYrh%UC{yh z$gPVoIVM?GF{SwwB^6Ut=`Sg2p!)MES`W@B-AO!#hnac^bC&)Q9!u?>UYyV${`}z# zTz#yY*#+|vYY<4kz0ywBw3b~2Aqr)}2xpUedcoB%7U*wiM^=PSyAd8iE0 zzt%(gYn$r2NSB-VJ>WoW!Va7P-JxTRMn1srf|RnB*<>wm0;#OVWV=Kk2Zhlynz(~SDUyCAQfRK)`3vaOR5DJ>csba zq>gf4JO~*E0%=+sg?v@>RgHW?+75ih7)cm7n%7N)J(n?Axgt+VwMwVcl}Fpoyguhj z085KqQa!M#2Q5M$FAcUKsxTVBN_O`ZrP<6sO7T(Eu{(b|x#san)v<}#nLYJ!{Qt?- zIHL05nhBGtrL0j?r~EcHYUfhJTi6aWGQo3 z^@QowPfVIR`T)F`!G7+Y>#7K$a-`d#L8PnYEr=*r882hW(D#_MBW#c z1byo?T)j@HhfxDKC^X1<^XQQN-cs7)5HR}QG)Mb$Y2?!d*!Hz*$IIwOurPAcOq&co z$J)!UlgbDe==G3AQTeIftAVIMtyf>e9V<+75uz#-CODvo(rpX-YJE6#;R3w?s!B3q zEol15&LeH_`Nx+@u~lpv4CC0_6h^}q(;yCIQL(bNxp9PCLpUvhRbbT^y!Ckfor>tj zT!9Mo37-17RewG8EIE$nnH4B0nhN8Rxj^6QOSj`T7~q@Tgs5-|P^{O}g_~d8ipk1W zKf?BaDh*!k?pUVu7?o^S*bR!%sLU#w!{E|GdIWdv=NN66hQnT|k+6T1IExNs_MK#Wf?a#SpS;8BJ<6)c4!mcpbqLD)BGjjk!4cT7hP2%z)KP9@^Jq@$l_~{ zD}cXO5$?t<+wt7S3$22}hq+nub_fsFLMTr8@K1L}TBH4RyVf?XR9i2WFTl-CKYxqt z5$*BKPXGMUyR{z(I)k(g4#EoCBDo(@@jB#7*5q>xHp7gxs-KV z_2biHw@sNC(>dC(sgFK7W6GrIPsfJUOqo8dMhg7&r4f@9_BDEX_4G+or%0AzHIpaL zm|Q(AM#}QeJRnw`tec}nQzqA-EQc$Vv^%r^4?nhNm$HE(R&zLN$m!VY!la>f$Zv9` z0%oTn_3no_COteGDU!Ejj{6K%B!38E(qnB%@Wf=^9X07ou-B{n`sSy)FsNf9&WNlQ zV6XZKo41qb&DGEfR7?>;qPdjLje3d*gbFN2LL^`0!+8eyu^m~Mwi$K;Q<(sIVBBDg zJd}fJP3Ss6X&F#OeJNeXTqxtf%r>+Dd1J1K4;+lm-6u!av)2~mw(IFS6!yh(BVH{C zT`e|KPR69qqp-`Dj5xJI6NGk>q*>Q7moc!eNn$y{Yco4_y?o`Hvk{3GW!jWe<1(|n zG4g%y!f_-sox!EG9J1AKw-^v^ULJ@0-pL$>j9qX@v@KQUare_JC;YHl>Dws@-P{@Y zZ|>Kch2!GKzagkaY#k~TrQ!m~m_>hMjXIsx>?W}EPx0n{*@hUljVsA?HgMaK1-O_Q zu~GduTez4Iw{aIBMxnwe1qL9_jZ4Pi8kPIG>nOo8kvLALpwFP2wOu~K`bI*s_Hfr} z<^_;n0Qw&5D?h14wsggFACe%rM*cEDem;fr@(kkP*@d$;T!Pg|xnd)JO3PO#Yjx;F zmDas4*`cp~I6i}9j7z&vU%`5R8E?6-0u4-PLiEa`J5LgN zgM1kE<>b5ju%^3o8N2Siw-!E+Z~)`j>M7G}rah(zWvU0|JE`j5AAELIjmmL7rRdr= z7r;+47ZZ{*e+?j?sNA)FhRq4k6sNfccr}}1g0cYK^0|mI@f70|07(%VtPY@qS^)^P z2I88pagK}J3X@%Z%N)*r5)9{=0?$^?9`H`3Hy<4QEathEt8;}+2eftjv_>3pn;MT->4 zXDrX;|3aYi45fmXO~6cd4Lz#AKqm(DqQH^Ox{yRut){mj@G}&h9RnuGQ7DkZ81~)j zugP1T^eM1q@~!5ynFH1-AVy|%@8HS}&k>ognR$#WtPt6P0g^t2l^-a?EXlf#85E(B z%>;}iM_{um&~NdV3gkGi+%>yvhRVP8fUC6JDf%s}=p7Q!#lLy)Jx4^xE`@svgNO3` ztwRJogmGnyLQP7J-E2K$D=VF3$wPheeqHp7=ssV1Tb^ zQ0KgwI|uoqeRP538l$c)cA}hIsE&J#8^dQjjF9bS4X7E&-4U)2~;w@oD*IpYxZQ^jp8~BHPKzY1~GDIS^F8Y`w@jU!_5GsAZ57ca5Du}>d zrKv}fPV>j09-+k$&;ogvr~_huj}!=qyx$l#)A>mg>9b9^49F7!aEA@5{K92QTkPQw z8^BDnp&)CyHN=6*g4lp=Wm>!A(t4Rl|H37(6(>Yw>C&qtiOvern@oNk9a1rqs`RL+-Y1feX=>nqs0>=)Q@ zP$&ONmo?}A`{nw8_EeP$>2dYT-`?2pA;xX8E|UkR1du`;pBQ45aw_O;8bFS6L5!O> zzwz%gX3hmEK5WMHnX#cY)iV@52^PsC-s@2XaK=%nh&kN=<2 zq2#?ONmfmrJZZvBF>>ZRV%4`du4$DIscoPZ{Q$EO302v8w!!#VYfkee zA0Dm^p5ij)BA+fXNPlZTQCgHqS(hP$a#Iu~hHw!P3j92UBwCrXRZ%-}po3Xu$!^Tb z&hEWV4&^NLJ0>%TrPH@?hVqQNRLyraY6Fxh21pkfaE5oZD4*w%#0GjUf_adWtpSbH zX_H(|kK+apW!YPY7`j~Bdd7-b`hI!?#2!))+m5Yg$XayK0j|6+Pe-#Duxoh81W#-4 z<}-L3+b+|)p%76Pk)jfc!mN6dXe{lmeEy4fu?EYpV-_KJUsDUW{`m~KZ#F4HR6?14 z+&KM1|2E?+-|Nh9MPiBt86!6OzC9%287E${k0lhKsynDNroaqE!hY4r;l-usAT zH=N)u0mO0{6wNURAN#he)YIG^K*^A@f&7M0?7i=tAwTVD?m;F~srp3kyF@)(1) z<9(&uh-BR_jG#RUhKV`>Bu!o(X?N@1j=SAj8l{$=IhXZNCo>{(&tdlKz2wvY0A`@3*@SAe{6l#G`>($4*CflAcoo2i|Z>3pDk2$aXYUx%r*{&8{L+riz3^O_h^y|94 zvzLAymNTfL6sUe>hRxUXEuoi6vE%3hQW%*<;81{ND1l>;OHog3L4~>TG>q1(cD3v# zbHu(jbd^rhs4@?60}M9Af2`X04gQVIyXZA2p5y~uEtu}t!iAq({Qj53fwi7KhCBeQ zBD7`f3b!;3=?nwB`D%@T(8Kt?>c!0XV^0>j4KdxJA)cp zJz>)Ar+Vodm?oO<6K16TA=Y5V{$~05=dp`IKF)R0zfJzEa1IPNKtUaQv!|0N9BY{6 zC_pn2KQh`5TK@I2_9<7HHrlDE*~%YQq`2ZzmenAuF-L9xJ9#fx@||MlGg8t5jO1cL z#5JX4#JV-9P9!mWmwKmsmDz$E2wc{mD3Cq>?4>VayOiBqj+9*tdTd|!3GzwGvYlsF z(5OPWmV!12`?WYhHR>JO93TZM_<2#vP$8wBRyxMv%Lm z7kk@ptp$9Eo_?NQo4Qn{xOP?)V zp(}0X{nKW&qE27ynx;k?EhuIC`3yCmkixJBu+ns}y8y}sxCF*5ghsRNZVbgG2a z7K{iP4c%L{Q5Q%(G^7-MpXD{=UN`LS9ko$fOa~a`_S4|ez3T1Xsuu_6G_>9wXhp zMZClaBV3hyzPZ?%^d^EXx83f}`epbQf86bU37DlI{LHo$JVmbTt1plB}4<2aj_|vEAXI^Hu@pNSpF$1#< z%g}WBjrUZ>eq89}-FA1tZgz)EQg*(_;R(7N7Q0z4?4#EY@A^A=-zP~u!aAOI$QG;i zGq=}wZzG8b7ECGRM-5C^&7Pcu7KA#NP)U%&RX#H;=}HgJavH*spCfdo-@~pg;$jT6 zR;>c5cKo$d`=Ks}cJbh_A!N52c6Q^*&o*g4boc_#7biKPD2vs3)WJ8qpvu|xundiCievZ#L z6(z4+;=(d8b{E4qHT8)05Qhetfmae|M>g@nRp7lt{c(EQKRI)WCPw_o25xXtu-w{V z2=Z$9Zna~4g_Nm{uHg7kKtN^-!-sqvZL=_p*}<3!f-G<>FxIFDrl2}v$V9jW8L>o) ztcmV1dA>)n*HPp@99=wM7ChPaXPMu6J^|)YbDr5BOb@)x zU&eYNn{iwGHfJKL${2paDH`Y1*L|ZFGm5tItS`iIUajgfxw$%zlWF^vi!Zu`pARt2 zd3R6~KsNXOir1p&cqr|UP+31i-P-1_30=ALPQ*_0OnD(qnN5mPZdY_34N6Q@OB(g| zvn_srX9h)pz9noB^cv3e(yzw1@u;{zKv6$K$Zg9xLRapBb*as~lycD^Mp!mnX3{-= zO$*37QOQ!5`JCt6v@^$DME@alGnl3IrQSg{rPm95W|T!p|IDm^Ov_wCR}SUr%nBaz zLkcrjZcN#OD7P0VJ`I#frgVX$``O<9PUkc$A3u_1`xuMGH0@Z3>BUmCIk!bz0tL^c z^GhrRY}ik^T{*5hEk#zhn+m(!H)q(;{ifFAy4-yNRoEXg|79!G1pJuxGOEE<;pt z`)g-6s`LW|i+PX98gt7wLuIO#*9ko)Io1^&7H*?&Ve+zgx9I`ViE-}9H!mY^U|gTV zGkhjsk1&!wQWDM`q6f}*t|afIa50!&oFepDBdj!{OyK)e(2J3BwF)+J*K{o+H(d7r z<2`I8!EbT&xNF}Z{{Gwv0tMGuvVwO37jZJI0SKqA6%RLaykx7Yp7u!fquA~+MTLg8 z51m{+;rHWbOq&wBW72OQd9wOxi61?o`r(HsOqEJUKQd$b^qOgp=g01wG-cw{CzZbp zd2-66DZf?za&Psd$?D&RPo0WixqWi=_S{ZX&N^+?bxU^jVmWl ztVLC3sqZ}&QQ19-ACM*=QR9v-c;z@jw`r7GQH-KeVFYPI_}2&O%uYxxD9Uj8F_z8I zh2GjWmAYFxgAz0f#2GMzcr~_>dGl@ZTzb+w25%9JJ5>9hCN)oRo!mfMi{d6nVNBGS zRL6F;<5ThmL?z>Z;xS4`WZbt~o0Qy%q~dZ>EGjdYx9j$*)Oyo$l+Q~Q1p+_75Z1F# zr7ku%AlJyK;Jh=&>v0~fpEcqmVrj4}rrq~&_R274wKl@-w?4St~&PS z2hU zrqFB%>;Wk;sC-0eX(Uw|DNgkjA}A(C7@x^ybLa*DZrsuD-rfEbiIK=|N63?+!JTc` z=O-78CCDeKM#L1B({zCmtMt$nbwZ~zvycyjLNCJ?84yR_-$u_|29j^+h}c~<6DLim zo{atYk4>(5DnB-A%v}ubEhbQ97qqPseihG|c{_z#Y}o z#!sCwEjD&i&6Baas;A+=Bpe1%GffI;|GcYuO7(AR9#tO3M%PSxV$uXGmftb5l15LRp-Ae)lXg(5`taOW2j*bV2Qzhv9vbLt2|$Ri$kG|6{M337 zN_-q&tR<6?u<;!WzIew!J}r3~U^`G|p-5m$1&c`>E;IeiAnF?M(UTIPXF9!ZoeEo7h>K#+)Iw+Izyia3s6D=DA7it%&iP$t8Oiih47sn&1CWz zp_6H)CEg_A5^n0wCU&-C+xA}oj9E8JIKfTLp77Aqa-aU@+=9w7A0&N!QNSX2Y!zq= z0i9g(VvC>XXiPI2?zZF)^O*DWB#uKnp8e}FGS(&LDxC=MTv*w8hRf(E84FvPn9H=o z!gE$DXAu26z9RG_b~!b{*pg83=+bbJj!ve=KyF+?Mp4%0bN&LDUAY01GwnCn29JLB zre6_S`Ay;mH1%DB0RO`mO@}X$Skor49sk#7E-Qx^ zGe^rjqRlB;PocQj^1>!R?&YAk4U)2}BFp47*tO1X(#Yq;dX#Gwd^r~0Q0!;p2274i zwiVJA5CXYoIm^j0CO4;J{;hlmzoKmMozfpuJmtSy7*6+cv?Nu*%+!&iP=WvJ2c2f7;fL?t4Y!q(={2T<{&ywHj?lV3c2dy5o8B zvhs9`?HXV>fBbagi@i?|+B#67#&&Nk=zV(1z8P|P_36ADtqau?)0({)AzMCBR%4>v zyo*1+M?T^6)Lfdgcv#x%HTW#ge)|4qd`4XD=_9C5GEpk=7EjFW%`)*?nwA+$APYak zui?^!>E&P>T5gt$tPE?9YhFPdrg`)zennB}j-+>^Mi3oN&VN&=-ugFfnAw@*NJu7l zMNS6VYDU0^1>Ng=v>m@j%1T}W)Hgy=eWHdi-W`9{$jdTYXf9SRvQgvRyyKuoZq3vo zl*k8&=NVRF=@%OLYNicRv@jx@;cwGBU;4_4E&iEPInT-CZ@3OJTfEV^`U<*gX%&#ynD^yjneTl~lF#!b{hQ%S@s+LBit-+5_p%B6%6Lai>>u;f~6xifudiS zOpLW6M|PfFFiWG&5@Y$a(~Z#%E$MMB*axS&khN1>?K;9ffPjzaZI<|BblhWZTTpHcS6 zFSNM$_tb`SgU1n{JJBJeCpdNg#lp1;H7U7P1UCVnTPY!@85padrg$x7S|$k5$N%Xe z_&LEvh>k=UCLE>>5Wa6JeJH>VGkoJD5POd(70dY2q zqM=$1C_PKBeMhMC<8?IS^0BntYd|{L`05*E*h`5$ASCXv^U>RFdT7GDPnAiPNXc0_ zYZ&$c?=Ql6dDbEHJ@)s}gdI@8vowo%j!l{igOl&lcEFD(uH)*Y%})<=t8KG2G-WJI<=>awOG?ghXGN zkM}X@EPUzQRfKvXbqYadFrw18fFaIco=RPk?glAYZkOXFhG>wLC)A$Tr4Qhq%}UP} z{nHOUueLp&J_e3Nq1&ES;M1u$zSMS2rW^G!2?;wRL`r4W@1nIri6jhbYyB#+FSciv zA&);2UhCk>=kGFCE=#o*xcUu*JuAaE7tx> z`$z4YXTB&^?fvw54Sv`Dt$;Pmc{~cyTV^8n{Qq zRyr2gC;`x8R)eWTc4m@=jd*?j)eF>F4)9Jy?UGTX%02?^&E~*ql6^F# z9^n9qrs(;RfChCsx|H{jBmoz?1qW6UlMeBte6oWGe0yB=G}nhu%h^SD86YU<{r%e; zpaTDFf{_j}b-P_Kpb;PX&yVCA*16|mP2KlXnCIplJAmvfcRfOxj3Q&;l5bksWtzA( zwXdx6T!3;}N|g21M7|IZh_Wm!((TQ&WK9ehOIcbAa;pAT%$PaxXz6T&* zS=qc214CW-H2j(W@sV7mimG7>61KnO`ZC94OYSxReadw8RKJjOr7y~&CD0& zsvGs&zitD9*wo3CTKkHdQS=UX1DbFd9vvYLw~TW2HI1i+(hI=;klQEM!OsUrM+I9U z=L8IVEbDG-Us%DQ?6uej$vhH9W!QU&yshZ!Xo)4bQKC^A!KG4 z2^*`;3?J4xWy9*`7avtLZr>_)Kb_9`jrEt#pzMlP4UA>c&LA_;Wk@gH+t~59X2R0f zu$|D~JyIIJN{gLoyo5)?iX3|knUWc+Ii78Z72EgC#cfYv{bDvhA9+fh5-SER_H?ON zPYc<3x@o=I1AhV>nKG9(UFy_tzJ^nnoTab><<4;R@6USsm2p4KdWCWAJtvP4M6Kl_ zh6p3M9e+Lg$&Vz_r%CDtCK99RaMXzCcu^a6o3sW!WENt-wrB|NCN;kD^=2~hD{>v` z&kHG$Vk||1Sf)qz_B6MwC$F3^%|>~WlwU5>Rvxh`0~CpCm%71G_BOm5q>@+|QH#y_#?+VWXumuI}Ag zhj4}hx7oQFjdH8XZ0mmf&?WJoJL^#2ZJKGaeUJ9)8UJB4RI?)XEdR$Y^6;F$4Gq#B zcCXMLUhp@g3hiN66Mm?4x*)I!iLm13@-<9 zJUpWjy60?O_Y^KPu_@XKjNQhMpb=CT@(7+xIml`y}B) z);=`ZlG0(Zx~^yq7bUNNm>leovTn8O+o!2VBVSI=N9IBkV=FKl7-#1-jl4d46JnG7 zO+wZH*$|QRZ;iYveF+K?-8YX$2F#(x)nBiDYUXF~|MKMcuvR?ev8j(^_~8-NlcqnS z!MjWTJEl&ld0OFuqaVWor&Wreh?Qv^*ZTi6c82b{ZTPSu_ue^l=xsypjt#qG$h~83 zyEiuMp1Z1s-2H&$9DC=@_aCXAGI4Uvw5KI2wt?P0qvrAH1ZVzn$@{>JM<0(3ubDh) zLiO~T*qzGo!=}|#KdS7^Ny@+PtA2XsR_&lqm@>d_R_Fq4JeID6i6Myv^{^l>$-TDKG)f;{q97SUi_QKIo9e=)O z*+Cx1W4EG3=svUGiL2C*E67$amrj@>Xv@N?9UWHQH zi;WE!%Au)I^-Aq@*F!OlQUwfckowlHSc^UR!To_n^ss*S-B)n?eeVFz%e2ghf}E%x zRi?XcFTQ<%$P8<|%OR91i21Yf}NL|AP&n~|2D`; zxg!IAMSB>VVDs5-cK*YaXGrdm?;r~17DhsO1qR5I-1h-<#tC|a8ECCai4RgN#d z^@s6k$+yVA2H9gYSYrVbCrgYV3ydS3t;Hb{568Mc;2_F1e%Bz1ip43)6r`v;9UW$2 z1BbISH~ZT_#FhJO0l|`|0S%Mv%pVqv#aShdfj>g=K#D4IAWFh8?g1?r3R}UpF5<9! z*yH~k%o&fsI+7Mkwv!i}X$`mqN0MxO_YXM4ts{I13LLlFUPK0bzq9LlomUHjO&}EJ z34BpLtKV~H7puQQciVuo1tznKY$yM#fW<0g6OVsZ71otDVRFQs5jMDF+_x^zGkF}vD6#TjV+dcaS9KT!_ z`lFzT0-?gFD|>)XtKsg$3;Wsu91>tX6PjXku#Cs&_hqNG3I^o*JG9~ev5cMyEk^EJ zZuWcfKV(mw5ABCgam*Pm2s?BgZR5WuU`CDC(BH@JyxHjN)n_mW<@yL!bpUR0)i?}i z;poeUx_&{@H{w$geZ97LKc89ONGsnYpDwM-+l*|Bu_)f<57o zl@rgc|{Uw4-@a|A z>z6hIxYfevu?`@w;GXazC;4r` zf{>LnakRz9GCBgn!k1KEyF6bU>nn}gyd^QKzC1hXHEN?c(Z!oWPC+)PxjSZGRP+3g zi}%|F!DeGwyJ2$wQpQ(A(`8a4s2ED84iQhSU838hU#ZgSssF6R-r$VnZ8kk5Gkox= zsHyNiU+A#{Q}EFMOS?%}Bs&PtbU)s*ie$FgG+z--79*k$%-T)*^h)$L)BP3nc6jDq zhK6U*xLF4Y0mA^8H-L~V#@QT(2!)Pg+ldl%#8M9q-ji`EEKR32?fnerddMx#hoC$_ zp%T9#(C)?u&tTdG*EDfxiW7$QD%<$b-Dn}SHSTA`5gAUpP17`0w!fax&bV`}4;2cw zUl;I(1J(S@_>|;a?iowj1d6gLoT|V}Q5LMm-bM0*u#9_SFLpI!r?%$=l=c=tu6wO{ zUqHQWRsl+c0HQ$ylRMclLD6?yb%EKCFVHTTW&?H_S!J5j<3AORgkT+jgCQ)7*Ib6^j$i4EJDv1@wdvycBU~hxr^9)Ip~CrBssel@z6Mad5Fv8}L2Mum zHqE9G!+PY71L^>^iFH5+T!`^H4JMC6`(J{Yvp@l-FTW;19%KC@Kh*dsYxY1nh2QYyqDAi5srt0)}CbxARXVL@5=QdI6}2(c?MX6yGfT zQCgnk^GFQw9+h>47BKXaP84Pn08p6Y$`34#S$$N zPz^%Gl<0W5^7q*43mj z)@2Q3F3LT2&^1b?MPFsWRpjJpDQu=KI(YQLugT?eSli~&Fp z+^Z$KTX2o3rEi@i2dT+d50Fp}c~-W80i4~vjF^ef`Q`$ZU#Lu4;fiKAr9-05+qI0$ z?TYVV2;?#-m}Af|_wHOqia+-FsVtv6VouV(Gx+Z2&s{~#hVtkB>8#Jgab9B%>%8sD zFn+(Fw3YI03k;Y3p#>fPL+ooyLaXrRXKAb7kYT-c-!ftxJ`<`36iERUP8+4x&s6I2 z@O+?CKEz~u4beg;KV63PY<@vxq?BQ%>B`Ds^($9I9%dBwO84tcX(F!PuT|on$ggb0 z5z$%{mJE)jlj?X^BK5#zhO=~fm?44h=#gb4ig#yhF{0$6YB9_D2ZQkbY0v2!w=P0liXPgA() z;Jw=*`@eO`w{{*5)W9%l@Q^1~mT*Q(<2uLNw*vE~gtA|`C7?)zNi#*WR!XZuL>$hI z+b_TP3W11gQ+cA~P)#?#}RBGTrOcAXDnuhp7rHJ}x|5j1o|6 zad|XT%Ad4$*M#!HiXeHb#AfTPsb#N5y)2FzL8I6(PD@i#8P{%&+9MAwWs#>ypbb$U zjUQoZp5!}iUIF=vm}{bt&7_F!zfdM_BRF0O0v&?c>AVe#KKvc2I$+)oIL3||xBt+h zqw@)J*aFM&K`crQucZBTR|AH!$9&p`FM{*e^tYw&x$#ibU z)U@P1;aP>a8s5sYPL{XR*|OPAKLH^On>6jwWgyXEi#JW|Zc6&w&k-jn;?q||ff`-|z60O8~*)xp_^jDVO zOCgIU^r#iyX1%H{fTs~4R*I;2Z#E~fn$=>mSK?c|YY_TYcN}*f(8k^7Efk7fM9ZQS|3$&jB!$jMR2ok#12-Nx^}R)3au-}nR|Pu5Q|@0)*E_70(TDPm(`e+Cux zGx$k*&f>NhuPvwuToFY&3>&4x*5|dZF9fGijsOKtEp1;-b6coU7l-;nB8JdUtb{Eu zXw>DQC%~udSFhRN+i8DEqwWq(6q7zqihGT9oLOlOx95mG0daHKNWgvF! z$b87Mcq$6*qF-cWm50&T`qB6|+&o8ewMG}fNM0C`$Izi14hEV4vTq8{F06~6d>@}1 zMKr%2m25846WUMma*Mhw*JDjUS5_i4KnsB&2ch=c&CBGO0m(O1VQC{`W2Q}dY;sL3 zJtW;5R5|lPpQ`8nb#mR$#{W%_b_mOEnH`^2ICi8XcVLJgku#u-kEVqFLm!zr_^D8C zp9=R_I%B_o#5x#07BUb0F@I3-4tozgbp;)O7MOnbl;SDuWNsD2`c6*Hg7Wgp4bX(@ z&^6eM8qxSCMlFW^O;EfW-QCJs>bcwnXriLOmrjiJbq^i(RQAYpJ9g>aaxC9P)lYs2@52Z5R`fR9d6E7%dWZfC`VajY{RVm+ z9fGf6FZ>Aq_2iJ>42kx!yb3cOy=^7@{9jNom0bvlpC_Fo>7>KwDdc@z$d*B#Ncr6r z5y{7xIE%+5xhRt*WGfURk}Jfe&)=d`>JxBLs%!iUi3eenLw@xVjxz+t$3 zo#$^P%6v4~&=t zrNb)Y`7Z(tNu)sz&4xZuW~Pwdzcdq@1jIt$EW>ZVQ}I2*7!x02|Atq1tsofGE6 z5g1yv85Jx?LwBLORinIzqv&mr?+rhY7YOoJ$&GmpelVLT3mvBnl1~xMnAw1QqR-4* zO^h6og6~4fbD(th*D{6HfRU7PqxnG-V@cS&5Hv=SRqhk)RTm8B)K^s1^&3nL^_J8W zOyIo5c2~lO_0EmBVsu}39IF*W))3ak7Le$$X!o%plP%yggs^hEDF+J*;h;U}=W@)6 zU{26Kt*NnbH%zXPa>%G5TBr^(8dgfM9wxV|0RNqHnyWQXCl7}pZ5J7b>5(^j|R-!RGi*u7@y~DO5 z+#d6)iiKh^$HTTDYo}_M9K0-+BL`8?>@>CDjZ_7#7>vAE$OAWPb_W?J?X^^?g3Z%N zY|UxoQa(yp>+k<1RsJPa{v}oZB~|`kNfl#Cs$gSoeZA+@zV*=hd*1jOeaZd3&teF% z0ny@ci7_mjiPLe1Ekp*0-n_>l2e8**a)2r~*J84Sq@cA|*q!Lr>`z#&!J$}@7ulI8 zMp;=aGD`|76B$~`a9Uoil4Acf)V%fcA4qQGv=VsLrEBesLpD~&4ge1ojYnQ0!4P>PG=M=5+#cp zBg~T1ZjB0I@H(QsaU13`IPh#L*BJ>92^tDQs^*^Su?aCRY4pe*7m4|-7Qdoeb(9}3 zG1}$-3j0*efy%On>Xrdl7uf)|i>icN0p*8L91b`;jCamp0lo(JdLBea*CW$yOVP=C5gf6NkDiN+DnFQn86YkXm?nVB;1b7tin?U z+~%qlb8Y#gXS^!a#*KIdZ24F|rS6+C1EQ7wZqD9ZF&*prI(WKx0@abOvGUT1OJU-x z5F3;`(KAvWKsOX$2f2{V#qJl1nUP#B-qRAYSuAY8SLkw)g;-DeF}$aEd*HX-izB(Y zrJ;%A12!M|9AHC~e*_T%Q5G63__TN0rm# zQ6=Qla(1reAK>VUjkN!!VoIGnDln#cYQxkKchhFY8Mc<0z4l-*ODGWv#5$^%w;xv@ z_BWv-(&*Ac$K6&ZmL(cP$dTicJhEuQbHpsd9u@3XHjgYbkPd4A9F#2MAzug!l@tpO zvqd7wzC?FAVks^zjR#6i0f-ws9#_D`2bH6Nwur%MC{dX~x04`PkR9C*B6N1y|AEj^`Kh`my-o~26Q5Err93TVtG^SmiI0FMMqW)1i{ zfdyqRX0KGtr6w|jTuvXB$j%Xi;5ShYEEX;l3{fOW4$kE@xp6=13=aM!a>{47bAE-Y z2pLUSlr%adIaP^D&g~%xaK0>AFez-1%W@mdR)R2tSC)K4xywXR_NIDuN^U8u)aG(H zSepw1u82zxmRw5QbP-OglkvK(M!UsoU~L8y#uKd5K!n)4xLlsM5H7PPNUMhtmg9=@ zd3dm9h5K~SV>88MgM)B+C>t3eJXnPC2{tS17wn)|7?=9TNCsKAAgK!y#ofj`%w;B{ z%mjNJY1tXOH!|M$EffxM^fw%X%DYU19JMi<>k-*Bb_a4D0(KVomO%a*=>MQ&7KHn? z6zv7?s9*~eIjfl4>;oOrTQIr`DjJC^@(Za5c&!6V0|ZhTim zAp{st{i~^LXjhg#vG_aP^YxnZR&YKP8B@uY_kVnAkxD4y{D)m<18#;3u{dQB0nrW` zC=*UQ1p?!|44p*n0PWRv$!B_8Ul|X5q?bx?_VccV zQHkStniNcaYoMq+B3aA=p1c8ZYxlCd_v>Y&ocWe(Z4fsJIM7^ss9CxSjMz-(kq-SoMDu|`x_}ahu?z5k8 zEhWV)Pe;Ivfbk>D%Thdscmsy9VrT9LMZfNOQ*SMgb6@g&5)~W~8Rrb7r^zkQN?0-T zEq-(9*yPhCttY&Gx3l-mEv)yhC-dHPT<=|_XKvLbU5Cp!)=6*o9tbG1EXs-^rTrG$ zc65&Cig!-P?hs{$Rs{_~)3U@c>Ym{k+-gs+R>#)P@tpD=3fLWzWV4GIsh+p*>}>C- zZ*$lP7_9&pWDMhN>dNp)Pp%-OLkxCr>1^++?^aN91dXCIU`XR-&)=lewe%wXJwZFJ zz33Cx0D*hb*Su}7cb56jg0Bkd8WFB}d8~R*UxzVVzZ0>8p{Pi!nvqG6{OWd7Ws59{ ze$vP!NUO>0Lms0GvxotKl>gTXf!>2TqVd@oy@##9Jr5T~EUcLLG!A#!LFO%Z zhzNNwo4^-fe$)hE;h_>q!OgTFDGDcnH=sa{*DWYU!p=z?k7S%hvRgKiW>JutVmgEw zgj{#F*I~t-aJSWuvRJRdh*?!lQlSN2fGBeFO>%*pX9?QuCcz?AGnR^mM0r8A*D~Do zHB7894Ii-u&H(L`O`NNsTJqEl33oH!ZjFGAmI;gCV6w3oVKH@4d}6sT6mf+@aW?K^ zBOW=M^O2&@<_j1+`9!HPv>u8d#BV`jXx5ztYhh|MFYLSn6)4U`QFEf;!D-<#dtTV; z&KWhWs;bABX@hsd7FY{&p|zjWpW_V%&2FN?X)WQJ^Sn7td5cuzr?EL)Qn3K0Rz%CZ zO;uKBOU_6JJI%hdm7+|#GE&mH$n-3s2jt0p8`^LkMwEvulQ7jqk#2*;OH{s~{p}3*}A^9jmmIVufU`!^^jryyht8k8uv8AuATP0p(BvSd7lax{?t~ zr7MB;arjHiED18-hC)g`6P{bvClHRh0c`EJ%)jm0CyC|B^A zOtAnTF`9B9FEAKO49IE_3^~pkrNU8B>@H2zTDy5-eoq~dCly6=3YZ!!Du~UFpja}! zG9U9)k_A$kDeChSV};@TM1#rV%;)7?YbYy(dwjN94_3*=k)zTk#!)vflZCr&97=$Tj6$;?;VF!CjhBW3zDVup$6?$y$iBVw zRba>W{R&~l(g1Fp&>QmkfW_Cfw9r#*dJpjaWVzVQ@e&NWf8xXU1}vp=IgI4qMp9QH zCgr*v&VVsM6!VWo?lXM_SUy?p$fx^Ky|Gup(jeF3^S~B#pRD}eCUA@~(BdO)n90K1 z1Xf4_+y&HaDJYv8WQ#v#y*}i~} zjrm;pY%T<1VmVf9c>?5eb}{g^@h;ifwcR2k*lv<7hi(}aRnP3^p^5sYf}DZ^b4fv2 z)LK#(?K8DLG0BM;OQKaJlUjn?*F2)Xl}$e z!0p;g$o|jQJ=)sL{g;$@tsR6HXnMgb->0;s|GBxLm)3)XZ*0;_TR3w6KJ;_63X(wq zSO2>3<=-oeyr>q4bG9R2q95ZCJ|COT4&rOU!xu)1sx7&Aq`FQ)D_TB#WwOXX)m$S5=Ic1mz+B{*}l*u#v zP17bmIGz(5C*I{BJnezW_iCUaGfxRE^X5GH#^cc1m#f3>SPT20`R+##L0MUWw@x|% z#zny7kQIhY@Hm_xU%=}uL&bh*4;W8?cLg#Y0GLfnhXMPUH2-tlkduuym(Rbq_k|{uyMa2 zx#TbE!P&*S5_jeIozb-j%GI(O+s{6;9JTi1%Fangc&>}Jl2na*vNE@{x-??Rm*cq0 z)VF`7A>uH&Y@!DWg>1+*Swd_s7lT|+w@kpF#XqdrctLlbJjJe4e;uGUzijJM8-MR= z?afv0=2ue|!iSX`BbZM%c-ROPffyfS9FnCumPMN7fw@uFjMAailtlVX6`s28bD{Tb z)wgLP02Nl~AW2I<{)grj!kyqw(&kuEH+ymVWpw}6%Zulu)_z>gQGNyYUo}K^i^3Gr z)358jX&O5>hhgnzhOrnj9MC%6*r9z0RU6;I@1ll|YaUlHBrzg7g&2^L>g}k$B+wDMvN<^Vy!bOcdPRm8&rcuemAo9c z%Gv?XBknttg1F;#mf5{dUj|jb`NebrY(+#9U6$mWRjc#?t48N7+fJ&B15L5Gol3aj3Jwb2Xh^H8nTr zbLhpDY;f+t|4(lsiqKkBUfrI;i@edH_h9Gfliq#Me=#H%OMm9xzUZq5wa}1X0`s8? z{Z+GqkMDkN*JYOm8^1g{vlBM{>Y1}|e7J{6{rVpe^UGe>%R1G;M~?%S$V4;lSh(-R z^U#{hxh|G&7Hl6v@1E5UV-epF!D4v|$e#8yVD6n3l^Zwc>#gpcO(hFcduPvEIun#} z;hptAqLS%EX>P8zBa4Zi(Y^)Utlf;+&XB*_JB;gYFZZY0y1wW+jYA9^(NXm?O15?L z=@n~fJvVIiEF$^S>h(9bsH4}?EOeQTFuzq5^qEKvH`dI1>T(j>rptbumyD7i8~6;^ z%GEkO$ceZ1qUBJM6UZvg4#ukRWvSps%{BM@f}hqttnvT;_tDfm%*irz5uVU^*`;TO z)~HU7UcC=(h7pw+q}?k%di_^z_laM>k1hdkbejc(%cT4KBt0me(dzm+@yC5=9dha! ztFt1y+c8Gzv2uqNX(iONLb~fgSX~vV~x&Hz7U(#G*bziZrV<&v{8Yef6pEP5vzh(T4X;UVRf8f5ESJ;-t|MtW68_*i# zoSTVjOEu&|<5B!9qA`dl>c-a6@))r6@|}ErsTNNne1fln zJPZZ%5f-Y_@|tuy%x*|^aT;HZD+ru2WF`l_v302)UvmyutuzcvSUQvO=^ik%R;bhv zCod!}!9&iy$h!$ye<8|}Vlav2dHKwr4<&Q`E+WpNWctRpJD&LBnjU?8keE+l9P7K*?7}jh6+fq#QSO_^9ol zeokne&LQV_cDiMj)~PmAaxYHB26JTApbX%xO?#5n#M8?3V+Cz|2W?K$S`ioxP^W<6`!Ij@nZ$L~n_6!(CrnIb`OZ5y_H|Sfy#5tAw zjRYC=WO(<_`Y<_wgUlA(h=E(iFjvMtKAfZ;W=^3R41$%Nsbh6d%Z@LS)U(V6+>5~O zf=obyCGAP-Mdkt^R|0`M<;I%K0rzQ=I+wi$epTW1V3?ed6XoM1^$@!ZPY_^_{}X%c zKfY9tfa+k^5Nf+M*+5ih;6lHvf5*AP0;C|iMCB|zKvIz)g(cUWP9jz(n>f#JAeiD7 zjxOoXrmss+?gH(6Jtxef_JKK#SG?_~xodUzTK0mlm8fyA$@~n*4(Ojj%Nr+N#ZjP$ zz=NG0$6BMize~<(wlo`us1H!YkJ7O%Kka*24|`rGEvJ&K^N0B>m;Io#&Nb;49u`<{ zi03>RX|cAwtb4(>$?I_3Y``gtLZxq!ufLw89+7w8QlP{v28&H;w)-lXxw3IhAe^19bD$##w4s?!PHY+5I%$fI@-%jw zDl~PVYaI{o2-ot;scm2JS`;6KErTVH$cvWLO}5t*b>PfwNDG2wk}2gZbl^Q`6pRy? z*+Gy=Db8v$y|U->p;TsQ*hTnpB5Ve3U{3~*n{m3QexN8(ja$zxJ$_Eh#%14)*5IoF zT?F%Nh|b{l5JTr8|6z!BUMi}>>x7QXyb3=-gbBPTf>VX*1zNRB?=Z{>$MN&zaE>e( z#!_ieH!hj;X49J+Pn^@);W)k)PqM@DBU^6$kc5lF50iBa?yV(>j7(>3Z|f~I*j>#>K7cD zawsrnXRvg~8+w}&&N!F3gfrP;U!$cA)%*QXZ&L=E*2!6IPoCAMvxoUP)%51Sb~b&J zIg1mKD1k>iaU!+hF8TaYYB-14g+#K>p8uxTQNQR-?h+A3gwKlM6_t3(r_-oe%^k0; zJ(8T}T>dzr9xY}OungFn`EPd8*YisVCfiTZ317xCbsV{rTBZ&BDV(ScBfPE?l3c&5 zKiWw@%+DoN*<_57nUd?!Tb=Fi5S9^4&oDvvN<~vqdj645_4?`@_KJsb2>SpNaSYkQ z8F)_ZD~^1U8iRP6VtjX6>EJk9I*#%D%bjC5C>|uK+$M(1=}M;I%I9yplw>mV5pgz~ zpu+~Q%Nhs|%X%EbUqaf3L}PZ>X|0?V&y!7pIJhe>4N9kWJM_)r)F@U+?bI|1{8R9h z^cRxpU;msM#Tr#Uq5fG2`lVc=2~D})y}fgkZPE!6mDeGtNQGxG+DaUHy_3FP`kriL zaDNv%mAX&&06+h&-oL6Ju9n-WN(iwKOFO-9|MjaUlX>Uo%JV6*LOnRkvxqcKUEBAa zqhBvCC$V0ofO?i>fZ<&EQm30a;-<8YO2*jWWAYWUE$#e%%azkOkz+x4wiVJbi0%JDKdvmtLktrR zlbw)L`uTR|wYQ$u=}QcIi7vx^wz^@#d)-Pak`S20%;yJcJjCx4`_II zQzrO(Oqn{KQ&KThJtj^{CgtOd1E)-XSe2=n835krTHbnU&5F5N0Dyw6V&R{kjJ2q=St_J--gB$D}{l%5Ue) zdRDh$HlSH_azj6}^~zI=b-}P7b#C(ax9h)!IOS`!8Q+W)(^d2uGMF!;DttW(G$OYq zkQc9cdAF9SS2}=p(CA4m>CznNbSc-2)Wz@pd9SlI&RMUZeGG>P*Kh$3=aZ(nP)M2= zr;-dpGP&?KJND@CA}5JCj1v(#J{-j}P-(tMkuNfv=@yAD86a}S>By%u=d_OeoV1nQ zLa=ww2Z_6DUMl^TphfdsdF%Rjf79ZG=}*{$)LA4X*JInW+6?@hyjD0tcflLvuGkY$ zMsjI|;>@=f_v#&=W=~TU1fD3ziFif?Q-{{Es$~Dn?!@n*pl%|GYOC;1wKdYQ58kRrA5_uMVYgkc6N0woRHxpI*<06i7>FO(NyX%$Qtl)o<3$PSL(#D7ne%I5bWJ+cqB zzH8DJ|CU-)YgS+|E|6kyOpnt~eVqmTR>J%^6fmY)ke`xJ`c31@e@;$q8NY_4JYfp= zM#zlZ%=*YHxyV-jlz|j+Q}jzjj#fXjFkKiCd>MJ)1MUe>S;F{8)xV`6O%3S}INA8bt3zQ*4o!Wb5f0Lnlif9GQAyUtY&od2=* zORs9RogBMfSV%7fV1%XG+INblK<>yX%<4TT`{Si_3`|iq6X>nT%vo^LC`j7sS;>fk3-+)o+s# z+51+Cd`)bliztu^aU^FXtouu<@8!}3oN(k&xI3H9;G5UA+Un#EN}EYG&qPu-9w$tG zCaqVT*{u~Za#V*jpYT7DO4<3@5tv!V#TuuLziaHBQ~b@7#y;flcIN}*^b~sZDNzjq&U(Hg=vwNzxxD| zGVbFQXOCUeb-4}jBNT+=HTi)=ZI#O4DID@&pMT~01Db-q8}@-HaAqSbW+057*V8X= zfezJVPs9y;B${4>LxlFgu!8;>e+?|yZpnS+w{CD!U^U_gyqTJ`iLE+7BA4 z;%1HFqgC-`#4y%@VT>xusB#R;8NNQxtw<`e^V`PW;uh>o00`lVHG^6 zYCxPoNtl$5R9dkLTDx+E+fAnl2X3P+qQT_2-x3LUVulaF<3ldNW)`g$#l}1Xs4MU+ zDP!F)1D{@vmCx$m!_1K0Nv5mt%VN zf}=tkPV^}!@ZJ@8THTpoGm$ z;VI!ZWGh2hmO(uoQnBhrO}+bRcDtTx??>T=YT!vgSe-Z-iBV}VmNOTUO`I2Uq6Fbm z4RP6`vPfD-TRBf{!p3nM#NEhCdPTb-g+%t+hr4y0gDv6}a7qO4;BhW}GJSeAInx8; zMVyM&aAa0>#*ND2KP0K=#A^_waaV|;G8~yU-bzxhi8s}+FJPF7#nLUmb2&-9C2l}w zRjD(f%siTxQ`FhgJ_5^5AV|bA#Nr31lGFv#HRQD`CZA0-XC$8ednffGD0YdJEh3X~ z)~2Z2r4yij5DmFeN#82XyOyNxmX;Anl+*((m0?JyesJ=bmI;wMAg#v3!T(^I?Q2%) z+vlQm2}gn#$0Ixf)q+VfX%Q{} zh&)14dH~liCaK@cpWt@Y)^Z?ZPS>4xypwtn$3jjF3p+A$!(9IAm^^bBm-t@@-W>m+ z@#CgUzEhLEalP#SPSKfX*p?TzZq+1n2^aIW;~Z_Y25GK>!U(sE0KSqV<2)i=cATae z(&nRZdlEW|G3z4R!|^@#ATw_cngmlIc}JQATe$IiRXnQ_{mx4$86LW${rZ!$baigR zD!gVR2)sZlumG$X;`X&aeDaW1X~JndS?R#?>z9AkAyC)DEmXs?Mb$i)pT3(r^V2i9 zrU=Z(*AnihAviMQ&Tq5UnD)i+9}(`=J@zuA$r882Tww=?% zz&8m*ve$n2gz$t$Ivy^G*z8` zbN%UsMahdh@-V_{@(@v-n~_*?uUXOyz)ma5?#2Z)^)2g!v!f6-DINWB>^3hm05!l z1YVGhQ~BwJFaI&w@M)$UM-J_V)PtpW#`WWiQn#lU5aw0|yUUh=67bS@$-1jpwXQ3O zz@1XC^}5GSBG=cBb61ep z9L~w*99Y^SeCOH2vmVtzfH(8oaVzI1!Vs1d*?v5SN*6k_SSzHCWQ%YM$D+>7!UJg6SofecXGo7;72yLc1uk_ZsRQIrA2bt6fgD;+|Z)uOJ1 z8Kv(?Us|BHtQjHF6=cJ}?d-h!PUc7W@T*n*^>AwGdprPO4`L{(gC$?m4y4GdrA@d? zJxSf_I;QV)kA19>HMDSPuX_wDFlF z^{RAQT@i}(4XNFL@7EP zqNzZJc_V1FEATx~kphN{=4UAA-!MAzEZPii3?x;V6VqF%?eRl;m*>zG5X&kQrLc3t02w4n|}raAQTALeT}@@lnN)NbJNtpr4Hd4l$&Mf5dQN6$3uFOG#E_P9 zs8a;({*z9;$h08{XCV}dL0T@(zp4{AvA2Nimq1kC%uKeMZpM=r4;`RvOS!an?7gLG zS3%DFGkXMK5wogMtBg;p3ShJgmPX6}^f%f}=5jh>5QPV`Gg#-R-)gia++0M2Y6u9| zW|*(rv`1U^7Pkp*vu;Jf3`paS7e0C@neyo-P%)JqvpOLLbdk3D6&)7k5`P0IhlCLA zrO0q@3cgMMBx{o;76^OP5)>k2FGFWVG7h#6=D(5@n!+Mg(+7LtpYnTMekn;kBCLTh zM_NNHm0?q@T$rSu6xM2wo^DsCFi0M#ud38+&URM5fjkYddu6_ym1&;0a46X0*eCak!{?Wq~4HzQ8h#(PDmyqts`#R z^$MCPa9qpS>C>kq&F1I%mcL#7%QaPW<#U0eBY5r#z>ByNXWp1ukoORw;0mpXoJ<)Y z*Wrt0Km=l%-Mj@YM4))UZKBQ8NhUd z{^D;6UsjKAf>lU`pom~zMZw^@oM?~cth|!uyk3$6MJ#^>wp+t%NUoJ*)8Bv*!@h!7 zV08R`&k!=7sI`u$8j_d?(qiDJ``&|Y)5V904D_9McK`B-mSgld@e303=0HNqeFBo# zN|Gk0mS`eZ*-S6QA8Q_vHQFjOyg)0d45i;`L)RoHv7J!DIVM9Wo`DH?MVDiT$qpIw zs$a&Fi72$6)Btr)QhV@6xRi(6DXpv^aGEa`LQ3P))ca{2|WC07D@$OaewY zSPW-zDZ;5XR9cy7yQcP##n~_MTWN(P1PK?s63IC|0&U_6Q-%=O|E;K$9-@qZ>;?oGK}efUB&kcp(~=0D_pRnSON6lV}jE{3FelCTA=NpDqIb4ltr z{%5_tJ7_MTEc~Q%11=A z$*3^2(MU5KM^cK>VzpQp8plb-pt8EbkWTKtf9anoRju5R-E#f4Kdx47gsxm6_We3~ z5m0TzXS+Lu4s?UJoaf(!*~{Rq!tD`jwmopF+($sxpFSJpt}7f&UZ+{sZlVW61denvcJN&xg;U;CT?< z1atp82Azj$bHfiXrAuGa1OAD99+>0`_cy!?Gd{p4{D8O2gZc0>9D=dK$A|Kt!Hqq0 z=K=8z+KHZqu}k4~KqJ3E{|#0B3F6Z?g6VBE_I>yey$jD0p0}Z39*lbAq*{G~*czQs zbO$!GZ$&q@_Hn?fpT-llY~L2f_(-!W{v7-PIfku*Z0x@2-{FbBX@k1}pCR@MSOWJ( z#YsIA{&g_1OT%&)xgKs0&jT^A7^as`FDV|5Z-kz2LwMwqV3fB&?0MJ-TVV92=T$c{Tj{?d*CwiKYT}g7cleT&f(owLw&EKP%x?Cp20J@9U$I- zxLS4$dv{629m7vUq66Y^FspMmya<-c5lc0sS=YmN-n$xX$DwgK)UQ%Ux(-@)pa-EKk5~=^29Ic%2UE*t z&W4A2O;T0mu~Q$1)38=urIKiK4{2y*nq_LmL1>w;R+})!{XGPht0#Z+aR^TxR@XmI z{U|TM3HSyUK*K_K3i?E9#+%=O`j0@Ic<*I!Jr8$2tI{4Q$mgp+0DnVG_x=+G?FCC! zU2y1r5Ze)P6cVGDJ1j#ZqbldF)S}V>~zyef<>WA(-KQU`M305Wn-r8;h>$ z7~*H=pXy0{RmY%VdyIK&?3~d5O3Omg3AHj z>D!8GcWW%D>_P?mK-doCOjHuT3a`Rh7&NJD7ASXM;c}&VGrR% z8T1@K@-BKQlzj?ypMhmi<$b7k?=PY7GEASszX9GSp#FB@CFG0scnjqBAo4zR>scM> zsoZDDe*&bjCDPFHaDUGrrL=M6%m+5Z7icc}9A>NgmDI8g#jatVZqaeBl^|=l8H4^EYF~onTW@%u{-HrEfTVUdB_|2%mqplev=D#s>GVb=;nONPmp0B*?AMEX}zoW(vzz`wHPgXnle>lBeNz>x_|0RutJ*<+~wxI;H8FEh3nn-tWY^;(t}%J z=qxmC0jks1gi{D}>b-W=hqLEU`ji%<UM(X>enNS_jQ(7zXY{CMP&(WIL3033}EhMdWkS+{ACGR zF^}R4vU$egqZvz&q&Y2UTkP^xeQCOKr8}0Q^$RI7J3iXhjf_wcCDh}-vTi+kw$v6m z5_E!y8gmNVRa_N07x<}$8CXAObKV^(Z;Vg&YI|Mn>c~>Gc`g-*8bqTh;4q3s;iM6v z<0k)6?@G1a*Dps`=TMePz8oKtys!A6LvKO5*j$Cq&ZiO;&K%T~Z2i|gI&BMZFT#!u z=;wtLmEEVmQ}mKvR3H@L_hdKnRfZZzJ50=C6R1yFmA^ix%G>On1yIG#EGr22v4#^_ z-o{|Pvyr=#ZwXYzMim}Jxwo07qTRrbiVQE$3N>Xn`x0y!ln7bR341h3Z2EfnKhDv3}Jn;A5z&jpiq(^693JwC^9_Oy6%q zKhC9mHFDGVnvwU|>eQ7>7TNgpM@bejuK56MnMZ{S#@ypBfHJWzzdl*w%wE03^T5r5 z6Pxg(9ppl&-35g+O-GP#n)Obus#wk)>G=-1x|@reETemRhV{;#?jDy{OisM-DfQ@L zx_BM_?D5^kdqxWrtEZb9D)U2y=7RYUNx-DyJE=aEIcNbmhc@KE%>LnSlO`G~8>u<) zyQ?s*aS47KE3_- zyVPUx5;7KE+>g)RO-B4(jIJtUw1|SRt=>Ef>^-uW#)e)EQei>JTWuU?2z0gd6|?0C z5!`?d?Z3$B)w30C4&iiq7_5d4K&%`~KaGMYlf0zki1e+l(H*w*Qa_PMbos$!Yhxj4?WnyPRagsL+10til>~ z)i70f4xvZem1&Z7*~iIQHF5u?W{jz3wq4by^e*E5#aaKGoQ0lJj|z`RyJ9`?%^O7P z3dG%lJ*V*H=g2t_pAB#dkDfz!cYyan&ux`8cR4?YvX6lL0L7n#k$s;8xUc0s*s1Du zjdwZ6M}AxJG>R=n!#;)H&q4Ql=fU`uFt)ZU)llDCxU2Ljcwi+oJO_~h~y7)Z^e+raP%lFq@<2k&S>qZ+D^G2BS}1^$85eZpDzG2dL* zMekMMzJ)_4@S7i#{;v1jJGg6wVG>MgXsm6SxDXaYnWutoDo=a~1>Nc≤|PE9{4N zYbd>)ouYIr2{kp4-7Dqa$hBPv^RS4cue)JF?`T6)Zzv3rgJJ=BP{nA=UDdHc%zz1z zUS0CCP5Bs@T$`rhGuHa|968J}nfW6k5(E_tC=uGtq>YVI)(H}rG%No3t&$|?`L zhxZW%mQF==QM{x?$;)oV@AkKh8Mp@QqfAZqNBslu@SB6h3YAsENllMKNp>%DNe+8= z>9hvakj-*7{k%D=8m;Q21&cW5rGMy?zWo35NgGp>*6h1&+CesR6XLS9Cn7Bba&nIP z|7kO(Od9LY^$!|9V}_P)q-Dy)$un~N4U;vep|PBG(0vnU+#Q?lZyrBQOHkLDj701{ zZT#37{;p&18#{T*c+R1R@xRypcKhD;eg5{W4OFfA!v)0De7Tl-4&mk-oGJGDA$17AMz<-GQ{Ii>5AaraJ}GIreEoec!q zmwx#~`v^D$EG!G`A_3YHOqA$KV{lo<5PVvZr}IitS?{E zaR}0dW`4!Doca2d8#gqK*knH-OJRlNoGuP%kuVk8lULa|r@xvxIi+BhB;kT8-0Dga z&SlUel{xFqRwKu3fnA24w-@$L`JRu}VvDO*v6C0U%$ZvOTSP5|2kAL*f8D)?-}YVv zuM(p+lDBPxVLHUbb@Y(-I=TABE9I>wj=g80Y!vMF=E11|=E>@*Qoa|qn!Q%9RA;Ti z!gSE!beMe;{tCfRj;V*kX)rq69}ZE~^-8T3 zcZEOb6pVt=Y<4UDXpvixuu;Bg`E`6fwGIm0gcG;()9xSK^|snRk%1;Z@-uE@%5!~2 ztCv#_!}qeps|O1yNG7vvO20vDBsBU-Sfe;Cb|-}^#(+DLbS0&9zj0cl--5N0U1lUz z{3C;ux|G)e=f4p(^>zW;AsKlJH#$kJgpkUltiRK|W75?9?dTJUQ;#236f*LTY_w{$ zL+D3IFte0sNYV6{m0ulN&)0|*rZN#zPadJDyHQNWA&}b0Rz@{LWGmOsH<(|CflDE4 zY_vh@nwe;Dd)w>(&93!ugFGkS>0rF$oT&sjdZN^MK8?13+95}2${%9rjG*6bp;ixP zTu7}qtbqahpn5Gdj4A&f1|?Uut*u(~LD);LlI;e;Xft-cQ|LjlANln}%Je1CXci@t zNfFaCK6FSYo~18{L7&ka@Ec5N7u=4cI&lqmi+9SL(IwGxy4m?JR;v@XX%n6gU3+z} z>n0(J%YKM6Gf?D8jcctoVFxFi6ZUb2D9`bP2DG0{^Qn=1obrjVMXIt6GlM$zgW(PZ(YS1VJ3TqL0 zN6s#=Hz7amcU5@$kOLj{=|OF}9#nxtU^yL?dyN?Vmz5( ze3l$22-<`B0b4qNfA@vBh5+-6eKijLqD|?X6Yu=xH+tTA$1TDQsK$d~mFe4spFaDO zpu564R-uZb@|x1(vLqGL=JnDSD%HSIpE$0Gu9>Nq#?KP1*_`XJgHm-$o>R|u2GI(O z4MVnd~I(n&=L>Y&(b?svnS|t zhupbRtZ|T$6ex4T8BOiG^*V1XVCFD_s%mox&$8etXMIe&<=y>6cir)fX{XJVd5Wnj zS5AAloZqk4KFZ8tjV485If9}YQ!2-_9+7&nSTyJy}CTPz${<| zQISMR6f@+>1-<5M_7(+<2}iVn_k84rX>u# zs^HIvLR$5vPTbAzqQR|^B$Pfb+TPZQTiLmc8$*5rcy4*ws}Nq7#mp%-Bltb`nsHP)QojaSxc9PU1<{7e`DBP77^ zARtAx!rZjF*BYo)#I=4yzdb4Nj~kDZlGnnC9xIz3^o`H`nlw9X+(KGKd)Q&5d72On zlFI4n;QTA?dJFBwYfKJK6lEhkKYc&Aq(fisOQu^49ZJwlIGz#vbMj=fHnTP6cE*fh z1OphQeocYGkUfSl630MP|2Wd_bNjz)*1pe==ADd^=M%(i2?yMma%j*F-Sa1!TZ_5y z*XCKcpxTAWZAj7-$+BhxC#cpQW0bAV?)A0|_|q%j=o46LS%xH)nZ$o$rtQDii90O& z7{QQm^TxO)#Oj5;MHq>@YYrR zJUL}w#B`6{S8OvNRrAQ=hLUEHvS2B1oLQfr+@SlTAGd8{f`VKS;FbI|H!gnXs_u2X z!G47rV#FPTWhxbws&AlM+jMG&?MFu4c~%e0WGGfY?M~J`XIslC6fVdlk%1Sp@`cZI z>J{5zCMwYG7|&(AnEbRRNxfxjWBeTJR$I=X&U^kdTosz@gqCmS{dMP)sI`>Kx`8k{ z3nm2a;YaahjyyRB@`zr!+re&QG zIot6yG!Y&1yB+ujJj#`2_oV&;{|@h>H;|?=B$f0JWzP@L2YcA)$#-3EdRc4;IP&iI=r0ilTnm2Haz*8A6(Cf9i z#X0*$?yw{!NW{23oT=O8LF_DRPrj@#p3 z!V~Z~GB`$#FaJ&Gv6O@FH`@9Xa{ik1l>R;`EFxO5cyf_*6Waj)QAS;Hp{eYAN-nqB7oFs~z~6__m_FbAFi z)v8+rp`^gYw5!SM&%Sw0pV=JwsLG98LPTsvWc9YCDe@Y*-OPm*oDIoDhBdS}Mcyng zv@k$$ECMzyDHlJjkwT`hcxNYsfC-?E$yjxaP zyEIuaEUyH^k|%_y$MODsPO5{vTNa5n2Svt|aeSXy_M}QK;Cy=uPFTvT`%W}P$hi4l zv&U&`$pBG6uD{O{vuyR{R!`j<|CD3?ub<~>jC(MDp_L?ArcXb!iDIl4j|V4ck|Aw2 zoRDQtGE$D#6~(1mCsvL+kblBv%mA6&bVF^*!BHpjkK0;JMTEOarJ#D<>Fj5f6jc@T zf_=6G5hW!PW5H}<%#-blShCYiZ2y~D&cpF@3-{XYnegDigSazE)P_3m9eoQA;Ob74 zE^rL*?H7Y&m?)7X5O9X3c*KK9vcG+dv=F>xu#=C98UixScPqTVoE8by9Y6PR{RY?i@I{ zv5$f=qUA4OeF6#|ksiYg{|OFZ2Q1{}u$f^@3_%$jDNROGhOhkjkFS5LLpW@LU4qwb zHvM<@-o(AC>U}(w>)~;^&ZqO_SLb0GXm=Q{mja~ofhJOq`N35)gNV29qn5)0;hTj0k1x0l@RK;#j zi;?wRH+&yF%{c-AtG?B?6tQsZd^h|OJjt^*m0_$>x|Qdb2Hb|2Rth1AV^!gS_69H+t7=FYGku*{Ys_j4IN!Bv5JdeDAe(6TV7aOo|~7&j-CIEi>V7 zy5TErdnCKpXLtC#j?_N4?=sr&jdI(ww~EWjMxLeh^GOJgd;y69^-aLqCB-UOX**m3 zEMAMS_%ykjS95kiUttx%Ut4}{d<`PY zhP;K4r`)t(6@Xn;R{^uYp&dqnT2#Ecpc6=vmG#PsEj-2=bDjdu6@ZQLD$DT%OOqD5 zkyHe?kOBPSEH=kEIe8QgUBC2_Vdro(Zx3P?gAzbL1G=+P$_CYH^x;EtOJR#plo7OM z@fl3tP_q69A8yy73FJDEzfp_;s=f$<9Eu=VM*pY(G$~9GN4Gz;;5odKnaFmapq*i4 z28f}6AOsbLmaOKZB#TDGGo#JgS`Qjy!{MU} zx9S9?=977gHwE8t*nsPsy|3^nYY{0nbelCF)(m2^Y-SGWImuZ>i zY!bz$1qyDt1>ao05j)D+?EmGW+1`fF#e5B^LuSpHHtGI3M!d!PSu>~1Kjx}`?^idU z{c2>xG6wxb?<%|0_Xt=ISAZ*E!q|z=fVv)Q!JPxt+q_eP6*>1k7OO-Bk)9X9UDNp) zftA3%7kUtOx4bUjDLYq?|}y&*aEiz^cEcT8kCoV8B>WjLH&zBdi({@ z{~6H#d9WPzeh$10Y|iN!1AaCoqY2Q9!Q<9v!T70<^qe^uP0bqoHVBN$>-#E*egVRd zzXu*Dpen1qLS9(uHMmz+;9c+v*a;*h%jXnx;u)6b!PB7E5?~!$)nf=z)+gKh z3vp0o!@WaB_^m#V%U(0KY$vFD5;TF>UcF|;WZ%3;ZqJ=eyaEb-+2>Pu5PS%)fIopx z!Q0?r z0S~+YdsaOD2axr9fJQyRw*mQ{*8uVk{}7B*x`4DsA8#A@JJ=510Q>bm7J_&gJ$^oO zpRyT<9bg$)1LVRH4bgpI0k{U_0hO5p$Fcn~9ziokRt?G?Fz^vyNp+^L3g+g!#Il5J zD=Cbiep;a?2L(Vzal<81xd8ehW$)k7Bmb`2=ZEgWB= zZUn?tFk`@@*4xS!gPK7NzF|N6oO}na1eKe?V{=C|fyUat1Hg30Bl)Yr^i`k*H0$?$ zt4?=*40eN+I&yiW6~q<;aenxT!YA(OS2(107qAreuCtG>-vhKwU^)(yc>v6>E&d5i zUkXmZT{>0zi)Qd>;t}UBGS7j6DVC9M0>`AP5%ta?>VP_-CbSyRwf+feb`Pnyvqz-= zxcDO(LvpL-s>E%IIy|dV>^ZV=%D{!7s1=a+)D@#dZZWhs-rdXc6j0BClFE|Cs-lS* zjI6|L;QlzYFny`-Si)F9bsp(|{dL{G_wxw+An#>Zv||H3*a6wcicl|&2Syq415V?TJZnx5E(q?W~v2Kre7ZU<6l}{ z0}XT0q@O&;f8G$C(0AChz`b0UaFS7EwF+#CGC`* zv)0}@;9)LqU_(Ea4ui55^cf%1?d zi&E`;^}*HCzxfpo81B3f*ikjWHEe!nF6@_+TL83z-fx0}!G=^Tw@fel*6+-j29bC* z@Y6#jahtD4w$+{Ti2dZ5b2~4+ij@ayQ*iBrG6`rK%>{ypb*6mmzIyiAc3db6*%k(m zKNzvvLZr?MSwuh!oHdxrru5Vjv!EZLb)iEK$H&Gid*!9LldpCxZT`cn#%MMMx6YJV zP8B#lErR1yU%qOLMlY~Gxbk6}DA_E6m?p|xvfLc5K9U2$%`*r)uTwMug3vUb_)Z$D z8r0fvSG{G7#DUno!Amoif*#4m`}6uY@b?1byB0kDK*%R)JgeycXvS(01)5YX2#IM* zo9CCC4e1MXA$as*nIuRL%XzZo?jp%<;#_~mU%_! zz)VkZo8+W`I0%W4>*_wJ|G0OJ{R7fnu%czJ635%*lyvT^#byDWh5S5x@d1&?8a*VsJv2!(5XKXd1W*tEHv3LfLj&Chlpj?LjyGq@lF2@pU+Bq*fxmfyZ~Yn)x-<1-Qz$d8jSFC|mj zw&7NR=E$ZeN}P`TQjaxFIr#3SMepDO9wdAoIWbeTK)&y3hM$CRNzxVRF_1&jqY4)KfvKe7YoR%l2VmZ8Z+3d%Km>;t@{bKTi zx5S-qt$eMmdx-G^GilAiF&2B8`NWs!*LNR~=J?WCFsB$2G7frZ1wbt_PZEu9!nV(D z4dVOw;yG$nmT2jjFvT|j--2yBkFUD?Dwv;*#DViB&79P2*<=2dH)sB|sf}|H>UiF; z@A*wf`~0BzeaA*p9R`C zwG%FZ6W)fWz*O7U@Gvl*hCR%BG8wk`0W=1;;<8PN1e~$pFiTmHkM0+!s0~dYSwDUJ znBs|vM{E=AHSt_~iL*Lhc&}q<&89In9<|1)BnEYqywQ#e(mwUES7j9VsYiLnIJ;&LxKxuF~vKP_F9M3z@V7GxAx z5JmYllIH)b`09n-#pQL9%CZ)pgjAWew~k$I7>KNO> zA}PIK2z~T+cc{lCkB$lpYU=n)|R9bA%)HEbHb`sb_V z4W%fn*}k1_0aYu3_tCr>rdk@;D==KUtN2N9@2G)I;0JI6ya`6n(~S3Vehy~XapYBT zzkQ#mQM65=DNE`|?_IZOqp^b59jhhU$y1~S0Rn_rE>i@I&&|-zZjreW|KQCZUp1!D z;k+i%JfayLpQK)Zj;%>>v+KMhlZ+-&v?V>SVG?}Vb($wMi2xRrNHO{sj$m*GvfXfX z@G1vMnF5r`VW(?3oHBw~{XQ<%7ZopXpA@7p30VsRNM5CNbWHfic4#E^E>y+K3`TEJxs$T2D+ zdpxN~vpdfo!p9>Ac`mrm@frdYL-87|_hI27$&!qIUQ%bY>j3U)II3RgIl>mwz)lea zjR=C$e~KC)kbtQS{Xyp;)N;6ZSf?^{w8l{SbBIlnIlzcXm4}gI@e|yfzF|MQn~{E_ z7={v5TJKyEDE)^lVXL#0HQ1SVaB-}9^sJ;aArZ3}DFt9rDzM+)Z*h@3(V(rqT@quZ!z zumM0@>LUH{-q+9d!P2=s9%3E1336wm)gV-u9&glGN`22Sc@A?PhSV7S#m!+Ur$}`l zQ;f8mP9|r4%=cmP1dat1R1A5JOT*5A4uJ{_C3j2FZH(38UgTPA}dHn`ZT4V z*OF&(qxUN75|GU<3TZ-})gLCoTfHY(mF0BGn3q!VMp`~fg4?~jX`M9l`2mp@6zR;@ z80p`SqEm~~y7H9|>UG*IaME{!p4`Hz$MXpwfs zA|OE$c@pHPteXR*;NvL~kvdsMt17L({F;(q;&uq;tDbP+vwH~ljAKyw7ce?La7mC% z3#hRA%j7ET_kTkNY=Y*ubknhzCTPE6g4JFAAGtszB0GR8$w3rOT7LcQ_pb!-6{v60;Tba9cA| zYLeBkVHoPYpW4p%Ebq~`@?Jtg0!Pj!s#%$*EVL4}?}SeQR)YHXDxpC*0bs2pE0moV z1h%)kJkMW{lN43AHshXrNI3^LOS?h#D!^7TE%4D~=7-mo{{0SYNw|PqBMow?1%2H1 z;*?FwFYyqskp~b_QcIAfJz<)g9&H4fqP`PA<~R-Jj7^IN@wE{$XCu`rtBNn6$VttG zp`khWr|%7?u?_TQo=6NJ=y)SgNv!saVwi~}=8hW72P3j)L)S+{ev_%js!YJb5VebQN1T~7avb6q@uuw06AxSO$ z8+h_nC~;k0Ktopm(4nx$30WZeoxHs!CUbH?|J~>G5u#s`K)AR0<`nWq4wH>E4sNkp zUB^!!TUZ`Q2KhX6{1i@Zq3%&Ph_;Bs<5NRSg!CodXuCc-1&rvT>SduMX7MP3GZJ=Z zS5^T>GMVy*=Z*T}k7^ei@dUHO-cUyBY#-}1p=T^VvZ8{Jpz?eQd)&CHL!C(Y$+A=& z6kP}WHHx{-XFfP(xDKw-<~#UhAZv!Q3>4MT2S9Eb(%k;t`$k-Pahl=9-M+p^{q=79L~)@JZBpmFjf1FyYr zj(dT1F{mP8VI{=uk)u0`%#u?$YOuW2`Xg!vUbX&7;8BJfaMjTItv-c`TIGms6ueF`4hd>R-t*4fkF?T!n}iZjUzC{Bm1l(XR{!|J<2K;8TH}{ z-oz)(VJ&qYSSU6vuvy17bJeapuQ6-j3GghyUhPlA>d95`Ila)3aYlU91AjJB z{+BUUHp75!N+Gr{;$mP&4Jmo95V8x!2H%m_HJa2Eu7ApEv8SbuVOUW5J5v z(NMWr7q{GT%7kukck&Y$GV?APXCQPWuW!>%v*knXRqU{Yw`6!c(8HXOK@k4ItlQzf z!A3O66}HGuvtL~I#s{B(`NaIKLj4z?o&3HFmsE%&uuvgDzQVcg4bdjQnrn(<2cVMO zWW*jATuZ8qsxtQz)sC3Q7g4iqb)g}dnVB`Q`cQEqa~M}kjF#%qc`$K|Qm3SdqJ!(V z?K?|0RG_TO^b>>#Wd{B4`3TkG<5LHI%X5D{^r(Tv*uB7~(*WLX64kUupl~p`ee4aO zB8v2BB&8z7(=)1iQ}jWL;p2LQJq!pOR9A5jDH7N+stsGF-|@>%Csp%#$7t` z77i|L+stjn)HWqk1nFS-NTq_JsZe!?utvfv1J$19S5Q8gwfPm4HorqEZv7^|juJTtG?CPwaf>I*tC=?d z;MVs_1}frDFfh~)fM8#kLe=fZ%+?p912CbeiMXo7QwruAEQYN_t0+yTIg6Cew{&tC zb`dS595!#jZuO-Zf3^zP(4t-F)K_i1o%KgK(w>JP$Lnl%TBeC3df#=ZXp=<9D&+zt z$fd~+A-k_?*JxE_JkKY2Pm&OR=f9}Z0R6-6GX@H+%gYWM%sf_FcGTo;6!bchQH z#o-$70D71>TB{T5>1s9&Gd^`<=SG~l-q$RyCT#%dv>id&2&f4J!DK*!W+9Ol!Dwd{ zp5JP52S8yPBSb7|wz{A4W(2);OpVu9-OJ}Sv6vZdt8)>~48!~+9;R)%Nz=vkEoLGu zxr^>6p+sMi&q~!eb4jm}ja-Y>b(G5`hy=(<*sY>Kf`A`FSxP+|UHi8g56^1#Ch5^h zYO94JX*wy4Gfqp}duEBlmQ#$&B5M(QC{mDHZek4;%Q%{FZ$^Hj)r=@QZGsWm`j(OF z;?qWCrjyzU5YX|0&Z>$?|Hsla$FrD00hC3cSd#RaR=F&G?k@aw8&00V?9q-e^0=hI z#F`eY_mnSLm(f*$?1`R7+n;a27$SRz=zG|C>$p`Wm=#qnzf7Wq{D+^#%$G@xn}Y>>FnPy zb`Pjs3ev9U^6$>!>!~v;Yq&NjW!rP(Rl(TL>fDrV`(JB9p4|!}T zyO=r*N8dFeo*%EZRFo!ZsK2ysb7P#{Oy2~Ys zQr0aUMl9S-Ogjv4B=WNqpE^_r6GlWwW-s(e6z3HIof0c=$;WM_ zfzO(eN<3pal3iokAf<>DE%RwX;kOhUZx+)+iYx#w3#3HW6Dx?g&H4s?(q+8cC)neV z3sR8t=89~9Bxp}Ei2cF==@xmr#@Y*LisWfZFxNxL!g#WEyMcDrs>flbonjc0kwsdx2@J!r6vbpX z{HCu2i*aDvg6+mwkE^Qy2e6ocNHft}{j>@FTwMzo#4@zb`KG9jUkZ1HwXxo{s_&X6{H%$}B=_#eyK3`0Pr z*?JGM$#TDhO%rWYTDaf6H&1RidP~+4b!wA@psPopXpcv$sX=neo z_u~zh0e&bh+d4qL%Gx+c%YdL|{iS9yB*wz%h>iwaT0*x&|1fa#DXIRqzkBET7cfVy zIIhvTF2P|#yw*GHF!2=+4E*dvLcf!Y#*j7(Pbo&Wb<+{??3s@F4Fgf-C1JlXHu^j8 z;GFo+3huQp2UHdrq@z~9H`+U|)LWqRfkPj83otr|Yz39J|A3k0B`on2XiU29{chFP z=P<1)%vi{Qh=&5vWZZ5ubIZ!l^=@?N+)g$^u~;u$qa}&G~w6Ua1V_>*jK5XzpSI(N?L*QdZ zC=4L6z@O%B)Ygi@7%RZV)E$nDVz)KBfD=XQXlL>c6-DrpV;_sGpZGoSN$~R*!H6QE zC*4zDg7P2?2B={ko3m!1;`_!&wzQ$!Si4__z1iOUI(v%C&3H)e~ZA2 zVA{OAY4-k*a>t@2rV?fWvm2|C-@bI}_2*1)V0a!{GaaI*C~RRxnMtL{`@w)8A{RnO zMU_*Ex<%F=lvBQJhcJ1jZlpejWFBRep=^`#rDPIRBj^~w+0V~WJJ{OZnZ(?wGjggb z$Az&m(G^~cc;`Vf0EQl^+J}rt$mEsJ9037OBNZ6 zr0=Kx=AncZo|0$HoKywJhm-lP+F$xe-&y^^TtUa~YghpCH5=ix2a-azFOKWL7;fva8fo)R9MgwkLsT1gQ9qOw zh9>Ol%9d?!<~8&|g@^f7Lkk_W=o1B(%s`TXYSbsj#|X4F;S~bC1zL1Q6-J0!I2}z8 zCN2!%WN|N^Ui5AS4sx|gTC9mrfuUOfy&m}A0QLv^Pqhy9_b0NrQioS`f}l{u+$BCh z#D(Zia1glX3BLu*dQkg9GJ??$e>4_Bzd*atieWC1cQ^%8QfC=a($1s4}%&j zN{m9X0-xh_=Ws53FK<9A;QI<0z878vK!q@!ZuiwxoGaOYflTHtFXGfi!q(ItfBLR;9P%Hw& zlR$Q6yCfGBvDU;vQZ~EJq3c{81)!>v`AN+Pj2Y?d@YAl(!_now9`0f1_cT$wH zdClGmjNlJR&4XPY0Wpl-<_|{vsm#QmzN@eLe7&pDvl|=dpOxwto!|MV{h(n9ME?ST z4FP9gx{q2A>az-*1+(Y)!nUx_J0Yq8jdH00-#%~?1bi`DE-ECp1N(l+p9lWA&U*iT z@OZ8F7>G6jr2n%HA z-UNS1#(=Q_JJzi)fZ8Ck3yiH|%a~@6dksuE1MX=ksjI22Ph?kUCt>IwSR#f3E8z*4 zIS3W9h1UE@3xE)yM{>os{8W}dGc}KR$<`{?kW_U~itd?80dVNclgA&y-clDG&ElQh zs8mLzuBPwzKH4w>)tz*%(RuO+u^5OWL78QAZ${FYKDM{tYEhg6{{rm=RwpX~3sjIK z@`G|R`D`LnEK8`2jnYVs4p@_Zucv?YUBpOb=l;fSWmv_*GFr;8)d{b{c1G#?mp0qfeYLE*{1%g$P?7Rh7;qYXj@3zg) z>8(VNeX;+0rRRwLuY%sc^p0SAsc~2u_L@EbdpEDT$>W|5c(19ENJeHjoSBj0!j9cY z4rG`2V=ckkN5nTsJ%SzqGZf&d{o*+zljBj}c||~kD$A-)vO|fNtRQv2&wPWsNFe9#_;%}r5%)E&hF^gD#?F6W zHE68$7kks)fS&pNKQ6$AG8A2!yVzMWbh>juR?TDM{{q&6e}Tndax1tyk;P@fFdxns zm{xE7l@46bkJRSkbJFiXWs!R)@QbzF-02{KYjxO_HY#h*JBONY=ayrR0#_$si?x{Zp1FqYEs6Xd2 z3uvuGrWB4ss>te(2rB?c3p%A8=Jo%XuOe-X?i8-9W6?DOKeqv1rbU8dfanKC_l97i z_0wechXys-DUX9B-S#w}%C56X@X2zG z62f`v_qahsmqXO3;nZTqd9;8I!9siaQAjU_sGz6B|RCjIPzIicHdKqVss z$Z}Nw+vAHrcp75oQ(_}EvG$&lWuPj>LJ|#wP}%n+@eaHOa%@FfRAfaR4QRQMl0dC| z8+^zma!909A#v|XV6F0p2HV2*?qM0(cfz!!98bS?#c(|rZtG+QsC1~m!URoioe`Au z+}DQMSD0~=ye&IeGdwHQ%hdm18OfEMH%#agTgm!>rR;XU&D2V97<%w^42>h_qYKbl zFtws@{-|;9gWRHu=rK6&Jh(e8&DEt(u0IEijJRL}Q>L<^Fm$uBsWl|=4!->v9*4oW zZJnA7-l?+p{Y25jQ8MJbUXi1C!*>^~jJ+N;4;HiT%^Z!ovF1nqxF zg4@6`SRwL-;};=%PA*K0rRcIID2Pd~Y?K32PkV9I<>~ zt*akn9==aMT=llmOBZ>PN>mK4$SEIIZXyI@NB)`|#3}L|9ngp8x5O&bJm&wB1Rtd~ zG2uu>bu3ufDI77knfh`~CxIYHl`hr4WbxdNrdc=sJ< z|3)IwQ@Ds5iEHVboEFQj8$D>ugk(n450Z@^VK0*7B(7wv%=Sn#pZFAmb?RY(c#~RA zwvq*z)cB+#|K0t&-!&MkrDz3;Iem!?mph({G`#a@vgJeQG#B+{7e>4p1*u8@=U5Va z9sS5_lEu`~Db6)={x!Dye`pd#it zxWV0-v_H73?5*mTL&^3Kl;CFd^Cgc=A~ z(Fmbwt05+BV62G04!hVF038h{4Q?L6t?dV+Rf^UWl1WpM{pYWr8N$o`-~d~e;fa)H zyQ8V)J^1NnLoB}xe#3e42YZxwt=~kXhT_Pux7iGv&}i9Gal53Jr>^7MtP$A>b}~A% z8S5?5(G<;m@T}fy5sI~uC)kj^pPgeVf#6Ar6?k5v-vmWrtLWVgemOo^Wl6@GxV-+o zJMaSPoiVj!G9k_54Wm)t&G4ug;;ZAMGulD$enk|Z14XRsu`-yU*+G5X;IDpN3NZ^QX;*K71K{49bamrxYKN zrqh3M*=_^+4ZR6kMaJe}u@^%|a_c*P+iu2~VHWb4Iv$EfD=O1))w_DjPQ)!_&+t(> zY`t}ZI(A*g3PENU`yD^D=+@^m?dCWSaMu_yQm6>g0xhM%`S6eCI8Sqjc~CcxEc^MTOx69V zjJ(^-As*&C>FL?GKDWJLwzWeiA^K=SPMt-}O_921{`n^Z+R2|{Y}T?utF5#k6SsP7IczTRG1Lm!9(4j&)(54+ zcy)dICmbo^HL3nzo8I3jHWZ);aXt}|1A)+JS<@IB8L%t`jRC<$XkuNh0|m$-1^*pK z$9j`Ilyeqt2X>X030J>XK)I6c`oB5;`dL!HX5nk-OdJ-1NM$0=<4gpzgB5v&Ig$RM zmw{)V7-fb#QcZ4IxK_h%%IE2GIlZTd9Lc!UL9^TnN%1CAAYl38g?Egmu^Te|O^zpO zQ@ycnPYq0Px9v0FWhmUi{FL+fQ1Mex*t2A82{%X?G+r*V4#}%g3gJERaYK7m!GGfv z=uU%k>%3twe-We}XO1TByb~z0pc3Q9drg73fa9EWzTVyUI;JT{%gs?O@mxzP4QczC z^@l#ix=`OHW>2m+mnJ0_VgS_SK!M63MPMn~ZH`sJd8e9w-QC_YW>s#i$RS6I?NUk! z(6y%yop3*`;_*D$v!2w+y&G=IzYVxX(Xe0MG)6&^riHzl z$R>zs7DXTg5zaK%496qx+RY%?EpQQsU|GpdI{`QJL#$8&p#HqweQ&NwPUw4mptN3{~6{(`hXeF0= zOFG-T;RnP`am`kkVX+pZo2|ap4L>Fxh_jl?aEg*<_|x{DF`s7udTg0?D%d)K6a+rV&A;`m*F*$QkT50tTeCYQboZcmRl`t6Zd%x&qk zUWiJ8iiqmvEnbV&JU+A`C)n4$wVP~vvTG#AnBJ;&Y)S)v;jc%MOSRXwF&<+XPZ+V@ z)LXOR>Jf8WeIL8lh6=OCIEHaZXOM|;%mit)rSMmv4Y)(8$+Tm8GPT3~Q&uj+4++yy z;YrTiS`Lr7?Qh-veeXV+F&cvWQ6T9jW$=sbe?N%fcEm38HAO!Hccz-YfMdgo*FEii zw@cMLP9=?^xzO2;ry2gAaMpn9w|e5zCFi%kb`x9Ch^M@VV^T(Mmz-JaOg#mMzCM^7 zS(kTBn5P&K(KMgtO7K;CawS*$4n&JpYju%g>zU#vj{U8>euwW!%)u*RJ5nPlKZDk* z2D~TA-4$4vE&sgg_L4hmdW`XVfQzzmnks6HLz)im(Z&VtCk8}k6y4*lBMQ^DyN#be z6WIne&JGQqG+pQNAIq8(s-Hb=&a9be%x$yghUUzh-58p7Uuc^C>)dHGW`r6aoi=Cg zoZL{uyt$!SGeZqHw)3Q!Q$qcwO`SG((u{#KW;Ha1=HB0ktIY{bX}oXR%xQCHJQkWW z>%qpk_v@wSUlQxT-FoovrbUi+owbCj0;<0}m}0SvNSMBhj5AP^?eX_c%b)Tomgor+ zc5o#D#nHp7I#UGDg>^qZ*@9D~qt)aBhPMzpM|A7?-0=QVi(#`z{zSQ)*_lpPRz~XT zw;DEk=gD=X%NEUbT4OmWv~eY%KfBs#@-kD$jRqo1DOqvCj%`AW=h{#v-lV!ne<&7F zExeAgo%U2frYpe)4N*sx%Q~X?x&HUnn_s>DYsmH7Ah%fc<*~la2OqRb$A~&#KF2`iVci)t0q>l81^_D${T7> z?yATdzR(@;+rnHQor+*>K%-Ptl53+hb^&-3K#P0eN$@9d0Q@yA;MUhqb>fSuFVUV@ zC!JZBd;*EnAFzzL2?;rZOc6jArBjm1A2t~~&>Y`I#_TosM;*PUn&{auy>35Z ztnkTrI~B6jOb=?krlmo59x-0g=7c_iYNzV$Ws_1{+qtQGe^w^;&?6{-n!>QU$ zZ|JqFQSRwPD@*9Cg1^$ntG*BkDGwkxmrhz?Ntc@klot@B6#`N*AC|bGO@2$St)I^$ zIh)xqO@|^J6Rskkhvue1lAL((jTio6Sfp>rIZkIjMW0J>9`1FR|$RRWUq@mb^o3%o-|*+JZe&_@wJ?eH6V>&c^(k zR72$u{~&%CQ>IpUs&m(Y)gTsH4BJ4ltwj8u^4C#ST48A9Ff#$V+4+{;-?w}X8XiTB zYfF!iRHghygEy;u`Yu1ChIq2bd|DF%pzo0T-0(^nBAZONHrM-#D%>LQ#%;C93SeZ{g15Gj_XIwnlWwiw7IkJ@A{)KY4)_nIiXqih3e-u=l}!# z_nr0NgVW~BnKo;tUIW8MOqzTD98@rD($7L8?z<1i_QzlQO?qV7lu)1iP<`XfnW0R* zT7GEo%*nH6KQwFhq`8e#kXWBTB0p3&>(Nk;$|5B7oi}4Heu2j5PfsIq-#)Lgab~Fh zjA`>HHR!KNXz<`r-Rx;orZytAuCejHq{pu*ss4{p|MsW*Ut5Z!HB4II@U5_wA+I;PY_s9AM`pS#YqcfRHaloDQe#1!30NqsQ2ShckX=y`6i&cNcX9 zMBgBLK1U7@DsHzW=sY8$eMcYoD)@=*NO7o(tD5OvIw=3vd$(7SkT+ z;atVDQ|#oG=iWGr-D#L3aHCM1Qn=nQ0Rbc(hiB-S{c0yR3_1nsQWI-^^4O(``YX#_ zgq=vstg1~h#g~k#F2r7iSLr5DkYe;tb@%o?Tq$xBQ_u2M1E3RkKf-g^DkY-Pav;y) zH+dcgJKY>x@bucVhE#ALbyI+GcSirX)0^t`LUO=j7r6()Sd1j2;WV|-h9`~cdfyAE zHG(HKsMQy{2X&lkWqZU^fU^bwXJDh&G0xnC%Ms-zza@nPoBp)`x2Z3}5o(`^283s% zrutQPs|TnZZ0_XLI6v(kXA8ZDp#wgK@q5$4h`0aSXj6x`(^qLrX0bzy7NwClZMXXT zhW?K2V*{?#W}feEx}Dz54Fj-bC!3{pC7*Rtuc&4_G?JBIc)?dq|+D0IJxZw2~oBy39~1 zZFub@?pWtiZ-y5O{{Rz*tNpnmG0!o$WbC-R`uzdSPhHISx2)Unq>+B^uy?m02OL^y zZ9JTr$65mBE6axPRIjwIH&=X>?{m?YUmo%2RfSWb4lXP)ddxwtQ^A$=Gk|*uXb;C& z8?w3N>7yNhTxB4S#{7?+AHKviN0D|jK;E&<7V)H+`ouWRAD8E za}vpC^(PLK8k7Xz>-33yX>7AD`D1n^k zN{+CF5l@+nG-ffJSLPk(EQ^K;(&l@x33oW3nE#PjzhwE2B%?w6#3pE_D$dZADVmwk zc|x=o>_JLK-x1|Wr_%MGL0qBiq*$%U6}@DkG(}&`Y8ZotHiPd_gQr$J2jcfBb=DhT z&iLRmvj0S2<783ixHQ7X+PvB25mqKtQO?z}nM^vSMEr?7l@vLOVIrhPXpD-~q>7=1 z!~)VoV6k!!j9G47?7f$FSd7@=;H2Cy%ah+X+ntxn5YhHb1e*izf$Kz%i{?C@Xl695 zSrx^V4AWz{EWYs zmA8R9jih*mMNL#Dg|JxO*m`)g1&c+GQ=coA)C+LoZ~AyK*-5u?SpkbP;a5!=vY{<) zd0(&OKzuuMM6LM(aPj0Du=}$;ZX*^yvqlNfl*7*?k&_`t>fEFnf!Eo+a)e|eQHl(w zgu#2)8NeOvWjRL6w}m-nM2d^-++YAtvz>~I<$O-2+x^iHYQAOwud+8~8Nh%~ zik6&4MuBD6Z$dmGwaFC}$Swb`(EshNe8bPsl(l~1g3jlw$i_H`5F5JlI>=iA$N}8= z>PtW@169_t*WdJ&6Q@OyPC`Q3Zv;7r_Wk*ck#UJZ2%1iQMWhh z?c;w2_y?1tY(J|gij-IMNc0X2g{7AM{=v!?z&!(Cju`YgvxQ=+Y|v#8hz*N96d0-I z63d|b0`N}&k8nvOQb&Fa@u~ab^C$P8BQf){uILCyj+sb7yGp>|2oeUvCKut=3=Z=N zyj+KiHgmvM1_^5qkd|!V*(dZvNG&M2s}voVl%{z!W+Xq|n!-lwpX$=N5Pi=MlpN&=5fOwdLcnOAISASCGhO(Eemm`pOZ5U( z7XU?!m<0%?006C*Ihq=5a(L{SCmM=SzR(K;50(FfeS#b;C8e47biQl=JIcHG{GjH`3ngos zIWP2@E<{}{KZAKm5!!fUd1oVMH))(&C~Sm(0*MP6J41)M!#pw~p^z(QE#Y z|HX_2DZ{4Cojap3G)nR6#in~9tqFL&(ysJY|aP{-Pi_K%+G_>KNYd&h5(G`w;4 zgOhZo1+yTN=6|Hs|KW%cGUz^ZM{H|$^!}2SU`R9A3oe6=I^A*_ECws!xcxA;5JoS8 z2abV<6Qk6D>f|1y^Tyvj`gJho_h8spKwSjGzXt_dz`*Chq!)DlWAftGG`i5>>rq%nB;FDl?$VO7C zl_Jy3OWOA)!5@PoA-T#&3zdE*g;iSiV6Y8Q9qdnuD&R2!5AE9Z-Hs!2!whuiGHr2T zrYlg8uS5vO;!Q`st)l2`ndSEfrP>RBPvv(9f_9eJ?8?eObDD0#C4xqReb=W=jLTe$J zKqjwl$|F8}@^|07jg5q~)0thlHFh5nLN=1KNLl6gCON9JfBf_9*wpU;D?rr0a^_FD z>Ig?P7A^~NF`wdaf%_b!G-e_ zg>h*FRkDS7m%YIJj^0H*3%AqTz}0_)D4f^=b?RaDF+n$EF<~mn!KHgw~Ob!yN ztyMIzRig4d20QcNB?{t`^X;d9?}?4bJ}6Wi8pTcoc?9m=^}crK3ksyjo&)m~r(TOj$}UJH)MCVR7U#?UTM;#&o{Y6sGQ zk#rLhcD)V3E>8Sm?}dNA1{;b|;QPY8Sp~>3e2# z=^G(U{Q7%5mu7$--cxw9G?zjkW|1XMV(h@lMk#k}c*37gJK#eu4S0lz6#+!qkV^X8 zE@majNLcH#R6B~g`Z9t|8gy@QFO4s=E`z^}vGsSJ1W&=*9+B z#@Tyek#f69AsN=X-=EYEpN?+M6n5pA=tiFS&7a>pcug{lpbFPylMx@Jg56F8W)7nd z^lLH;-Q7~#k!4>2nC#NoWPa%?fYt)nYT$n8ZO{h$^m`n>4#JN|>ne_caV2m}Y$afF zC09l)nz%O*ExETinyX}2$^*qbYmqlN^&kia{pFxE^a`k*L`{y4sseZ8&}*ad0l)Ua ztK|)IQNxj%1923FVJ^tzfc|ub)$8Z;Sg#^TRziOq?E>v2{rvDse-B_+vS=^owC7oz zRMck6z0WpA3yteHve1WOAi%@|E|0C2bP(BWuHYdZoC;m`OhqvCngfi~Nk5+W__qM- zp%?eQn5lTZ)+k>9`}?Q*1val#@Um{+DhR2iY&~U^*V#E-zC_K}W)Dm74rh$=kok^W zGF9@*KMox~2CxzHp1MO>ngrcNlPRl8kBmD&W|@zxp#!nllmYh)sNW1WfD3RJJV#zn zW}d;?=(m?+jPV4Ter)i{g1GNqxj!+2DQ9zn;UJ$C^cL`WAe<$Y6Fuxt0i~Q@4uoFu z-Z?qF`e)q9_m`cyZ2g4H>Z+;%V-mIf3Udn!Z6$?enU0d0%wZ4JCT4gDtt7LmWJY}t zrj+h$DQBV_Ch}}`usk0dFRefK(nhS)qYwWY9txRfMwxi^`+vXwraXTuiR59kW==K2 zhMU2TxbDA^XTacb!~2KwLJ!TFGi~m)Su;aZ=QYlm^RrpAA3*Bp*^M)1Of%z+8>B); z+Lzo=x|lI9G;yR=0+VeZT8e@GeZMs%{KC&KGfJa z<+1;n2o;t8ADSC|e`9FaBuvT}0h=&bCruuF%ovCAKcJ{$*sNJ|Fr_ndD*okvHkLk` z(4G21%?%BjG`nHeyxB-eCTk7#fApc*`T`*#y(4SKa~;3#c-P3tx)-Nr{q;wykpuUh zY&(4rLfUkYJZf&fK8aZmPBQ+Uzf!7SbmE8b}-pN%9PEfd3^Ht zH6T!xR`J-fwQqc7IPGn;eauWK^5oxD=*~$?+qi0HGWWz%`$}d^o))?zKk1xqz&ETm z;5c5Y<2YU6_x30c_)4na*BGf8A(9Tfy`s|){rqG<#)K4P3#xot5VfY4jRwL$6)xC-Caqo!SvWd6l zn6(8=d~_Z+3g{giaIc`leOkc4SnV@lh*^X+OjUks6v0^=+^d-Z8Mc^HhLl|dv{SYw zO+<|N7aO}5<3yl^aqx_6MXZ!Imy^daJn#SG?mYvmD$>W{Gjn>q=l0%9dQV6QJ@lp# zur~rmVMU@83;WyM2nbok5Rrw5EFiLgh=9mqM1+VD0*e?CAtI}Y2w6lxWC8iH_&+n} zT<+cX|KI~Mk)`0>A|v5d5><<-p@T?;(OW)_a3Ms z*W>%D`NI4|H;~~ubvb;RE{3x;=qz+au4=q7Z&xt_tcq-8(g0iLV}MIwXGX8nW12L| zFe!C-|MbyUQH(2YUA&%p5jGp&xBlg$C^txs;A~E;=N-Jwq*zD10vJ2tr0u_eH^`Kt z28?ak^ZEW+IMUvlyo2l;@CEQDAfE`<^?MOGM{>pFd0+?t>RaEiAm4+|#A#Sj=o#j# z%&ibyFhJgyR;lSjtx{hhe|7e1+79f3lQ7AYla@^myQRcrrA!`|FGAZS#ggrIkTzZ= zRE@vGHzJOxbE0+KxgU@hv(lb(lO8(oUhO%H2J@T-89ILs$^>^92(939$uZJ7Le$9i zxGm~{7%>Nk2;(6_yv^xw3vnVY{s112%EJN6 zLz5^1t6-iGrT8PP=tB&3%0~gS3o?a@W(m zCn|E@grbu~Bx1VY*p(+DAo=d2WO<;F!hnJ{`%RuTdDh&$qmF=)mBWm)x zMT7YzsaQ)FUpl@6UwiV(58yodp{k-m5B4wap9;Fs{&KRysU2_`6_NN@RFtAA{YTdl zTtOpiPJRe?QX7CHKlAoV+1#VFtYoxx*d6#BVC$sTQ*V6q6*;5N|3v}(-*3BlKuzes zpGSc+`2DFfUe}(bHD9i(2jkuc!fRkhbc6f_m|-QRSM{ERZYOK>P4Xfrxbxv|Z$NVB z^WY3T3|;~3uQ2O=x*wb>{EMuI|0L(b(Yf8>>yYiomw1cvz5`#w+2nViu=E`F8`WnC z+yHu1+$H8$4_nB;O#AM41p~rX@@H_G{tMYf{uK-pvt6seV#q|;$ai2FnOAZD*vH5o zmT1CV+HW*I z0x${&=&|)Z^*|=|5|ap(W_uKyP7}6VIJf*~Y!%+co)tYKV4${=cj>U^pD+yRk)#7+ z!kRx!+tRnExp6lC_$G$S*DO1vRd78BI^!|ND(ID6%@Y(LPgIPyZVl<(F}} zN03|W3zY-VWZ_gHQFW``iNv^pLjK0!dg&zi)A+Z5y*?x7!HnJ$dlI3j zN`%Tov*BT~lll}s_zoTvHfc{scoDiL&g?(ha2D$U>U~>HA8M})_frb76JZ2d9NHrG zc@&N8npESf))#*j_7egVrf?4If(o6|a2b+J~u>NOcL!@>_*NeH~+{&pu9|izGhFW2=?B2HrP1B|~4a{-uu<6kvRP?35^3Qp?rebiM0Eq_M#h zNI(Z2C^C$<7hnhyfyK5-nIWqy9<*rBVI-MvtsP;YE%b@le7T}mVRrYvc{zC1B(!JR z7vWV43+nm!amgJRSe{uB^2ur$7z^xx7v$! zEN6|9P>mO>eK#(STFfom;TFYjqGc!wM8YF$&&e?DN=2Wvn_AS;`!q|IAd5{dgV5*apsc8SlOPX#;y2j`PKnX*H+0mbqqIG~YOgR5ZQ zJni$dW7qw%_>JF>%N5-1J7A|&9I!_M7PHT9wMV>Wd&taJ|EUt(UIhsguHAYW)z)5z zLp$I?B_fE4@PEAy%_ml)J*RPlhj+j^+Dl)gHRHx^`SX?fi{2SWfsj2$W3Or^kFO0? z<%dSpPMe185ko^KPph3Wxd!ooHIqX9CL%MGX~OW1Wg0W{3K9Z$Z2r8yV`s-!jnnxs zq_H}G*Z;)-?g*W%U*53_mu>F&@bl+G9WUpHI$qNXW`6!W;)_n!FB8atLq`kLm^-V7 z31n%0cY!S|4;6%p%LGgMYosxfkJnDqIMaz!$4{u8qOpVh>z=MP;_?oun^rqXup-uK z6yn`9o@!dnbZs`%W~>#ecf5N3(rdyvS-bWZl9ljtXoNJAPMOYve7EAs^T_U$)cE-q zw$I#yRD#S#a~JIOL>h1N>;CuNdkfpXolOXkYgkW9ox=!wfAAm-1?GB~cgC%2{&ab}fTKj>J!{^BoZJ}_e^N6%`q1^yMZz)jj4V8qe;_1l?W zzhFY>%<~^78_6HQV}A$Vl8a$=1Na@lw?ZB|3h(?452NuK%Y7Xnjn~+Gbz$d@@|LfF^Stiuxpl=aOYt!=YWSay2t>lAmr?vU+dyJ1ph3yV*gm1!C zfG2Mu`_Xv})Y>%!7Lqk@rMLURn1^*kkXQt60>Z*eYc(>%>o6y@>*A|3$=+`S4#9`hvHJX9Nf5$ne0r;WKVpzJ$%Vo8^htJIz>`ENXG04C zW%E=3hp673eQP%V`X_FweYqpC2B-?YJQMHDPkB!K`qgr@1Caemd^2=)w{Y%C!}1=7 zrF#GCBz$pVJ)}8{%CP1%o6+w&lkkO!)zIgXWUo_HQZMRPN0RVGi6$tSeHPK;HK*qNGpLfB0Ok#s7DTa$NkLk0o0I^^8T^fIp9wEZ}86UkK8t? z0gjp+y05VJwERicbAauh=%9x)A0%pmy`=6Bh!5TOyVGFII`Gf~Lt^(y;t7XdxPvT3yNFiMf|uV)tp~^+A#mhN}NgOfPIx*8CM-5CkO=*BP9@zNTy$Y z+~5Am>&PsR+vr@QOzo3bpzpr7u3mm~pPp1^rQ?dEI8@$bmxa{b@Y=uhmJbQHZ+17T zVg_sSvabWP+iK6_^Mv?>J8laOG7V$Ks$-dI_po^1qN+djeZrPAz+39>TV6RlKbRfQ ze8w_R8ps#f%X&N!E-C0!mRH`R=nmZ;?8o0edjsX<(hykezb4z97S-f1+{We*?PTz{+2IaB5kgi@aLLhV zJi-XPuJl$>DAun#ZVlHMUM_~Lg2g0If-D&8gw2?~_~O=Z>%-ePi$$SLPLq^UOTF@s zR4w0~%i;Y+~nbyS8aCt45;YEMHi ze~B;3^e4*b?#gpqKV@WQIFcjw=SswsJm!P-Xu{UfBq{L^f8Wv5&?28q)~dFX|5@=hL_e z?hs|wD%lw)nd;-m_xDg%}Oxc-=k`S%>8c zo-NzpJmpRBa5P@mYXt~qnd3I8NN~&U?X}sruxZ)^PjZ1+$nB2?J*m(IZ(P#* z>mg)yy#w2Xeq}>Tx)+&fGcnX7k~B-m96KscB~`-0NJ1zu!BI%w>i+wgx4Q4#1h;ZZ zZbX!G!cyw&zH(9TUZeVMZidG=o}y)j4pAKA1|)|sOBQW|S!Zu;gPHHZ!yKJ|pTZQ} zE2doc{`Y*cC)@USv_;8(=B{vQNvt3+e8?_ zjy)oL1zrMW&hDmrqoebN_UiW%ushvG7K;^MzWE)pi&R>fW%623ISW+wuPDejf<7EX zz<{7`pf+$+X3XZWlNok@G?Y3>9eQjm>JsaSgv{1(IL&!|C5LcprjN*EFD`D0di+Mp zo(|M)LU1jkXG`j63m;&hlF9M6^$Mi>TkxH2QoO zC5_C?+|0HM=HcXE);X|`+gv7_2@`EMlV-}S$`YyZLma143Erm`=>)@U@z}SLF-Q=O8;(ZGS*h@{7(m0o|&=Vs{>0&t> zbPHuCLfx{vIr1wDGnH(1P)4YG^@m{4^I*WMpyCdna}F4p;9DSRp)8!F3M#bGRdT{S zhP+R3=uhHrS7(2H6?=y+Wp9c?IHpjdgQD07$L0rF(o(|S3T1@z6r2!nOl9^kn_Cp{ zVM6N|_@C`k^cV0wcOanzy;dR4kK~51{tjly9U&nL~|sbEf6nu76P5 zyVhlv9nu@XbBCv2#O{&<-uvjWMuLWYXz84SaLTk$_VnmI^id;z&9_I4H9e&^h}~#y zmvU@*Y9Dq!j6+PDw@Kt+58#IQjoem<>~9~3Gsu{43e12~k{(#Xq{2sEtHDxR^BRf1 zJqDQSsNqkI1){e73t&h-FEPB-$)Rm45vNWRZPk=VJ)I+G~23wR~Ne9FHXYK_a2hSXpE#{Q7X0JS3ZMa$GsbPGE0Ny z8jFl!&2{5O2?G!KX3G&bC6gvzW=u9wAR>xNsHDP5vMtMVzomdG(a61fflQf(P4$#B zy^0@y;6o62Pv9T`sIyqNv#N^B|76U&7olhayQh&Slh&XsQ=oHdCVV*_{bs(^ae==ccdXDYh zaXZp=u8DP+GUEP%aE4Daq zXcn8nB2XnV#eI_TgRqieQyfLN=-@B%wSRi%x!OMie>lUP!{@((EIe$ATm8X4 zFByAi#Z9zaMMAWLngGLQnzB0}BilHMrp1^wR_T{$)vm~*-C@y)d61os#4)i#IkVu)Za0V8=J zMb)mwxd-<1i&+r&kW{7@rs8ItLGO&IO=y9k-e6MJYygHO>7pfG?cr2*i;E!4m6_YS zTfL^ZF(Du7@Q`qsDs@^)%Pgk66pg(Whitkj9H4w6qq-$FO(D@9LzCDl&VzD^8uUOm zTcg2^;B{ycp9Rr&*eq>fhuk@&%#mRsB}s~?8;no1WYKzkN1v09v#ObsWDB2`Mz_yYUS5t-WhzDN zY;vIMWw&yIag9_otjxudMv!_L)(8XQ&?ENy1+i0kKqG_i$s*w0dVppuiEm$w&W}xC zH(R*a0Czw?RTn=-SFX<@9W5kZSAp|;p{KrlUIazsyx@bCn* z^Z~*jN=#vg+QSlfI;JIjp;P%wHx)?i9{Nd9nns0gppd= zC!I@HUBo(z>(QNX(5;S*Xb3WX5>B1gu)b61-H=#BH-OQl(GeN>Wy79g%CmF05`RvX z9JJ)|{&+8Wpre2_Wt35UCiJ)UFQz@VZt6_ndo(*cQe5HDZ4aFRgIC|Q@zq_wA}21} z#`rPdas(qzJ45rl#Vl|fo0cQwBpO|-b}jx570_6U43L*&G0CFDXX-LPA4(_+f4>@vXTGvbpZYZcWLC?yOXJQ^p5L0=qc{@prs_8; zfkLgExsK{-{p?r)H?sDCOLcgiX&z};ZyNB%m9Ux7h+jn`e$(>StoYS{x2=SW>2PVb zFIHyQ%VWxB?^O*xBPa-Ic4lU5pI+b5f|L`8G;W#klTy8D&d0Ax<2C?c6__bsL2Pad;qd?>_u`9zTBDN%n=8IKHSjIgO#jChA~{WuTaYN zEeG}BkwM47Y*1;L0!!5g5+25(Dh|d&+(Sp4xz>E=ZQ|e4M8(SR{uL};7CuUcTpkjJ9k9DtHewiAVC3v?gi_DIF0Q`xM zy9f7q5o8UN$MY`$(QP$GYyIcZUw_d1Fd8M{uEV+fNxsiZKatr zL1;kCF`&5e>29SDhQSbQ1v@u1DH4y zJo7;KkKSqb&IU`sJoqZ8E*mC}P$m~n7&I<1A25qRa3IbOjd_Z5mSCC-U~jF_J?16DMfMJsJ5 z9<$c^|1dJgs=c?Am-O;>vuHP&?7STe7ye*`cU*S{504DG!!2qP_>&{<@D@51Su!zJ z$1IR$3h^thsnIk$GxkWmY9Brt}{UBhPLV`{{&(X**6r( zb@VRmTN(;*_ei6t+oax(DqBxSwp{AYH1%c%NZrIiQQCcHci9kFw9dt|(rA)v8Ea&# z?T((tH~3|ivCeH7&B~C7IdgE>l96IyyZ(aL*(WG1*(;U)_A+rO-QPOgP$70)Nw!{= zwMxn6@(Sv<{MlkwA|qGK6|x2)HSh=UjT4JP< zXhvc7HgnaVZGZ2FO(<)gzj6^3~Wj0FT|_bKC4`8vP}o zh7fE!HQDF#2E0xq;~uy+83+e_{*XUy*bDnY$nfQ&G>0mT1iR_?LFbW=_hw*mirfr} zW1?CVHS~=*$=(W5Bg#ze^8aMZoI|FBke4%;q)z)$8WGcrtt+XKh=D^L*6%?bS_JyA z#h1Jco8B`9xna2uoH=vg5-=cYn6rHL)v3RZMtp9gbsKOQ*LTN9sDW0v#kvZ(j0>$} zmr;1cIv;qF#+4r$!=1N|O;i~u>@dpa+o~nQMzZ}aqwz-DaTqK&tbW>zipy=|0>;pt zZyIH*ZG9D^amQMtY^SYQN*Yl9&FHYzHU~y3jfpNdDz@21c#IBDtT4)s*kZRje8VU^ zYwPAq)_dLP@VxCDh*cOJE<=SVg0AB@e->5l`Et}(VnCOI!Y%%2l}6}jkwPe@p&SaX&#$kQzF@%MO7@Ejk39_8$fm= z&<&SQy#2S2J>ynEVLrTW+HE#d_xJjLH&NQnmD_TB(L%4!I;8)kj0r^FoSx3olAa}f z$sx7@KA$VMFtcYcX6+jdnF^_5QH)0H1C)nc12P{ij#W+=GVGpix5XMkb^`!&fb$Bt zdr*8O@R!on)>3yN-vu6fv`-tD3&z}C(VrXHlZg4$LZXlx!VWRrlauRxL|O#OAIKR~ zklQB^v^YJcgxoDSEl7V=!> zF>|JOHZVU60;GkP%CxQZDu4y-5^#6mS&>4vZ`59Jn#9ty6&v1dej26uJjL#324w1F z&5CpLP=FUd{0U7V-qH0I9HY9wYhg`;U|g){%FLsxUx8CSq#wgaM-Op`cCDmgVP3h3J|4u^ZF}8rhoBbvs} zA?)x4>{f5kks5dHB^}ztx3gx|<+GTaUOmPFjst#PhpysRbH0en>JGbYDY|jRSsl8Q z-@{3&%Pg9mwiH%#y9})OBM55JpqA8wdi4hbEB-X+iiMoca5`4+otlS|)dg3Z=8NSS z1N#geITt(+z6F1Vz3%Tb7l>taFWWP!Kk4I3jQ#f5jjMk^{oUXjc-5g81_H@7*z~!f0^U+aL(Ej!cE>2 ziMg$Ak)zpU4RoJw`dV+lP@K>BJszLW?ewPJ{=LmFV(1)kr6BPZmn@i^sbn>CJN333 z#2t*+lSug7@pwu?vS8_pK$q$r7JLb`qgaM!jWkwR_SMx7y}xuJzi)Wc=B0oPC&&x~6G3{6)MjSEQ|M?ubIKGb?DZ22Hw}Q$^I$uGe2gs@CjQxq%B2oWlkjE+4@K zRKTca)lSi7Ckc43FPP&Hfkt%`VQg!PRiv9%9a}pMq2H$L=5s?MUM2rk1BVmk zuoL>~S6Nm zF?1S=I){3mTsJK=xpurZaLttG@NG;HxWQ>RayRx?hUL+#VGlW};`Y11@B z@@LeG)kpVj`a&ExMi^Kx5!@V_T?Di%JKhX}4~%YrkMDpzR)Lz0p!<-aqn;aE)Vt3k z1rG$P`&|JABi4dW@B(NAz4|`28e|QjLzF{uqGND{~$gVK;cZd2>-6jT_s;exq0!-y;s%KOS4c;*;FeoP>9= zhcVnndkr`mW8FdwcL~Bpc8fB=9AJC~M|f}eK zaG0!%+-d1|p`w*w76_^nvmKV-my_fa@+ zz?;RDN`T{Y{j`vmdViX_aC?hDT^EmOw>R>fKD27XjUSM$JUd4^rZ5YVo~_%Hs5DFG zo90*&{dK0ZQj7u?1p=Q;5K0tKy2A%f#D4MA1p~b`re=j2-jf2uj37cd8drOJ za(d@Xhm-)rYMX$|NmKkD#p5^xZil)-aZi(`8G-%J?cbxfJFf0m`0N0~WhFxrVxi&} z$!VWe>lK*gAwaGhq?T>vCurOm*#bABwpMqjW2@_)oUUE#g1z74(`!c6)oFM4pqeKp zPC`E8Q)*`{6sv#xVe8Tt(3$ZP+sVSpyPm9mHn-=9dXV`*>5yrILR=eosH&&I$v`7H zfjXOR5!k*@$y7W+LHBJ!N}{yu=Oh1cVe3eGgWxdxcpvekt(a7jZUJY$`24q@kz=8< zh&dp@PyrRS0)7mg3Xgd7GU`FQYTB69f{iOxtB6v$8z@zttTg(;`7th>Jm5l{V>`2q zrxKMc8ST!bWh8q3sMd*wX(M}4fH7^UWFG*|5?$NKqPzOcIW$gGP|vd`xXJEGjsZkO z2qipdl;mXJJAkp(`nkr=6NyAILHM1J5Z(Gg!^u)E{DAuLBXa+cNJP33M7WGdDae28 zGQbN;;Er>9xQgdoqYXv*Zll!|Znk9h)LjK>kQZ@FkHFoK&y$(1TqOm& z+JIqkL0YVAX3P|2v5=%0*&LHUV<`Z{#N357^G-GD@jMkKp&ebyMy*d9{M(~npl(o} zSLKjQSVIJ13#Q#UD^4`;!z;Q~IUqrkc1x;8BxJ0*KJyI%mkHq=N&_oZs*S+$=v|Kr zrLYOuw}W6KAp3HI9@qeU6Vg|3?%Iuqu+uQRTR9Cp8{jQc;x<88acpoG?5ma`miz5I@30q@YxB%>mX8I2}h3@;GL$; zG>n>kqHu*jpX5Pzyj7stcsO$I8TfO${ zS34T<2kA7ep<%xE7UeiV%1&d~F=N#IrqvWH$E=(ZwWWQpGb{B4JZD-*Lze`g%@0AA zs`o%5>E_(yMwJ$IH?8ud_M^IjHp4y-+oSFJ7F9t35!3@xrL0tTSLE(#iS53>g`>KL z)-wmo<}_LHcLt6()fD!F}bB$@J*~y zsjK07xC;#L5lltHJ9_B*z0YDk7H)=gtW;p4C45RZwRXV@q*)OgC|j;%>X{>|X$cO_ zEYW}wLA^mTjWF;Hqu?4ym#aQ6$Tm4J>Fa!j;s4(w44uD(tm0IQNQ96D#CQY7?Xu7I8bo!x_H zvQl^RdvC2k$`7fT*#?9j`JC7@hfPsXSKr%%p{>j}0N6YbT9dCW7BsBYF+I&J1cXN; za#Za~$>ksgT@3~2iq5B+6d@s06d5mQNTZuOC_n?)us1wmTdwNNJPT_ zWnX?_qYmB3Ee2%o-W1iV7nxd^U2Qt_Fn0}g*R3B3(`>#jyto%buW;)@J_TZV0H(37 za}Q|C<`nqZd@fx{`5eW%G_B*k-HTgsQnp3>9?~|Fngvv=ME5ol0e8(bzSK6p5fF)S z1QD;%r;P0Z&b((#hQA23bc*EOQm zBmmNG7{uc=!xv_+#NVPzxXT0SY&S4A34UwW9@V!&m(U8xM2uph@ie0B%nhw`?ec3B zw?O^!J9hJxZ{NYm_?C(%z=%+{fS?LP3~k@}U*7c~!SrfzCFq-zZOu=nJo^a&kd#c^ z0$e1M>4s!H^|dz5T#0emtet5puNwvO%gGeivE-do41(^K8X#{Dm;}{tN#!KjyGes; zliM#1(zX(W+y#UGoqF0Qi1|k-F+0Qw zS$;N+a&K;Hdv=^zAoF*U`f8p%ylMYQ4_e`+pn=lMuJ2sGL@Prs`JfGYcq!r*#Be3- zk?f|S{pttU(R?G^ND_%cZ8H@RsT;8C$j5DZ=32ND_JknOBe{X~%+K3iYr{EtFT!Su zsAenOv6N1C!J*gRr?Ell%+@#?4+MdJ0QRVak0mpUcI`t8r!nalsSOky2%NmrWVae5RQ-1! z{H+Ea^Be`McY48F`?0)^Uu1(3WW#l3efG&-LnY@;+b z(<1}uPN{;Mj~T6Z3!5oXdwnGB^+}OjE$3$M!{Cd;Zb%LM9R-FwuHQ)#W(mh2XH2l-(e6_re z*7$mlpM+`YGrLY-)mtxB8foBgl9bf}Q;$;fKM`2_jIGK#TFH$Hte>YyQ?8hLUAn$A zdRVUW-?ZE~$| z7_FC@+9>Ue+!G|oJ5!VEIEu!$3Ct-|3(0pk#A92R{AVGUAqm25byKEI(9>C*6szZM zKCw<3*GtGFI@tqo%#hKo;7{X*R`j`}f1i&)pwCWFq)vPn^T}GjmFVm8M~!l2K`fEqy*MaC^s(IGNaf`XE&x(M}rj z@nYGg=e;A4O-08B+_OXAuFxAPn`c;lQuu?*6N2lM={#NXfLXN*3&=zf@iNGGAKw2h z7@U@EXP|ZrT?d&aMr9;(MA9fX%I0$h?sU^}mt09+#~WS3k3q+8XaDj&&TzAe)wmBi z-$E-HX>N`!-~N5Mk*AMcMl*7*N~<|(G@M)Z~1BzK8Dbv@M|O^!30+erl>^5vKfVs|k!<}0!?m?*=2kMK zYNJTi#W3M47S~a*>B~Qoebn>oXlrG*YU`0Dr?yvTYZBhX@1P7DC5_`Lqxg2uk!2 zf=a3;K-we$C|1gDVpv{ZckGwiu_ig@bzvSyXD#Q7t6(ulkknwI))N61yacnQ~R{}-6XtSTFOx7 ze1Wv(i7C~<=3N+v48eX<>Y_-G1@aGRH@hX9Qs#m@!`mSXb+jTmnVIq&j?1c6+3ed* zX+BgP$;m8}H?lT{b@@13zdTva)?WaeW8&miqmP~1J?o>`d@sqR$)Ow0CgIzZ>kJXo zD5PkTLc#>p4_oy^W$RE*kz`DTK#f3XRv;DZlg1*|UrP3KP-$g|f?SR2NJ?@MytA{( zfFDz~P`w$tvnL!psh2Vq=AJepjCir z>H5z7s5PH)x8UwyGi?IOii8s%O`nWd>;APUnv4(}`q-q}sS|5Lk01uT4&}fLO{xi1 zPpNyfcKpY0*Jy1gOrJ7-0!oK8xb6|0M`=pklM`ykKR4qmzWN_uow;hH#%rR@@v%8- z>_Ocwo?{IjTv`t{Q?{~f)!r>5%~$O+Oe)QTH^@xY*)zlJ>aK@6LI-`tzh9dBGz!kr z0Jl+^5i6ZWqjVxDwGoDkA)X8K~<{dIxzMAS@#xVNMxtcC5nVo}@cTB6EP&aet6{*)N{W z!09vSPKt0Q2*MRldzo9_0y=OFMY!_`!jqRq95!!4!VqN(vlF-+c8AkWm>g+L*tL%r zBZk<1ooOXuu8Sb7k7`qn5JbW2KtIC6(8p>xn1Q`R*vphOE2$LN{6UKVLO{L02Ms)* zJ3)bd8c8s~$X$S$oD(}RR$I9_B&;d~pdTW*GYulHc^RJ1Zmy96Srq_g8;h(vhPD75 z*g_E+{{W-uSq~b%z%7q+Yaq-WLV}#ZlupOubY)90nhpF-ihUL8C!uAFf#xc{iGm|@ zAu%GkJ_yZ*FY#dO`BM}u&n7@+R=Pgo3mlDLjX+4<0-?&7knQfBHRj<;dWhv@mw&+O`9soS;DQ>t31FH*<%&J4kj~O}NIIg?xe@`a9&KB28ois7#saU{w+g3L zIVLTI7J`t>kVuP(dgdQGbhUgPB5n+EWhruY!Dl+OMcx4aOK^&zoA&C^{qi;7$SHL> z^NZXmu6@(T8dRI~6?q!~S;gA+DN0k{wbVnLSwp!FIDbN*Jrc!d_7H^(Lv2hT3Foz0 zi5cAl(`_|R)`a>^pH>&Du9-4zsvxBYI2P<3uXpT10kb+Cd&G-VWatWvh`_d6_kw9rcKGx zCVC^3vJ8)ocW|jypcm6mx(o-*)=%q~=v8;pJ8pHb`Q2pI-Sq#s?lx>cZ&f`{&jZQQ zi=QP+mokfh!|1l*(5-Hn)xdMVf!ASN>Jpd+wgH&vRM>}>kFNamF^Nh9ho!S^?02~%*oM2rn zwgtmA`k+n729;(2%MH~7))6$Ep0m^lXe`c$?0^hf=$|l{K|Qg;+@*T+D`Je!50g}0 zj7pu)uIqD+=7+@=(2XKX%gFztPQFjVFCqU-yF}lef`V%R51EA~{4Q@??ue*TZ zEp8OI`@j2UT-)EZMWb>hTHHBW^@{iY%#BNUK5bHwd;jmXMH>5QjMsGT?^ z^i1uzsS~ws^@31F|GLT3YQ|3s-8nTQ^kmIrwfUjy3AN9J^7HdUQ|m&{)J>T(Q5&!_ zYsULR^^zU)zdfZrE*9kmSjPPdvVi9r$fdm4o%1eTjiQ}2;wGynrMTYm!oOOPB7xD0 zZlI88=y-2h@cf_OK}<=!84~_#cRc`OTw^wX#U!)<)f~WqLR3jngb~CQ;5C#FSASif zsndYVDMd1=vZ$toL0k9ybq$Q7x`B1vPT3bs}a9q3J21(Ro7-Cd>jI^l5At;XK#rbnqFRUzG_^K;Mh*?=ByP&rC`yx zd8!SBPXli*Ff>DMtknDMFJIq0he$PHC3TQ>N>*F=ot!OSGlMyK7pA(A4PQRqS-wzwOT8;=ir~_c2A+1a8Is%YnNmDs@pjlLvI76OP4jR!U;IX&}O zr!oB<;x{C)X424-!KEIF6W0(pBA7Qzr@1gNlO~>*X*0bdEobA}1N#o(L_bTV!)z`= z_}II!sxPt;BsKe1*K`c=EhpB2c_b(3bC5UN*vHw(E)*ag1lxrLy|SFn)2WdTnh zp9|N@mqF#2TV?GKv6a0qE&yaWL{gC;m1ff=B3RYzCO}$4B((X{V9h*&4O*tboB@(@ zrNcJkunNOkHCR-G#r$cJL0XZWrgYnemw_eXldVy=n%a}i3WAMoYy_kuz%lk09_UUoMxETZ6*S4giVb= zR8&bY$$SdiZ*#|G2>v#>VF4)4A5=+KIU-;{Xh5#Rk=b)VWkq5@zQuSIQ8rBZI6U2#mwX|q=iVq=XM}?hG1Jwo`czTi`}0Q_s3~Iq2^{L z^e_o{h4#MC{-^oL23$1Dv)e`A$g(^ zFb<9pic<*e-H#B^nrViblZ0}mpeY(wi5ZJ4%$r_X%zIvDr( z|A%Aw@mNS&cJMOB|!vip<5a?4v;e`46R=~1Y(Ge+7R#pX=Dhjdb^TQ6*$g9|mk)8sgx;e*+tH@6AYIj~Br znunKf%UoO;xpKp^DbBkcGtS!iTSx9-mVmf07i0h{*8!f2SAAg!r#$HS+k?4cjio*X=aA_v_2v%D zQfs{GLb8#pgwNyDG9O}IRqOCDxe!i?m9GI$WmLSb2ZZKqXvqDzL#^35aygx3h~F?+ zT&j&csPWk|No+K@>LpyP5se4Q4%#rs{_D#>@AhLkKXs7Gc6FbSWA8Z;OXqZ%%O|J) zf+YjgQfj8wrU#~54}I41ucLlM{T-vWQzpMR5^_o2N_Y(#clC**pDg$uM~B%;Ej4T# zw(nYkhSKQMYg99pN2!4j06|?HZ{#yP@fB`{tDGW1cLxD0?Aios^)O?I?%ez}uA^ozL)?dk-8p(E8PWO(Legsx*bqmGZ`g*rhzRN; zwvC1fmLOs>0fr{!WZ1m_B4#%ef@=%gNmA8{?dkh$l!a8;+iD~yjZF$mou2t4Tq z7@g-aW2}wP!d)jv^zJceXs^nFy4+sTM&QRb?ZzW$Q{K!qkfj7DEFy>k{hKk!vQZe@ z@?LVvXSo*04#=Xpatnl_!_X$7UD~dT9)d^)e2uiIirFm7svgBz&&AZ5oXK|n9L4h% zyChg0DRJtxt|SZJAj~GAH%5R!G~F2dSQ5TkxJC&kRp3=4;uls&wVy%o8B3vH{jZc` zdT1Mg8!!>YyT5CwAdQ@oAG&Sg_}b9m>CXxN(G!qQPj&5-M{CF9Ty0ggHPfd(7aCnN zscy0$4bZCL1TIxIQv~mziBoDrqo?73{{N5MW`ghD=}&~TAB_U7nf%Ce*rjNwHcI~~ zwKY!&4lFAO4XK+xwKm!b#;?cfd9kZ zdq!tfYyrb(&zxSL-dlPvq!R*!5FmsAp;rY$F9H`(5nJe?2%!iO5D*X$P^u6SF%%UQ zAvQojk;j>ehUQ&xTFqUu!&IL=ZqPG}B zxC7TcK|dp3$uV)4pBDh1xF3wM$6^>^H=qYLjh4+ z${MHwV)+?kC@LW@wE6}8t4!VPs+mve7Xp^DD;RD*MCr+>qfw(DZ~cl-E1#-J6rGpY z`xuY#QxF*glqCwpA0Zv#F8QeOLiy#|xrCVR{=qy1=vM-$e+Sg~xo+$6Fu0OEicnlB zvE@5L<2RejK`>G4YS*s_5OM9KH_YzEME;iEeV0;amfF z7GKSH5RP>N-NXy=+<`EAs`w&0p@_xFZJK-wzWhU&0gLz_P&`eEahMXCc&BZe69QNB zl>`t^Ec-azBp=V_Fu0!I0jQ`Mf;Jh@csO$6<8aUR@%tH+lt@EzLX-2*s{J~cXe|f% zQ%p3=6}T~yIAGJ781y^CC`b7lXfOg>0tJ@LpdGEx#GuW1B+TQr!WF4Y!2dM1Id=m$7sB)j}PbhfmQ<*rnw6eY}jVVO9(K z=+(k;w2WPYmaz9>8M_U?F7E<@L;ikY89R6hTegf%UBVicvDz{=WeMAL8T-T%b}rf? zzlUCzcN5ev3F?=m+B`yLCwZ0-lE2Zf3g6-->`c;g+#~k@9t9Xdjd3HS+wE zz%G!ozX+_M{15WXm6os#e;;7x;pv1u-;rl_{BCV8VcP-1zW<2x@H^!91;Wm22I_)m zKKXY(-Yv|>|KjH3f2x#@bwQbj-!_D>F0jiM%akw-IR(U4*`&+!6{f%BD+(gUS z&&acrJoC^}_Fu4^Jwl$>U@80ja(2*iw)Jw>yOgDtvw`JotEKEI*eX{O;2whX6?yKH zzt@n;$H{Yx5U3%9KP1nenBdUMiFQ68S2IhAjGs^D#d0z~=Hq+pQg#RFg+LutLnS%`S0QT`9eEkvfj7BZLlIqWHBA$E$-qih9=LT4KRmMS7dF2=U|a1se4LUB%V(L%fQ)iyxrNa1I%k)05}pci}n= zs6;zad8dJN^w8z#UtG`AIO;E$2}fwd0+hJ`J$no?eIF<4yy^$`!IGd`~-iI7Pg?@;Y;`fUWL=} z^w^<4;VtX}{5AbAJeU2IAZ&q~gvM*=JNkP(b}_s}@5Rf|F<1a^pmlH){e=$Tuh9Xt z63>M1QQSHd_zUQ7AoC{7hNqXogx_K40<;=-!b-FqeTP=#x6#Xlz)I4ySCEm5A&qza z7YNfqd>aCLA^rlCkF=02_F40@?pL7eY8a~taS53bPfTteWA}H+&dy~N%@|>{`mNY* zwZ~XBb35=d0{Lxh-Zf<<`1>?l2hP_3lcEljJLa~H8lojoar{t-V7#_OzI|n3S05@ci3oH+)H0KbMTKEWO@FqRwRWa!-8Z?vs z2%W_n(FgDjI!1^RX$_A++lihf?-$L*D`6+$=5F>hEMs~tU?%*G919ScDrwh%`V!Sa zr>7R6^na4cznVYr%-vC*Q!1uyZ=x_&yY=E>q(D5++h`^u8Z(B=V?G6~Z3Fg5m*aBC`qBsg; zH=t)%pl*jCY8OaVU|9qFEL1!Ll|Pki^JK(lm7jr!P?}uK6c`VIc>@R=z}DT--B%4= z9xoX${%Y?tb5WZYQPaTK#gvNRzlb&0S zMy0UDz zzP<6sU$dd&IGA=p2;^flh1O&Wi3Tepi2`l(D9DQ#9#m`hGzT^rZGag{P$WvQ#?gv} zLmW6&J4%ocB}O2cY+0qH2WcnAecTGb(GKctL~!ry^TEv?@Xc6UZBdna4p)p7r$IueOsudG#nlebV9a}kt7C6EjmQf^7Xh~oR2?Yy0rAmY=MxX?* z6oITRg_W>b<~WXZYn;K)f@}q&gb6y$2^_GBq*xd%@yMu9lw=en5ljkjoPZUCIHO<& zh7%}`mpE+Xu!va=D;&ci23SeJ0!7{xtqBU^1Vz?31yPKuFd*;(g)Oqrl}LFcu#1|i z*b->Y%z>4(EYO(620_I}MbW^@Gn^MW9d;}m%~)ccT8iK`gI(Z^JQ#Q$SR2h-I0r+K zc1brdYet$`qBu!Hf|)imTBMs11Vkwc=^xE;iVMlIP3Ud2XlAcVk(hWluf*E>8d)n7 zl`4vyhqpU~tdhJUo5&$|fOcS>p`&aGlAZChan9y#DYIYVdRY=|En^k4k&H$nqh&O= zKr1X}Wdmj1kqwNjay$|>MnH<3t&r9YE`wn6@v5;< zV>AQH$|kaYS|Mjk6C;ZmhBDTfXGe;~X5&l_+wcN2C#ilV+h?YgIH%Ua)hvY*QE}_y z5o&(GG&l!~vO-x6KA97F-pbRF@x^1j0m#X;V23!)T+mU)F45%cY4LDbnMSKcN)=Qu z3Nt6L;6qaSAax8^?G=&HoC@)XZtgOch zu~9TlQJjrP50Ro6k&6U2A`v5&5m`1_l`-Nu-UL7=suq=1Eix-x45ERzP@*bZc*KLr z=P)>EGDj6F;$)h}0h`GIhSXvcZL+8|%?cJ{I(fOAFHOkbBb&}VVD@IXCYK&@U zz3Kpy8O&-vng>PrVlc7U!GGk6SbXI;T7QVu910Q`Gger^rtx-&p;N>bWZK8Y zB&bft?xM?7hu~8j5s|!)^Q9G`!Nz!_C&rYW7vYPtg+g*3yI32Poz29^ZFT6+!$gMt zzsWfshs4XT8$;sd7Kj&N^J%oXj#XqcGIJWTQ)VJN1i=oRQ6VDOh^;1wZWut1PtR^MW=+X?$T6HWGED$i6Od=f{;?Sqt=Dq$#m7dhk zaH$S$JIrF)8fi3u%FrQx9NQ7%N1VwLlH15=5gN7xBVn4O2x0v^_2K@IfR7MOAJ(Be z@3a3inojHHt07wb#L~@2(cO1hzpC$EPE7+&Y9<(Ifk=FcEGSwA11*!vCf2}<0h*U- zgJ1%(PBoUyW*N)ap^!x{@_PIUo%CN`+cZ~1572M z39cF+7e(v;a}`lUB1?oe&9i!ZThRw(r2@;iz$Ro!J$aSqO*|cB{$%~E`{5ghf_-@h znKq#i1OD$7R92Rvk;)g*7JgbJuaaE>nan&(1QzGuWiEryQVL`f!^+WOcRP+YnW7D5 z9~iRIS&!Z3G)BmxNi!uSc|HC-mztd(m&Y4az92KXS*#F9W?hOeMKsGMTV|G>i%8G>_(ZX)!jaI8_c7Q9l6VptS1S9Ke)e>^GdGXslauX^P)3oq?~c;w!4Io%Jh=9r+6c&i@%hkF&j!8V+F!qPt4J07 z_dZ6K53yD{M(Bk4_!3NRHii+%{-2gI6B3-^puxvh&ke4>SkZp;6SSGkTYdpzTdHko zJCkJWWNpEPwZPq>r88C>7!pd1o72e5k+4zF$abz-C1;X={RyDOxZNU0k&PB{j6_Mi zpO#o6Wdue5AtFj5iUoXbOom8rq!1Q5`$Gs(qPpTVT2#l1 zyu^b<<9z%GHMnoRyWzFP;aN_Q-fA+-_y2eyJj+9Xzi0XGMK>RiS)MD#ho(oeV4+Od zWHxa``-}kv8Le)!U^jC_jn@|`gF-Xw!keM(hOD(U_2>uEAJLgqRqyNlMe-L+ulki}%p_yTGUR)VP!$hQ@oLd+UQJ)24~8 zNfRn2Oi39zeEjf9`sI(5%<)g8R7{vOZ1^ORYcqcM$RWdqh-!Ux{d@Iq*YB<0Rll!( zm*}oP{Q30HXMA2+f4F{6;Qs=Q)vuB~HG1-BJ&^2#@qr=3C+Qx`qn{Wua`>cYS_CE! zA0BvO$i!)nK`~^$U ztENZlV&*jW6I|ntz5_39Vv~151}{b!zV_?EC3BddPuYM~ zoD}Vo)hNHz_;Szw`s(z%q3b>a&ask*EPJ=NiL>IhpBvzJ22}D)d@RexH3T6FIu_m! z!ULjd!{Dug(c3Gkg*LWRpCSFa{-aN55*+xcfx`U(mv|~MnxYb-s74Cw9tPo7ky$?Q z>T0soTtVNm4WE3m;j~0_3ICajRm#ZMp;P8JFdJH0J75Jz`E%PDjbmGytubB0K^gB( zKfO$M<`e55-!Cylknw&RRw&|rVhGc zPM`5N=qS}vl0qhKwMsDAPINlA@VO%#houPfBrcYg$-`n9sh*GhqCf%iv= zT%&LD+*g+WvMuPWK7Vk%eAqQ3t6PGW>FBafo54Gg3KUf5mjPh%0|i_y4cMHFA==9{pvPdFLbXR zvhO996Dg6%IhOq5XaOX$FMvQdIwGvw6GTrEotuZ$FJxJ=qsWNoiApL8EHThI+$1aD zqfJ5Nd@*kA(5o-8-CA(SYBIYd#BfN#93gL!5av{?AVhHtM&2e7K|k8I@aooJV1zXl z#}~1*M?thNjupDbGh}xU`G814kM<9Ojrc|7&X6mMS-}`>77bCh#xM_C7B-CV;gBB| zvI4Okk<5xREn}WTlCEq>O}z3Sy%|I&v*6y4i<;xHz*twdD23k3qd9B!_d@3DhKe(a zOLN&-A^gUE4$lwkalN}lO>q`-$YKE6mdk_I=+Sa*PLOsFv%3Tl z1Nt_<_`QbqHw~>_$ohOvkJsyRH%4#Yvbv%DtwR?rV#8jskKU}DYu9U?8@hBUYX%f! zK@c1AvDRPnwa@fg)0Tsn`#-rZ_8T&E)RaKUkVzF2o}3g&36xE!m^@|pq(IL}Lna1_ zCk!2%9B9~kwD2E+c2g(n5!3$;(b(XeEvAIhT?gtnk?rW9p58A|zv}aupUdk(1bb2TfKKsayZ(+}K`ZfVXd`+V=eBF@_UeVY7w8{U8|_+5JR*p|~F?{#?L zC79A*z`-LvEbtI&MGdz6pmA zI9R#3i^CLP0>)^Fbod-0QTEe}#XAyp2eM!6m;AEPWumb`vCc^b>2-Pbf#<+cATA}D)7d>wvp9P*54{|SsAk&&OCRk#W&(TEp%w_gPl zD+W(n1=DJwlJt8Htbn_43BH2O(53fVumU}|iWD7(DQgJRR-i6xAazt~*_erC`Q_=o z1G9j>4Adtmstyt!K)XMo<0p`|5bT#x$5|+425R;dSWhwpfv-lcPrz4=$~HqzmRg0% zt08t9D!z+GeF246q3}NBU8JAVL;I2K?!vtHU##damOV`SDo2|RDLY{aypP7df;tR+ zesqV)#?QbzdL2B1n7CyyxzFUe@IE~K0rZ#-Pc9>CUnW<>3m9W#0Tyg|puVD-a!EPQ-DS zWC<8#v%ksp+qpN+{_9>S{9EK(ZksBoR!M9E|L#wnuv=6&#U71bLS{>LmzEV#UBV$& z_g(l|)x)#?nYcCWH*_5Y3vC-VAG!<-?`aR-AeHrt#hck^NF4a^wGdx_ z$+*!Rjm+N((`FOt6Xsj3&R4QBKFs_un>8C)*6QMw_;8#hIT-x(Exo=T|1I-kwgG`f zgK%iP;A`8mT?eO$5uaqO$UXz7QL818yc+0krZf+><%@M7)x#58v9~xJXnS>VG)bcG zc+QC&rnO+#%vQ;%+qIODlO(fS;S#WZ>oCZg1A6~R<9}wK&*igIc`hp)x+&;Cd~JWY zZ>w^a<~S%yzt`_>a_?~OYa#Kls$^Flq__a$$}wHgoJOwjg;9@Hmm-_PRH{2xWm7Us zQ33;v{C$7c>JWHW#~rx=K(T%bq8j=8(~2;E?{-|DqfC=a4YCP|;V`4?KG6H`7fowR zZ|4Ry-pp7zE={p(TsRfP*<(6Fwir39-<{m(b&%01J(ta-GTU086xy%&|wF-sH^vW3RlKkZsYYI{WCRG;Hns5EA6)27#L2{vsP#X|#*=9#h? zXPPqvSy`{oLn5{BRh-Ofr#T}YGe@YI(FxQ5lUI)8;wa4AcgrF9e^jcK+31E z5)J(e%|tK3_b?N+{0KdM6a9=*K11p&;CvO*p6=DW-{{lqoA^Gyz>IkhpFqp#H_{8zrzxl zE@egZ7T1!$V-W6>kNcvjRAYruk<@qvYs-)C?!T#ruo15-TYW;j=(7lo(7CG)hM@8x z?Y_@UgVhA#tns0!x+^vY!^hs~u*j7eSu!RoqQmHXhzMS#A+P7HSA(H@7Ij?ia>&+X zyJBk+bocaj0xc2q9(F$D9ny|5vu2ABOI4W4aDj7J=YTm@>QALg$<{=7y3t2AcX}2K z95XSmSmh1Kgw^mhvfwm0^0OX}nA0iM0pA$O_1fW|gWWsT^{BUur;|EyIJq%8&w=*{ z^f_^?J`3dN{rEC2K8fzY9q9ZOyn(i&#}~q&ThRaU8PHPt31-0&_yYfdR^ct!I<)yW zz-)o^r!PR{5*X0$GbnhGe+N#3_!v41g)y<-E(w-)<6FM~e2O7WZQ*PUuRvymm=AG9 z^g*;%Z+^>nJh2=czx1s1VTILH&V*!{G6||iD-6SgZte$jZ*BjpI(V<(Qm^aIVw!uZ z8Kr1+=)Rh$zokdDI)YbJxAw00Ns`FOHipLGz<2tch?Vbk42GKSy~8K_jH2SVaE)8Z z*~8>L6o|?7z1O-$V#0{Lpo+X^vRRBKyVYbg8%0UrWQF7O-v-TM5<*)A$_pkKB(<}| z=o7t0gmzxu9Spe?ni-dS-|$$75H(Zb)l8t2VV#|bo2G*9h;s4=s_u^sY8Cq9wyWS!V4m^H=9 zIhl1}$}W2Y)J!&l8bBsMLsl96X64F%ey~OlqGmYXr`B!I9HOH_lAVlmNa&h|KEy{G zLv!y+pHI9pXK+ZY)?@?Txq?8GMbFhf3%wpMLl|c=38Kp+dw48bl2pYT6NTT}Y zpY^!X@}7P(+$t;B6fD}C+{|55svi#5^*is1XQ^0*0@lw^q3RG^eXo@U!;kk{>$0&* zs+Ccj1TS3o#?QeN#ryj2a0^BQCz`_6Y48T__1Ul9Sfp?0o`e1Cd@6+$4-KjTVV?$+ z=*37-DB9cDmjhQiR>X^rQ~mdO91^eE1X`3C*%hU7MyD7~MrqQu_S4Hqvr(eu;DEbc zn_>&tRhrjCXM!G;u+i#&^kc{1CC>pjJmFjjvujS@4JFSTaNOmis8}}zO)k}3dnZJ; za^P*RWV9)~Eb*c#!p2E1tud|2>02FjcHS9K?}|r|74vs!kf2KRdTB6L*uc#$3s8us zC<~|GT0s!H`WTePkG7VQ&CqdT;4Uvs8&$JA)~%;B6je>ej5!p^z^b!%=g%FdnMGsS z@TZ1P8a;GuDD9XY^7c=q{KD3^-dGM5UxD}u)I=^fJ*#9>E%+q`8h8iXBu0S zmKr|fORLBfV@?<^#(s*vhj(E3Y-sZ}JpC<<9n$d%ytnujweRMl@= zg7o{Y`{|3K=t4c2Q7IoHt&0};7Lq%8S_VRd?|<{|$5(aTMp*;Pjq@S*I(m8rdL{(i zqLOv&S;fvV#!+6rMQU!AU^4S=^o+ZWl!7M93LC<^{B@9sO_Yyw>&?$wUW4w7VN`f; z)C0pCFY#YkB*QCEx&U&zDXRg8fQv=FQZ;+Ys$}MloD1KD`E-`o?+Bh^F9yaA3zh6l ztZ<2jZR{$o%O$cE?m-n>p|CuB@GMstMeaj(pLx>#FoB&kG2^5|a(z^e~4(k zE^dqu)wTZAl#=G2Y&OQ*y5oCcU^PcJQ~wO}oS1P3p!Y|RJP*5G!`?sO63d*#+UTZ8wIA2_Z?#-`?_7smGYSxg2S?*X6SNeNqj^}h#M+FVSkbk9i~^&N;35#l(O zwqc8~1}#B*&6#jyW>BIU<7@6*Q@3qq5Pmq~j!{)qSurS0!WGtBYp8!b;<^+tsvf_gsno9f zF$j+oEw>{Mswh_)!e;Vrli%Y`bWY0*C-6SAde3E4ks(IwIC2|P%!ol*ZD}L2%FSd& zW(*W7QmWwNWQo=ThX-%heIBfnFDBQ-{o;9gH#~b2GJ7QTiW!hOviX3?>%iGU$z)Qf z*5cEK0d!|3Ep0Dwox*vqP6zAiSDhobNiM|@aH^WWNw~3_!9IJ4$r$;I+&*DUGa@22 z(_`VNSYI~O{w3<6XkvJik>#4khhG0`m?L+iK9r+_v4wDxL>RTJ8{qe&4vXbpIl8k) ziD(SByM99hd`9#(N%fgH#cSjn>t9~e0N)>dMs#qF0=sB$*?3xdIaI$A#7Xy}*NUb* zS@o!SVhKHpN~PoZWS5T*P{pxm0o;V3`b z{$^;iTW$j&RYRaODro24Y=AG%y5!_BEpjv#8dE8q+a83+iQbDj_wD7kaBu%sFy(lP zTm|LZ=#I&L?HKgg9{zxGU8tB2;?swV_L!SL&t*c(+?n8g2Y9EAvGG1CKBj#{YFuot zsRuPkOp0k{Zx%BXEV)vYwI9{i-9m~(Z7nT&cijhjq33`cX<$lf!nCd#TC6cAVO+~O zMBf$`fvZG_<>JkSOctBRWvM>o5Nz5QB~?i_hx$+>6XWn_v3%oKzuXIj0`}bC+?r~4 z86-zYXTib!BSrL=tzd{cz#GDVO+(ecYmKYo5-6%i zB4JDug8E=dnD+I4(_7!w8ih~VCaVv&}cb^jlo{; z*eGv=*3r;t0iC^6v*%{;Wj;XHS$i-!Y&h+0@I1Xn(P1<2K2|{>$(U9fwW-Qr$fN!E zFdId5)M$|jB^JTquuXbOT6~=q5SB27iCAU>jj6d$uzKBx_&DzbAU+R-@8rCDa~&b(>57#!*>(1;z8xo?WmH3VSAxGSz}k z4w*CACEnO1%HMahF&V0Qv3LiEiULLEE>@2-eAu$}!fYH&r%`;LR+YX&nW5O%NV)EP zy$8gMSkvw*m+a?JJL*dhy+M zZ}EQ@f3hH0tdFSlGPIw8*cv2TWSLmZ^rEI$_7AN7tTvcNMXV zwRF>_^L#oYV799Q#x5&M_(mRq7rmkBCy2o$65j-~a8`G|70xO1pVhy8a##0Au^jGP zOBYIsqRB_4o3p$&H^T^ey17smgdfiZJAR|{Lpqh`5>o^|uJNR*Y6~GtjERL^=3o{y zZ?fGG2p9#UO|ry}%n?FE)Pk9V^|&d-#5>+)JA=3TlMp~ARixg zy$fMJE(`LJm|y40=iv0Qnm{oU#w;7m7L)N{tpUC?EkO|%5_84n#Y zzG<+JY175>pQ;ztj3;l!M%|G{EP=#+_Ff*|QjWVsR3zp13VjUa+6Sd?xmdI-j+&S} zs;IrE3tuLzMI+NuvKsI5MVk`KSJCPzu%rfJ6CLGpZ@RmyB)uRnvBZ*Z=pq_a)x`V! z={-buC^PK(Wk+jYMiptI_h4!bSOgn(pmLuJY@DjQE6b9H@u&^4R)e?pKln_qKva|y zsSm-UL{oWOfn4ec`4C+`5rpcI;+q|Y2)0d0+*C6g4qN$I5T>WMNZ*e&#Ks$diEBK7 zS^sGe9wXX6Oux^;SfsFIcF3Hpu|_cZkAyYc%U7-*emNMg_*Szys7*Nh(xZ32ymTzM z@vq7JP-szVFAs~B)3fSc)y3ue+u4Ws!Qs-H{Xx29F|n|CMlnw8AsIh_8VCk* z&26n4EY-o$lE%-suaUE2LanS^-%$Fn{eC&wA1bY!abownVCjkuH>AF8!`)x-+oe$V z_jFh!XGDejIk%y-zQdls>DJ5&QXstjq2nysA7wOz%ImN0-V-XHReDk4SfN>%VHbks zgvx`CS0paXn#)&$rHP{BROv&>iWQBrs+tL#SkXk86oc-OVGHkgwRH^?u9j|+n6&Un zs)N1LEr!xHG9{RZ?x8`Wy0!J}dq+YuV|k~glJ1}oj4N}wq1}_6E=n2}1WMs0l~Gw% zCc3@IG;Q~IL%WAM&5@|^_^Z!1P^d0jPNcCQA)_c6Kqk@_R5C+RBZYHE8*tZ@?UFQ* zBue8I16EmHZ%yVxtpzoMs*f64TV8fuMB#Yi>(2#C(?wrx*=5NGl*gn;SyV&{65T+V z;(&5$Mm_PRPRF71`}bgtNYU_B*(@nvW-KO}adp)6bj-GJ1kd%S8roXa`Gm-3h6Ck% z6)Yv%#qG|kWXetG`}CmiU4uQ;p^8z4Dr71$3=7PHoH>xu z+ffO&S%^Ido((9Y8sGsWeTclJFdyiXI%#SKC~F{Q7G(bb{SHCDqcGtVtb-R?j53en zheaNR@joDp<6Q`sr5lEi|7Vkc-vrgpmr5{ zOmdIF+dwXsy1VZ}+j3^GTpB$GRl}4(4YObATG>n*;e%N`@tl zq7(5j%VBWUL+lLjl)DD!#}-BBpF!*KBG84-TBwH^@D^0T;9&)2mLjp7+XT!aM4boQ zTabDiJl%bH&#i~!=s0d)3FB_T9r`L4a#huLr33$cYyStmHT`V8rswdFcBPc?44SqS9CKAv826ZQ{7ENJ|&-6*!MBLvlSDb&1qB^&cJi zCR9Vq9T1p0q6YBPtTAy_#5|pnWtj!u{?QXVE(c%5J~)S@U+8vIUnS%FNB^$slQEsR z$!B2!k`~|=*%4jir$f}Iko*%+o#H!34e!ylV~Keqw6t}b*wwTEx+b*mJ`0|oM)&X5 zrKlQ;;^GbVi7C^Dqz!uPAIiU>?Z04jR7Wi|M(0sRudpp{^G6ZIUo6*fVE zBiZkaIshACCj5@5-(ghS%fQ!y8DAr1ztgP`(57o>2E31I;1L;ChZ(?Em}WuiD$q_q z-#HLHA6YMhVJ#Y8iC!4iozL*7g*du>dqWXbY@0%MbVtvktc?5&K7J!uZ$hhos2!DF z&Em3K(67Lt4wIjGb_qPT4x-ipAYbaR^qvFr%6wBav5RL!hNTpzGkGqyRA?3B=&Trh zhJvKT*2)6#bha)5oI)mht6`<9ptP@HA!JR9Y~^Z&(i2Nk+h-xqavPqB34dU2-UEhP95U~@6IBvsosDrd! zXc?TL1BdZ)<}O^ut-hic!$o=}zQu0g*3;jhJ7_1q1HaMbbNThy$<1K+6ZBbFORvM{ z=-=6;>^gcq{faQ3{U;P(Lkr* z-jHbt1+nv; zfGBw#V%~*jPtJztlU|3yPTg|N{dU2)VYN_x2i-@beDuK1+7b91eujS&hIjmuOvAQ4 z9vd?JO&B={&xicw`kEiP9?~*9ZGku7Kj43c{zn>}lApK&M(lxBHPEN!Gaa6P=CKZ) zhnhzAm+}h}g_w0P)V}~SADb{6+8u+IFyvMA1{^~JeuN1Nz}!4zg77mu(_<)EB9DM9 z+sxUJv<&24!ZV)MLcf3X6ZxJU%rC)!Hvl5rmsM0j`h6%o1Kp>LuUG_*I(YF8q$Na- zE|~|}Z$Q63Z$h7AkgyKuDbZyaOu4^*FZNx??J!^-d<)N{bz^P$S%dAvnwh)uafOe0 zpD@1yzLn5yB|LGAXv6EE^Xp)L8>p`0Na2XyUFTzJYuO+9T#A8U$a+S-r^x44o zGmcDaliGFobP$YbuR+F3F!ciDMs(}!=Z-=-4w* zEzHeY^sp*6Z(-}4=I*q}7McC}&4!k87rHDhav2b=+6M)epotg2+f{yAehoT5^EN#F zD@t3248OuZ*1=;pq1|bueFK^0-i5kQPm_B2Cp(mMw*A28#v~T??9YtY0Tp}5I@!Yv z9X|Xu7(N%ZG%i5j;$}y{st34ua_Dq2b(R5_Y|Mz^24&`&yT!f&c?-a0Ni-IC#EfQL z>{HURXhShOF|7uyH9%H$-V4sen2C4>yv!^^n+dD>Z-;eXa$-Fy?YcsmI{Ssf$=qvS`S^;qhFw}bu0V@gX^Hh3{qh&*e^ondLqth zk)!*Ru07|WiCf?}P_rQZB(&HE-5q0|-UDZ0GZB^PgWdx2KA!XR{KtC0`=I|Jl(`;v zzJ&tEVGP++Tg*XYFTv!uAbu;^Jx<|eP=yx|$vEIw_=s#cAHf_Ldj>_{fUnRgv=v{6 zeav;Z&Mw6d=!wgjg5`8cHS-l-j!SA`^lBoNzJ#;rUHB9}MaM|xzesogjp*ID8cw51 zcoo_I4Xs~Ar(;Pl#~5~wsK zn~K6oZokuLx7)ML?X-3prNmO{#yn@Nm`A1CGh); z9Cxx1ABd-8J#1n`YMaQ%pjj+a9OzpyFtrH!Y7>(lXCE(0ea@QIHhn_>;o~!(ODxLh z+kHKn*0(r*29OOc(zbQ%4XYsr{AMjhvq$1cKFgt|`}MmB^rM(BgZE8uU;EcDf9ao# zqOP<%m2DaAiAz+9Q949MWsJ>9=-I4$LTod69`IIAQcg_hv|{i2S+Cun9=ufbMadWW zoyLR=s0H&k1dIKme6^&uxe%SN@=>`;RW? zmfp*W8s(oFF)noGar57yHd96atS+~6(_Uyfrq5Gxz9_K`W#z2~#iXTDscLfXh2hVU zGw;l5XzNO+D=nJE_MVav(`$05E&WvI=9cfzAD^XLnC8P}C-W^Ca!GL&h&f>4Op+l) z5yAmrjFP74cdV%>-fOaYLYVKq`Zwn0t{Yl;TT*V;t2#%` zgZQ0boDJR~as5KfJ9cNot|K#p%zM!Fb{^F&e9dc3hydyDtnM`hZbNJeuQc@4d6X z5-Re==v6(cnoF#L6#XWKLTRida{3Ktnbz;2AQh{en4zcKaff{tw(op--)A$RqQBT_ zbB{ZD3t1v7BEEvO{oGBMqE(>Y;?%$%H0mylIf&N73Zn8HLY1ihi1>n@ z`MLDv5Ispg2-FP_SAad+6kMe;{|IDK!9NQK`XfNiT>U%HWWU;9Z z)cUT@CK{&s_CQXut#3w#+SjxXvYspK zo%4A64Mf$9H+bmKoB4HZ=>5itmV*_uvI3eZ(r>_=Kyw<8!<>-yBbki{erZ6guQ*8% zEd-I_I9kv|hT$3!_wN52@kT{eb~HuBMp2X?P?TAu!ZA{1eMlGf{*8FA;&65>1@R$7 zWag=G)Y#yi!ezS~m@JNw& zz5QB!a7_7P(%M>BDACOw32diISOC7}rO$RB9^W=^cuC75XCYmX*tZ6H_ip7|tH&P- z3bZp<-qsgrvgo~02bG+|VJL)vJw3B5X^inHrMPwB^JSw0ddd?W`@;DUHd&4L--jA0 zKu5Yp>;l%O-yG5rmc15QMJb|h*D;u(CcF$n4{Ac{G2lizJIC#YC~q!w3v>uCj!(}8 z=}qHBcJh;xo*Mqlw0lDNmfb=3CyOX;qOZaM7L?g9u7NZLd{vwz8t8_Z1U1=Z55w;2JNI2Wouhx>zb#P2c;rh1)50Ds-v-HAMShi~hM3&v z!*}sc2P@b``lw}Xat5x1C-OlLleF#JtQ%`1bifyuIs$m&O$Y(@oCyN-EaslONM(?y z(9k54T+QzdW54e?iFljJa8{*B7J?IhG{EeXx6HfE--F}_fq|&y;IoKMV=&;2k zSQ{_L?b;k98Y^0EC7uE)Qox+cBl2bsFUO>WzR=0~XZHGILA*%Oa4GRBVq_c7nPgV> z`a_D79E|q=(f!ag5&leCMQmXdQP9MPe(TSdZj=PGmZzLxI9DXkI{i(O_0;|GAH8y- z=-82Rm{D?^4Ck=0*pzRub+R&lr&bbm7VZk+>UR=T??ciIaIOdKOoPLI@XY-;y)nXy z9jQ0i*f1*&{O4!Fib&CNKlM1MNj7t$sXzU=npo(|7c#btA7|?MIWZEMcN1`Q(o|wgnfjjH`J|7Tf=aX9-fbKGmUkxUwRaJe}+TNzCzsN zL^+Ob8;HqpP7FKH%xb8ACjBBNJ2*vYT9cck^=m2@hbGR7X0^U1>t@xy;KZ?t+{27N z*|p4g)4)G+Ha-=aGd2sFerqrYs zb~(<_Dxw%A-HuC^HaYNF#H^>)5#JnH^YqZh7a&>=_j%9jt>AIezZmo&WM65ycvWA@$+n!8Lj=(J%KAAeL5?Gc#jd#F63QQeoG6w(o#9LHA+A-6MOCjh5DG zgZ<--ihBR(YaRu{VlZIZpvQnRz2Cj`4`2u}uyKZc+l&XT+SfqYy~H)lh1f)4_`SaZN~(K| zu_xYj5zgER{sdOS`M@M~LS;lzHW6nsCSlU5R9!CzV1%3&9pr{L{etYEov;Cx6E@&a z|39|=H`vls*divbe|Xa$cB}`E&Ch9Wo%$wx7+gaR7wgSjCYO#$Azz9U{^`9BzlRPL z+Qfb2>Gm)vuYU*r0ciG>VY$WtwJz8B^O56kJAMmghxw+$N61fsz|sPVH4jJSSPjYx zV!>j)TzMMuAL= zF%HgzFu4er+kjp-^$;j1sSel4*Ro@*Rxq?HJBzQ@NB;2w{o}9t1%WaX72wU4qgL_uBz>ww1Qai4|hZq$%gF9-yK`sb` z?3gYU-KM?*8g6eGbZzH)qfU2C6w#N$uo1${ZWNl}V(c;tou zq-(V(=kk=RQxDIV+fubwC|f+!lkjA+JzV&9TWYhcS6Vb#K=^+_$UMI{Uvl9d z#5NAlM6HhJ-4%55Z)vCVbB3le!2F!*PFIozRV6k^~%Q7q(0IQDLN~f8WOTpm9`(!liqK%Du`EA0ZB?0Km0L` z%0otbQ5lgs!Ed;&8i;B#+l%VpCPzj)ad^q%&vKlmj+!0jM1kvdv&bfIEktJ`7oKs4 z>d3J6S<}aMXX{foH;31|kO~w(>Fbb{2CE^`U=19579?hIw*j4%d9io3K|Bm5#iZnJ zI{UBmu=aQ^nOCO*kgWapw$!kedRJSiVI69HvL!jJW4?JZB1oGDRMLKnaOZOIV`m-m zk;jR8X z602J*r`cR4$7APVmy}`nD*q-7H+W7nQ3l?z?buWQc8mbo)&8B*GEkPZYGyq+Kj^;E4|ms%r-0lf6*GiP6RT{xGKyGfW!m-8vh+aH#Ex7qLJN}<|F0gE>X z5M*W%K4{u}!RK0j(?=PYmw-fmJS#i+yYIN|;_AofLzEK_ljB)7lWB4OoS&X`GCiY< z^w+G0Sd)wE8zZoe=o_Kc+ z+taw-&Ta&8Kt*GajAV4&AO7GBD~6P#>{Jk~23_+#y&ZAJ-36{K>*xE^EgWT==pF?8 zbx%nACfS0M*=X_Sog3VVeaS9l@(7|LL4fj%nf)hw{)IcpMdn#{6JQjXR|%P;IJu!4 z68dIX!w=s&(+DDA4|l8O#s678U*^i^-R~VJ?xUUCM^*r;tehgVQV4ys>t9LS9^vLe z3lg#yqzvDaxILX}`v})V2}gA`6w$IgT7O8jeVjWEC2yWBdvdLeiul}4r)`HKbEj#G z*NeT#NV=mE4t`(T<6@^0MVIlLD1nv;$%)uzQ&CEk85znzq$!0cW`&G}^!)U2XY+Gm z2tqpyfR))~pPX|BltB6lemfb22sff3iRPu0JH0!s%WpbuIFxD+A=j8WQp0BQl5SwcY7WvYS5&@(>%%<+(_fqxo@Xli+T4@;&kd6wMX+ ztWCK5ixjk-pIQK5JRgEs*6N;cpm+tAq8${`HAKLgU=}rbZl~Kd9^@*th?IcRHQLBD zgDcXzyOZT%PB;6Ul2~#26peV}wJ+Pm#$KrM1p76uRLk+SE;+^b{mUeb$&|Z+WusVn=6w!YpjD&Ps&biNBV1% zc^pK2>9SW^Fxz4G6dyaj?vW+QvWv_;FkSZePPYXcacyQR%<(8jY80=!Z6uKKwfQA= z|KCAbDM$A)`tUar4R*#P`lU}d2VI%cYJwgimFI4)+YxSZzqK29G{-^09qg0tcdT~o zwZ4NI5G0@>EE4GqQh_PRe3qGG=jpjl*)kM7WSs)KCPTj;>Y8c+mSP!}RTW-wA_U^{ zs_Vk=@43l7nML+TP`WiU!cUIj5yp|a&TfT5SYyQy12{~}GYQdJPP=P_`&wr215m&U zJTMs+Ar*@%lt!?M02m{gAKuaS_nme7(h;@HJ_wVx+DlLTq2pWker%_`o(w~fV?xO4 z1c+ZnLW>84PlixRnoGLQAdl^FvS*ec|6%(qfILHb{Srl}3PXrKi@vrf$t^0mi-C8g_Z$#NR)7NHMNFs| zM9P>@Wo?DFpVH{w=AD;L_qz7Q3AaTsq8Co8M(1oYBO)I-ssWJmy4Bs}!TmgF`(?Arjt3{**i2-5^K zEspi!Wevy#^d#r)P`1uaw|pGQU;3H=m<_5S^)RTx3e_OoV%W9HKKr7345CPE@*e^r zf{2F+BIeq}l8jqo?Ur zSgcWUE7%8M-5&CYO_3WK5Sd(2rXKV4NztXnPwzN z@<0%?XzAj|=Q}|$wX2Un4YG)mo!e+p$$r@RX32c#MpWtF0c8XjEV%JdN~ex=qp~bZ z7P$T_R0+}KWdrhtm=%lYgFno7F6-INU0Dnez8-KHh@)UoFbrt31dcVw^FM zS7UlPQy8i5U3wK8fkv3?1AF)@q%uWh+|6N@xC{I4iKC0}cihttNG(9rSw_&ftlQOh zmsd9yBL6aFHYwC}CrcyU>l20?FR054R!4K>Fy$t1Zpd?-;g@@zc1}pEfl8vN@?TGV zYaXw5LIdqrRzpwJqeiH5Iv@?`mz8&Y@0+t9Y8;LFY?3bmo)<9NV+kvOX#j&y8gCMW z)RiDqKY_8unWjS*4Bd5r2b${h=$gl4nVR7h++9ofTwCw2jysb}AhT882nf-_n;IW_ z=)_H=Q@OnzGl*|qsCGOVn&h2$c`DtU&|8+TS^A65`MOTto%%{n-10>F>ql~D>MJ#I z$K&o-Ok3KNBS2&ztuvv4J|1~kl2I56`Rd>#M^bS_<#*qj+j4)S4{-;T8AJ;p{Ta%z z_?Zjq$GT}Wl>;!3B5QL2)!hvS;!4SDmj46SEJeY2YAeJz!EzYkkugOOSb<R(7 zPR0&#Hq9r0bcz=s?@o0osW6fTX@Nu`nZaCw6jh}t6Zhcr4fCDgv;`})^MK1mm~WJD zd`XmHJbs2PFi6t2NXT0x=`CbYF`L}|hNB^`dH6Fo+QngQ8>y0PAj&dcy!d$%#d$*< zZ5a%on>nwqEx@IneB#DB@|rGPJglrxikuZra{igm=O+D~^z{&vAb%*GU(?-0-~4=p z!e@p$t1rdm`uC$KlD3$M3(oFbysfyg0!3O4qOM}B(Sv{>T4X^=pT~uQbl2`02{oZ@2%`=d{vp{K`uZoK8Sd2Sf=+z!E1aLnQ=Ve1zkX zhiM+~$n`(`X+Oqr6z^(d3k(XjPKG_4M}ncO883EctR6HjVM?wdpejh?sVph*^1{y? zmr-f8bqGGt4k%G%?kBFG#L2?_(tkeP`KjZVXS7%kGBQP)d4?H_Ac5x1B!j119jo(k zJeqP8K45(fI5zBOMUJ5AAzt(cYV@-UUs-m~nFlcntqB{Ki*-#6Jlh22gtNQBXQ|HW(l2-feXC4LAQU zV+OgAnbyMRlODx!q^&?Ff_ang|NUApWnSNh{XH;SVBHLt3xDY7c?WvxZELPPKr)XLBFCU!BcYt5_ zTx#>WEh5dz3i$f&S1#~U&sDa_a1xfo)XbgdnlD}8m%Z9-krxC(6j4Tn`{YatxYQO! zQNmz3Lq$G0oA12fU+mRta~xuMfn^{T&N2nw{W`y~zg{zM@Irew2t(=jA#-F4c`Ics zXTJip`5pP7Hs-e>fF6vJUY?+X<(OXeP^GRWas!_SRJ05S=8})7_|;8tN)c%pW#r%;JW z4RO)9bw&sfc92Nj6S&my-M1cd0%zDSj+<)>0#=idU_+e|btk`ZR`Uuli`hTHHJt??u7njRft=mV0pn6)4(1;TKJWBG4s@$83nF zd7id_Cek`(G8|$uZuOtPksQ#fo4z!Al0>)%l^(9!UPp3~&fof-+zm|N9tC*=yvxCm ze}Qel!(@i_!RE&tUZH>8*edaZV?z@0{HP~f9Iv@PQ|8?zudhw6)<=`i$s-9NYZE

t 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≪a^&vxK%e`ym32bJ(SpJ4mRdh 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 literal 0 HcmV?d00001 diff --git a/tests/update.TestCase b/tests/update.TestCase index 30a93f1f..3dfd0f57 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -18,6 +18,7 @@ import yaml import zipfile import textwrap from binascii import unhexlify +from datetime import datetime from distutils.version import LooseVersion from testcommon import TmpCwd @@ -57,6 +58,12 @@ DONATION_FIELDS = ( ) +class Options: + allow_disabled_algorithms = False + clean = False + rename_apks = False + + class UpdateTest(unittest.TestCase): '''fdroid update''' @@ -452,6 +459,56 @@ class UpdateTest(unittest.TestCase): reset = fdroidserver.update.get_cache() self.assertEqual(2, len(reset)) + def test_scan_repo_files(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.update.config = config + + testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir) + os.chdir(testdir) + os.mkdir('repo') + os.mkdir('stats') + with open(os.path.join('stats', 'known_apks.txt'), 'w') as fp: + fp.write('se.manyver_30.apk se.manyver 2018-10-10\n') + filename = 'Virgin-islands-british_centralamerica_2.obf.zip' + shutil.copy(os.path.join(self.basedir, filename), 'repo') + knownapks = fdroidserver.common.KnownApks() + files, fcachechanged = fdroidserver.update.scan_repo_files(dict(), 'repo', knownapks, False) + knownapks.writeifchanged() + self.assertTrue(fcachechanged) + + info = files[0] + self.assertEqual(filename, info['apkName']) + self.assertEqual(datetime, type(info['added'])) + self.assertEqual(os.path.getsize(os.path.join('repo', filename)), info['size']) + self.assertEqual('402ee0799d5da535276b5a3672fb049d6df3e1727cfb35369c8962c4a42cac3d', + info['packageName']) + + def test_read_added_date_from_all_apks(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.update.config = config + fdroidserver.update.options = Options + os.chdir(os.path.join(localmodule, 'tests')) + apps = fdroidserver.metadata.read_metadata() + knownapks = fdroidserver.common.KnownApks() + apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks) + fdroidserver.update.read_added_date_from_all_apks(apps, apks) + + def test_apply_info_from_latest_apk(self): + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.update.config = config + fdroidserver.update.options = Options + os.chdir(os.path.join(localmodule, 'tests')) + apps = fdroidserver.metadata.read_metadata() + knownapks = fdroidserver.common.KnownApks() + apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks) + fdroidserver.update.apply_info_from_latest_apk(apps, apks) + def test_scan_apk(self): config = dict() fdroidserver.common.fill_config_defaults(config) @@ -599,6 +656,7 @@ class UpdateTest(unittest.TestCase): _, apk, cachechanged = fdroidserver.update.process_apk({}, apkName, 'repo', knownapks, False) # Don't care about the date added to the repo and relative apkName + self.assertEqual(datetime, type(apk['added'])) del apk['added'] del apk['apkName'] From d530733290a7fe2a9ac11be6ec9b6ae600390d0e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 11 Nov 2020 14:46:15 +0100 Subject: [PATCH 0615/2775] fix stacktrace crash when env vars are badly set in config.yml This was trying to delete from a dict that was being iterated through. Python doesn't like that! --- fdroidserver/common.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index aa522da3..06970d1f 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -388,6 +388,7 @@ def read_config(opts): limit = config['git_mirror_size_limit'] config['git_mirror_size_limit'] = parse_human_readable_size(limit) + confignames_to_delete = set() for configname, dictvalue in config.items(): if configname == 'java_paths': new = dict() @@ -403,14 +404,17 @@ def read_config(opts): if env: config[configname] = env else: - del(config[configname]) + confignames_to_delete.add(configname) logging.error(_('Environment variable {var} from {configname} is not set!') .format(var=k, configname=configname)) else: - del(config[configname]) + confignames_to_delete.add(configname) logging.error(_('Unknown entry {key} in {configname}') .format(key=k, configname=configname)) + for configname in confignames_to_delete: + del(config[configname]) + return config From d44f35bd2568763328c29443eb7f06703cb3ca15 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Wed, 25 Nov 2020 14:11:46 +0100 Subject: [PATCH 0616/2775] Add missing test apk --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 9f0d5f5d..175901c5 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -603,6 +603,7 @@ include tests/metadata-rewrite-yml/fake.ota.update.yml include tests/metadata-rewrite-yml/org.fdroid.fdroid.yml include tests/metadata/souch.smsbypass.yml include tests/metadata.TestCase +include tests/minimal_targetsdk_30_unsigned.apk include tests/openssl-version-check-test.py include tests/org.bitbucket.tickytacky.mirrormirror_1.apk include tests/org.bitbucket.tickytacky.mirrormirror_2.apk From 277994b31d574ea0b5bea9e88af1bc208f2c4de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Wed, 25 Nov 2020 17:40:46 +0100 Subject: [PATCH 0617/2775] =?UTF-8?q?Translated=20using=20Weblate:=20Turki?= =?UTF-8?q?sh=20(tr)=20by=20O=C4=9Fuz=20Ersen=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (573 of 573 strings) Co-authored-by: Oğuz Ersen Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/tr/ Translation: F-Droid/F-Droid Server --- locale/tr/LC_MESSAGES/fdroidserver.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index c004df9f..6647b393 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-08 06:06+0000\n" +"PO-Revision-Date: 2020-10-22 17:26+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" "Language: tr\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.3.1\n" #: ../fdroidserver/common.py msgid "" @@ -670,7 +670,7 @@ msgstr "İnşa sonrası APKları dinamik olarak tara" #: ../fdroidserver/__main__.py msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" -msgstr "" +msgstr "HATA: \"server\" alt komutu kaldırıldı, \"deploy\" kullanın!" #: ../fdroidserver/mirror.py msgid "" @@ -1282,7 +1282,7 @@ msgstr "OBB'ın packagename değeri desteklenen APK ile eşleşmiyor:" #: ../fdroidserver/deploy.py msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" -msgstr "" +msgstr "Çevrim dışı makine, `fdroid deploy` komutuna kadar git yansı oluşturma atlanıyor" #: ../fdroidserver/common.py #, python-brace-format @@ -2454,7 +2454,7 @@ msgstr "güvensiz http bağlantısı ile indirmeyi reddet (https kullanın veya #: ../fdroidserver/index.py #, python-format msgid "repo_icon %s does not exist, generating placeholder." -msgstr "" +msgstr "repo_icon %s mevcut değil, yer tutucu oluşturuyor." #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." @@ -2559,7 +2559,7 @@ msgstr "virustotal.com hızı sınırlıyor, yeniden deneme bekleniyor..." #: ../fdroidserver/update.py msgid "wiki support is deprecated and will be removed in the next release!" -msgstr "" +msgstr "wiki desteği kullanımdan kaldırıldı ve bir sonraki sürümde kaldırılacak!" #: ../fdroidserver/publish.py #, python-brace-format From b660f32bf5859ab4df86c121c71fb1ed3b3308e9 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Wed, 25 Nov 2020 17:40:47 +0100 Subject: [PATCH 0618/2775] Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk Currently translated at 100.0% (573 of 573 strings) Co-authored-by: Ihor Hordiichuk Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/uk/ Translation: F-Droid/F-Droid Server --- locale/uk/LC_MESSAGES/fdroidserver.po | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index c714d9ad..e6c4460a 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -2,20 +2,21 @@ # Copyright (C) YEAR Free Software Foundation, Inc. # Hans-Christoph Steiner , 2020. # ihor_ck , 2020. +# Ihor Hordiichuk , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-08 06:06+0000\n" -"Last-Translator: ihor_ck \n" +"PO-Revision-Date: 2020-10-22 17:26+0000\n" +"Last-Translator: Ihor Hordiichuk \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.3.1\n" #: ../fdroidserver/common.py msgid "" @@ -673,7 +674,7 @@ msgstr "Динамічно сканувати створення білдово #: ../fdroidserver/__main__.py msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" -msgstr "" +msgstr "ПОМИЛКА: Підкоманду \"server\" вилучено, використовуйте \"deploy\"!" #: ../fdroidserver/mirror.py msgid "" @@ -1285,7 +1286,7 @@ msgstr "Назва пакунку OBB не відповідає підтриму #: ../fdroidserver/deploy.py msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" -msgstr "" +msgstr "Автономна машина, пропускання генерації дзеркал git до `fdroid deploy`" #: ../fdroidserver/common.py #, python-brace-format @@ -2460,7 +2461,7 @@ msgstr "відмовитись від завантаження через нез #: ../fdroidserver/index.py #, python-format msgid "repo_icon %s does not exist, generating placeholder." -msgstr "" +msgstr "repo_icon %s не існує, створення заповнювача." #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." @@ -2565,7 +2566,7 @@ msgstr "virustotal.com обмежує швидкість, очікування #: ../fdroidserver/update.py msgid "wiki support is deprecated and will be removed in the next release!" -msgstr "" +msgstr "підтримка wiki застаріла і буде вилучена у наступному випуску!" #: ../fdroidserver/publish.py #, python-brace-format From 9b0537514e197d99f1040c8488f4bc8e71a2cfda Mon Sep 17 00:00:00 2001 From: ssantos Date: Wed, 25 Nov 2020 17:40:47 +0100 Subject: [PATCH 0619/2775] Translated using Weblate: Portuguese (pt) by ssantos Currently translated at 100.0% (573 of 573 strings) Translated using Weblate: Portuguese (Portugal) (pt_PT) by ssantos Currently translated at 100.0% (573 of 573 strings) Co-authored-by: ssantos Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_PT/ Translation: F-Droid/F-Droid Server --- locale/pt/LC_MESSAGES/fdroidserver.po | 12 ++++++------ locale/pt_PT/LC_MESSAGES/fdroidserver.po | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/locale/pt/LC_MESSAGES/fdroidserver.po b/locale/pt/LC_MESSAGES/fdroidserver.po index c32aa62a..5852ac61 100644 --- a/locale/pt/LC_MESSAGES/fdroidserver.po +++ b/locale/pt/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: fdroidserver 1.1-680-ge1d3de71\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-14 09:28+0000\n" +"PO-Revision-Date: 2020-10-26 07:26+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.3.2-dev\n" #: ../fdroidserver/common.py msgid "" @@ -670,7 +670,7 @@ msgstr "Analise dinâmica dos APKs após a compilação" #: ../fdroidserver/__main__.py msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" -msgstr "" +msgstr "ERRO: o subcomando \"server\" foi removido, use \"deploy\"!" #: ../fdroidserver/mirror.py msgid "" @@ -1282,7 +1282,7 @@ msgstr "O packagename do OBB não corresponde a um APK suportado:" #: ../fdroidserver/deploy.py msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" -msgstr "" +msgstr "A máquina está offline, a saltar a geração de espelhos de git até o `fdroid deploy'" #: ../fdroidserver/common.py #, python-brace-format @@ -2454,7 +2454,7 @@ msgstr "Recusado o download via conexão http insegura (use https ou especifique #: ../fdroidserver/index.py #, python-format msgid "repo_icon %s does not exist, generating placeholder." -msgstr "" +msgstr "repo_icon %s não existe, a gerar um espaço reservado." #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." @@ -2559,7 +2559,7 @@ msgstr "o virustotal.com está a limitar a taxa, à espera para voltar a tentar. #: ../fdroidserver/update.py msgid "wiki support is deprecated and will be removed in the next release!" -msgstr "" +msgstr "O suporte do wiki é depreciado e será removido no próximo lançamento!" #: ../fdroidserver/publish.py #, python-brace-format diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index e6db64aa..906dc132 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-14 09:28+0000\n" +"PO-Revision-Date: 2020-10-26 07:26+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese (Portugal) \n" "Language: pt_PT\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.3.2-dev\n" #: ../fdroidserver/common.py msgid "" @@ -673,7 +673,7 @@ msgstr "Analise dinâmica dos APKs após a compilação" #: ../fdroidserver/__main__.py msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" -msgstr "" +msgstr "ERRO: o subcomando \"server\" foi removido, use \"deploy\"!" #: ../fdroidserver/mirror.py msgid "" @@ -1285,7 +1285,7 @@ msgstr "O packagename do OBB não corresponde a um APK suportado:" #: ../fdroidserver/deploy.py msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" -msgstr "" +msgstr "A máquina está offline, a saltar a geração de espelhos de git até o `fdroid deploy'" #: ../fdroidserver/common.py #, python-brace-format @@ -2457,7 +2457,7 @@ msgstr "Recusado o download via conexão http insegura (use https ou especifique #: ../fdroidserver/index.py #, python-format msgid "repo_icon %s does not exist, generating placeholder." -msgstr "" +msgstr "repo_icon %s não existe, a gerar um espaço reservado." #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." @@ -2562,7 +2562,7 @@ msgstr "o virustotal.com está a limitar a taxa, à espera para voltar a tentar. #: ../fdroidserver/update.py msgid "wiki support is deprecated and will be removed in the next release!" -msgstr "" +msgstr "O suporte do wiki é depreciado e será removido no próximo lançamento!" #: ../fdroidserver/publish.py #, python-brace-format From 50a240c0ec28bb878c8478ada72db1a6580fe57a Mon Sep 17 00:00:00 2001 From: Michal L Date: Wed, 25 Nov 2020 17:40:48 +0100 Subject: [PATCH 0620/2775] Translated using Weblate: Polish (pl) by Michal L Currently translated at 89.7% (514 of 573 strings) Translated using Weblate: Polish (pl) by Michal L Currently translated at 89.5% (513 of 573 strings) Translated using Weblate: Polish (pl) by Michal L Currently translated at 86.5% (496 of 573 strings) Co-authored-by: Michal L Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pl/ Translation: F-Droid/F-Droid Server --- locale/pl/LC_MESSAGES/fdroidserver.po | 108 +++++++++++++------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index b8704f5c..cc665f9f 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. # WaldiS , 2020. +# Michal L , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-14 09:28+0000\n" -"Last-Translator: WaldiS \n" +"PO-Revision-Date: 2020-11-20 23:28+0000\n" +"Last-Translator: Michal L \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -452,7 +453,7 @@ msgstr "Zatwierdź zmiany" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Sprzeczne argumenty: '--verbose' i '--quiet' nie mogą być podane w tym samym czasie." #: ../fdroidserver/common.py #, python-brace-format @@ -567,12 +568,12 @@ msgstr "Usuń pliki APK i/lub OBB bez metadanych z repozytorium" #: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Usuwanie archiwum, repozytorium jest zbyt duże ({size} maks {limit})" #: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Usuwanie historii git-mirror, repozytorium jest zbyt duże ({size} max {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -717,9 +718,9 @@ msgid "Extract signatures from APKs" msgstr "Wyciągnij podpisy z plików APK" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Failed copying {path}: {error}" -msgstr "Błąd odczytu {path}: {error}" +msgstr "Nieudane kopiowanie {path}: {error}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -868,9 +869,9 @@ msgid "Found non-file at %s" msgstr "Znaleziono plik nieprzechowy na %s" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "kopiowanie {apkfilename} na {path}" +msgstr "Znaleziono {apkfilename} na {url}" #: ../fdroidserver/update.py #, python-brace-format @@ -897,7 +898,7 @@ msgstr "Git remote set-head nie powiódł się" #: ../fdroidserver/common.py #, fuzzy, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Git remote set-head nie powiódł się" +msgstr "Operacja Git remote set-head nie powiodła się: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -922,12 +923,12 @@ msgstr "" #: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Jeśli przesyłanie się nie uda, spróbuj przesłać ręcznie do {url}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." -msgstr "" +msgstr "Ignorowanie metadanych '{field}' w '{metapath}' ponieważ są one przestarzałe." #: ../fdroidserver/update.py #, python-format @@ -977,7 +978,7 @@ msgid "Install built packages on devices" msgstr "Zainstaluj wbudowane pakiety na urządzeniach" #: ../fdroidserver/install.py -#, fuzzy, python-format +#, python-format msgid "Installing %s..." msgstr "Instalowanie %s…" @@ -987,7 +988,7 @@ msgid "Installing %s…" msgstr "Instalowanie %s…" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Installing '{apkfilename}' on {dev}..." msgstr "Instalowanie '{apkfilename}' na {dev}…" @@ -1010,9 +1011,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "Nieprawidłowa VercodeOperation: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "Nieprawidłowa VercodeOperation: {field}" +msgstr "Nieprawidłowy ID aplikacji {appid}" #: ../fdroidserver/metadata.py #, python-format @@ -1067,19 +1068,19 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Nieprawidłowe przekierowanie do nie-HTTPS: {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Przeczytaj wszystkie pliki metadanych i zakończ" +msgstr "Nieprawidłowe metadane scrlib: '{file}' nie istnieje" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: could not parse '{file}'" -msgstr "" +msgstr "Nieprawidłowe metadane srclib: nie można przeanalizować '{file}'" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" -msgstr "" +msgstr "Nieprawidłowe metadane srclib: nieznany klucz '{key}' w '{file}'" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1097,8 +1098,9 @@ msgid "JAR signature verified: {path}" msgstr "Podpis JAR potwierdzony: {path}" #: ../fdroidserver/scanner.py +#, fuzzy msgid "Java JAR file" -msgstr "" +msgstr "Plik JAR Java" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1198,9 +1200,8 @@ msgid "No git submodules available" msgstr "Brak dostępnych submodułów git" #: ../fdroidserver/import.py -#, fuzzy msgid "No gradle project could be found. Specify --subdir?" -msgstr "Nie można znaleźć projektu android ani kivy. Podaj --subdir?" +msgstr "Nie można znaleźć żadnego projektu gradle. Podaj --subdir?" #: ../fdroidserver/import.py ../fdroidserver/common.py msgid "No information found." @@ -1348,7 +1349,7 @@ msgstr "Przesłaniam pustą versionName w {apkfilename} z metadanych: {version}" #: ../fdroidserver/import.py #, python-brace-format msgid "Package \"{appid}\" already exists" -msgstr "" +msgstr "Pakiet \"{appid}\" już istnieje" #: ../fdroidserver/common.py #, python-brace-format @@ -1730,7 +1731,7 @@ msgstr "Istnieje kolizja keyalias - wstrzymano publikowanie" #: ../fdroidserver/common.py msgid "These are the apps that have been archived from the main repo." -msgstr "" +msgstr "To są aplikacje, które zostały zarchiwizowane w głównym repozytorium." #: ../fdroidserver/import.py #, python-format @@ -1743,7 +1744,7 @@ msgstr "Aby użyć awsbucket, awssecretkey i awsaccesskeyid muszą być równie #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" -msgstr "" +msgstr "Adres URL musi rozpoczynać się od https:// lub http://" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" @@ -1759,13 +1760,12 @@ msgid "URL {url} in Description: {error}" msgstr "Adres URL {url} w opisie {error}" #: ../fdroidserver/lint.py -#, fuzzy msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" -msgstr "Nieprawidłowy tag licencji \"%s\"! Używaj tylko tagów z https://spdx.org/license-list" +msgstr "Nieprawidłowy tag licencji \"{}\"! Używaj tylko tagów zgodnych z FSF lub OSI ze strony https://spdx.org/license-list" #: ../fdroidserver/lint.py msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" -msgstr "" +msgstr "Nieprawidłowy tag licencji \"{}\"! Używaj tylko tagów licencji skonfigurowanych w twoim pliku konfiguracji" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1793,9 +1793,9 @@ msgid "Unknown metadata format: {path}" msgstr "Nieznany format metadanych: {path}" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path} (use: *.yml)" -msgstr "Nieznany format metadanych: {path}" +msgstr "Nieznany format metadanych: {path} (użyj: *.yml)" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1876,14 +1876,14 @@ msgid "Unused file at %s" msgstr "Plik UNUSED, o %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scandelete path: %s" -msgstr "Plik UNUSED, o %s" +msgstr "Nieużywana ścieżka scandelete: %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scanignore path: %s" -msgstr "Plik UNUSED, o %s" +msgstr "Nieużywana ścieżka scanignore: %s" #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" @@ -1924,22 +1924,22 @@ msgstr "UpdateCheckMode jest ustawione, ale wygląda na to, że checkupdates nie #: ../fdroidserver/lint.py #, fuzzy msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Aktualizacja Check Name jest ustawiona na znany identyfikator aplikacji - można go usunąć" +msgstr "UpdateCheckName (Nazwa sprawdzania aktualizacji) jest ustawiona na znany identyfikator aplikacji - można go usunąć" #: ../fdroidserver/lint.py #, fuzzy msgid "UpdateCheckName is set to the known application ID, it can be removed" -msgstr "Aktualizacja Check Name jest ustawiona na znany identyfikator aplikacji - można go usunąć" +msgstr "UpdateCheckName (Nazwa sprawdzania aktualizacji) jest ustawiona na znany identyfikator aplikacji, można go usunąć" #: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" -msgstr "" +msgstr "Przesyłanie {apkfilename} do androidobservatory.org" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Uploading {apkfilename} to virustotal" -msgstr "Czytanie {apkfilename} z pamięci podręcznej" +msgstr "Przesyłanie {apkfilename} do virustotal" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1978,11 +1978,11 @@ msgstr "Użyj \"{path}\" do konfiguracji s3cmd." #: ../fdroidserver/common.py msgid "Using APK Signature v2" -msgstr "" +msgstr "Używając APK Signature v2" #: ../fdroidserver/common.py msgid "Using APK Signature v3" -msgstr "" +msgstr "Używając APK Signature v3" #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" @@ -2049,7 +2049,7 @@ msgstr "Możesz użyć ANDROID_HOME, aby ustawić ścieżkę do SDK, tj .:" #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "" +msgstr "Plik archiwum ZIP" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2131,9 +2131,9 @@ msgid "can't open '%s': %s" msgstr "nie można otworzyć '%s':%s" #: ../fdroidserver/build.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "cannot find required srclibs: \"{path}\"" -msgstr "Nie można znaleźć załącznika dla {path}!" +msgstr "Nie można znaleźć wymaganych srclibs: \"{path}\"" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2281,7 +2281,7 @@ msgstr "klon git svn nie powiódł się" #: ../fdroidserver/scanner.py msgid "gzip file archive" -msgstr "" +msgstr "plik archiwum gzip" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2470,7 +2470,7 @@ msgstr "" #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." -msgstr "" +msgstr "nie zainstalowano ruamel.yaml, nie można zapisać metadanych." #: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format @@ -2660,7 +2660,7 @@ msgstr "{field} nie została zakończona w {name}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{file} is blank or corrupt!" -msgstr "" +msgstr "{file} jest pusty lub uszkodzony!" #: ../fdroidserver/update.py #, python-brace-format @@ -2670,7 +2670,7 @@ msgstr "{name} \"{path}\" nie istnieje! Popraw go w config.py." #: ../fdroidserver/import.py #, python-brace-format msgid "{path} already exists, ignoring import results!" -msgstr "" +msgstr "{path} już istnieje, ignorowanie rezultatów importowania!" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2688,9 +2688,9 @@ msgid "{path} is zero size!" msgstr "{path} ma zerowy rozmiar!" #: ../fdroidserver/deploy.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" -msgstr "" +msgstr "{path} więcej niż 200MB, załadowane ręcznie: {url}" #: ../fdroidserver/mirror.py #, python-brace-format @@ -2698,9 +2698,9 @@ msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} nie kończy się na 'fdroid', sprawdź ścieżkę URL!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{url} does not start with \"http\"!" -msgstr "{url} nie kończy się na 'fdroid', sprawdź ścieżkę URL!" +msgstr "{url} nie zaczyna się od \"http\"!" #: ../fdroidserver/build.py msgid "{} build failed" From 6d4527186a5e21c57be645c57408db0885fec5f7 Mon Sep 17 00:00:00 2001 From: NightFeather Date: Wed, 25 Nov 2020 17:40:48 +0100 Subject: [PATCH 0621/2775] Translated using Weblate: Chinese (Traditional) (zh_Hant) by NightFeather Currently translated at 82.3% (472 of 573 strings) Co-authored-by: NightFeather Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hant/ Translation: F-Droid/F-Droid Server --- locale/zh_Hant/LC_MESSAGES/fdroidserver.po | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index 2aea4a9d..d569fda3 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -2,20 +2,21 @@ # Copyright (C) YEAR Free Software Foundation, Inc. # Jeff Huang , 2020. # Hans-Christoph Steiner , 2020. +# NightFeather , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-01 09:00+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-11-03 22:53+0000\n" +"Last-Translator: NightFeather \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.3.2-dev\n" #: ../fdroidserver/common.py msgid "" @@ -443,7 +444,7 @@ msgstr "以逗號分隔類別清單。" #: ../fdroid ../fdroidserver/__main__.py #, c-format, python-format msgid "Command '%s' not recognised.\n" -msgstr "不能承認命令「%s」。\n" +msgstr "無法識別指令「%s」。\n" #: ../fdroidserver/checkupdates.py msgid "Commit changes" @@ -1941,13 +1942,13 @@ msgstr "從緩存讀取 {apkfilename}" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py msgid "Usage" -msgstr "使用" +msgstr "使用方法" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py #, python-format msgid "Usage: %s\n" -msgstr "使用:%s\n" +msgstr "使用方法:%s\n" #: ../fdroidserver/lint.py msgid "Use /HEAD instead of /master to point at a file in the default branch" @@ -2002,7 +2003,7 @@ msgstr "使用 s3cmd 來同步:{url}" #: ../fdroid ../fdroidserver/__main__.py msgid "Valid commands are:" -msgstr "正確的命令是:" +msgstr "有效的指令是:" #: ../fdroidserver/verify.py msgid "Verify against locally cached copy rather than redownloading." @@ -2483,7 +2484,7 @@ msgstr "顯示程式的版本號碼並離開" #: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py msgid "show this help message and exit" -msgstr "顯示此幫助訊息並離開" +msgstr "顯示此說明訊息並離開" #: ../fdroidserver/signatures.py msgid "signed APK, either a file-path or HTTPS URL." @@ -2547,11 +2548,11 @@ msgstr "'{config_file}' 檔案不安全的權限(應為 0600)!" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py ../fdroid #: /usr/lib/python3.7/argparse.py ../fdroidserver/__main__.py msgid "usage: " -msgstr "使用: " +msgstr "使用方法: " #: ../fdroid msgid "usage: fdroid [-h|--help|--version] []" -msgstr "用法:fdroid [-h|--help|--version] <命令> []" +msgstr "用法:fdroid [-h|--help|--version] <指令> []" #: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format From 96faaf7d18d8eadcfd2c9a395134018450a0565f Mon Sep 17 00:00:00 2001 From: The Cats Date: Wed, 25 Nov 2020 17:40:48 +0100 Subject: [PATCH 0622/2775] Translated using Weblate: Portuguese (Brazil) (pt_BR) by The Cats Currently translated at 100.0% (573 of 573 strings) Co-authored-by: The Cats Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/pt_BR/ Translation: F-Droid/F-Droid Server --- locale/pt_BR/LC_MESSAGES/fdroidserver.po | 45 +++++++++++------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 7fc0588f..2776035d 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -5,20 +5,21 @@ # Hans-Christoph Steiner , 2020. # Rafael Fontenelle , 2020. # ssantos , 2020. +# The Cats , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-06 08:26+0000\n" -"Last-Translator: André Marcelo Alvarenga \n" +"PO-Revision-Date: 2020-11-09 19:08+0000\n" +"Last-Translator: The Cats \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\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 4.3-dev\n" +"X-Generator: Weblate 4.3.2\n" #: ../fdroidserver/common.py msgid "" @@ -394,9 +395,9 @@ msgstr "Impossível ler \"{path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot resolve application ID {appid}" -msgstr "Impossível resolver o ID de Aplicativo '{appid}'" +msgstr "Impossível resolver o ID do Aplicativo {appid}" #: ../fdroidserver/rewritemeta.py #, python-brace-format @@ -675,7 +676,7 @@ msgstr "Escanear dinamicamente os APKs após a compilação" #: ../fdroidserver/__main__.py msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" -msgstr "" +msgstr "ERRO: o subcomando \"server\" foi removido, use \"deploy\"!" #: ../fdroidserver/mirror.py msgid "" @@ -1015,9 +1016,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "Versão de Operação de Código inválido: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "Versão de Operação de Código inválido: {field}" +msgstr "ID do aplicativo {appid} inválido" #: ../fdroidserver/metadata.py #, python-format @@ -1127,9 +1128,9 @@ msgid "Keystore for signing key:\t" msgstr "Armazenamento de chaves de assinatura:\t" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" -msgstr "O último commit usado '{commit}' parece com uma tag, mas o Update Check Mode é '{ucm}'" +msgstr "O último commit usado '{commit}' parece com uma tag, mas o UpdateCheckMode (modo de verificação de atualização) é '{ucm}'" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the Liberapay: field" @@ -1287,7 +1288,7 @@ msgstr "O nome do pacote do OBB não corresponde a um APK suportado:" #: ../fdroidserver/deploy.py msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" -msgstr "" +msgstr "A máquina está desconectada, pulando geração de espelhos de git até o `fdroid deploy'" #: ../fdroidserver/common.py #, python-brace-format @@ -1922,14 +1923,12 @@ msgstr "UpdateCheckMode é definido, mas parece que checkupdates ainda não foi #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -#, fuzzy msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" +msgstr "UpdateCheckName (atualização da verificação do nome) está definido como o ID comum da aplicação - pode ser removido" #: ../fdroidserver/lint.py -#, fuzzy msgid "UpdateCheckName is set to the known application ID, it can be removed" -msgstr "O nome da verificação da atualização (Update Check Name) é definido como o ID comun do app - pode ser removido" +msgstr "UpdateCheckName (atualização da verificação do nome) é definido como o ID comun do app - pode ser removido" #: ../fdroidserver/deploy.py #, python-brace-format @@ -2079,14 +2078,12 @@ msgstr "o apksigner não foi encontrado, ele é necessário para assinar!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py -#, fuzzy msgid "application ID of file to operate on" -msgstr "applicationId para verificar se há atualizações" +msgstr "ID de aplicação do arquivo para operar" #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py -#, fuzzy msgid "application ID with optional versionCode in the form APPID[:VERCODE]" msgstr "applicationId com versionCode opcional na forma APPID[:VERCODE]" @@ -2463,7 +2460,7 @@ msgstr "Recuse o download insegura via conexão http (use https ou especifique - #: ../fdroidserver/index.py #, python-format msgid "repo_icon %s does not exist, generating placeholder." -msgstr "" +msgstr "repo_icon %s não existe, gerando um espaço reservado." #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." @@ -2568,7 +2565,7 @@ msgstr "o virustotal.com está limitando a taxa, esperando para tentar novamente #: ../fdroidserver/update.py msgid "wiki support is deprecated and will be removed in the next release!" -msgstr "" +msgstr "O suporte do wiki está descontinuado e será removido no próximo lançamento!" #: ../fdroidserver/publish.py #, python-brace-format @@ -2593,9 +2590,9 @@ msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml do {apkfilename} tem uma data má: " #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{appid} does not have a name! Using application ID instead." -msgstr "{appid} não tem um nome! Usando o nome do pacote em vez disso." +msgstr "{appid} não tem um nome! Usando o ID do applicativo em vez disso." #: ../fdroidserver/update.py #, python-brace-format @@ -2608,9 +2605,9 @@ msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "O {appid} do {path} não é um Nome de Pacote Android válido!" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{appid} from {path} is not a valid Android application ID!" -msgstr "O {appid} do {path} não é um Nome de Pacote Android válido!" +msgstr "O {appid} do {path} não é um ID de aplicativo Android válido!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format From a6c3598466674c5471ff2f3cd41753ae18dadaa1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 25 Nov 2020 17:40:49 +0100 Subject: [PATCH 0623/2775] Translated using Weblate: Albanian (sq) by Hans-Christoph Steiner Currently translated at 80.1% (459 of 573 strings) Translated using Weblate: Hungarian (hu) by Hans-Christoph Steiner Currently translated at 13.7% (79 of 573 strings) Translated using Weblate: Swedish (sv) by Hans-Christoph Steiner Currently translated at 7.5% (43 of 573 strings) Translated using Weblate: Russian (ru) by Hans-Christoph Steiner Currently translated at 84.2% (483 of 573 strings) Translated using Weblate: Korean (ko) by Hans-Christoph Steiner Currently translated at 36.1% (207 of 573 strings) Translated using Weblate: Tibetan (bo) by Hans-Christoph Steiner Currently translated at 67.8% (389 of 573 strings) Translated using Weblate: German (de) by Hans-Christoph Steiner Currently translated at 86.0% (493 of 573 strings) Translated using Weblate: Spanish (es) by Hans-Christoph Steiner Currently translated at 55.4% (318 of 573 strings) Translated using Weblate: Chinese (Traditional) (zh_Hant) by Hans-Christoph Steiner Currently translated at 82.7% (474 of 573 strings) Translated using Weblate: Spanish (Argentina) (es_AR) by Hans-Christoph Steiner Currently translated at 14.4% (83 of 573 strings) Translated using Weblate: Albanian (sq) by Hans-Christoph Steiner Currently translated at 80.1% (459 of 573 strings) Translated using Weblate: Tibetan (bo) by Hans-Christoph Steiner Currently translated at 67.7% (388 of 573 strings) Translated using Weblate: German (de) by Hans-Christoph Steiner Currently translated at 85.8% (492 of 573 strings) Translated using Weblate: Spanish (es) by Hans-Christoph Steiner Currently translated at 55.3% (317 of 573 strings) Translated using Weblate: Chinese (Traditional) (zh_Hant) by Hans-Christoph Steiner Currently translated at 82.5% (473 of 573 strings) Co-authored-by: Hans-Christoph Steiner Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/bo/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/de/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es_AR/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/hu/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ko/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/sq/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/sv/ Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/zh_Hant/ Translation: F-Droid/F-Droid Server --- locale/bo/LC_MESSAGES/fdroidserver.po | 67 +++++++++++----------- locale/de/LC_MESSAGES/fdroidserver.po | 27 ++++----- locale/es/LC_MESSAGES/fdroidserver.po | 19 +++--- locale/es_AR/LC_MESSAGES/fdroidserver.po | 12 ++-- locale/hu/LC_MESSAGES/fdroidserver.po | 11 ++-- locale/ko/LC_MESSAGES/fdroidserver.po | 29 +++++----- locale/ru/LC_MESSAGES/fdroidserver.po | 15 ++--- locale/sq/LC_MESSAGES/fdroidserver.po | 27 ++++----- locale/sv/LC_MESSAGES/fdroidserver.po | 13 ++--- locale/zh_Hant/LC_MESSAGES/fdroidserver.po | 26 ++++----- 10 files changed, 124 insertions(+), 122 deletions(-) diff --git a/locale/bo/LC_MESSAGES/fdroidserver.po b/locale/bo/LC_MESSAGES/fdroidserver.po index a6c83c2a..3f59444c 100644 --- a/locale/bo/LC_MESSAGES/fdroidserver.po +++ b/locale/bo/LC_MESSAGES/fdroidserver.po @@ -1,13 +1,12 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. -# FIRST AUTHOR , YEAR. -# +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2018-02-13 08:41+0000\n" +"PO-Revision-Date: 2020-11-10 16:20+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Tibetan \n" "Language: bo\n" @@ -15,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -79,9 +78,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}སྒྲིག་བཀོད་འདི་ངོས་ལེན་བྱེད་ཐུབ་ཀྱི་མིན་འདུག:{formats}" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format @@ -176,9 +175,9 @@ msgid "'{aapt}' is too old, fdroid requires build-tools-23.0.0 or newer!" msgstr "'{aapt}1' འདི་ཧ་ཅང་གི་རྙིང་པ་རེད་འདུག, ཨེཕ་རོཌ་ལ་བཟོ་སྐྲུན་མ་ལག-23.0.0 དང་ཡང་ན་དེ་ལས་གསར་བ་དགོས།!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" -msgstr "'{aapt}1' འདི་ཧ་ཅང་གི་རྙིང་པ་རེད་འདུག, ཨེཕ་རོཌ་ལ་བཟོ་སྐྲུན་མ་ལག-23.0.0 དང་ཡང་ན་དེ་ལས་གསར་བ་དགོས།!" +msgstr "" #: ../fdroidserver/install.py #, python-brace-format @@ -379,9 +378,9 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "ཚགས་རྒྱབ་པའི་སྐབས་སུ་ནོར་སྐྱོན་ {} ཤོར་བས་བཟོ་སྐྲུན་བྱེད་ཐུབ་མེད།" #: ../fdroidserver/vmtools.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot read \"{path}\"!" -msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" +msgstr "" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py @@ -390,9 +389,9 @@ msgid "Cannot resolve application ID {appid}" msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "{appid} app idཐག་ཆོད་ཐུབ་མ་སོང་།" +msgstr "" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -867,9 +866,9 @@ msgid "Found non-file at %s" msgstr "འདི་ལ་%s 1 ཡིག་ཆ་མིན་པ་རྙེད་སོང་།" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "{path} ནང་ལ་ {apkfilename}ཤུས་བཞིན་པ།" +msgstr "{url} ནང་ལ་ {apkfilename}ཤུས་བཞིན་པ།" #: ../fdroidserver/update.py #, python-brace-format @@ -894,9 +893,9 @@ msgid "Git remote set-head failed" msgstr "གིཊ་རྒྱང་ཐག་སྒྲིག་འགོ་ཐུབ་མ་སོང་།" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "གིཊ་རྒྱང་ཐག་སྒྲིག་འགོ་ཐུབ་མ་སོང་།" +msgstr "" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -1066,9 +1065,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་ཀློག་ནས་ཕྱིར་ཐོན།" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1555,14 +1554,14 @@ msgid "Scan the source code of a package" msgstr "ཐུམ་སྒྲིལ་བྱས་པའི་འབྱུང་ཁུངས་ཨང་རྟགས་འཚག་རྒྱབ" #: ../fdroidserver/scanner.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Scanner found {count} problems in {appid}:" -msgstr "འཚག་རྒྱབ་ལ་སྐྱོན་རྙེད་པ།" +msgstr "" #: ../fdroidserver/scanner.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Scanner found {count} problems in {appid}:{versionCode}:" -msgstr "འཚག་རྒྱབ་ལ་སྐྱོན་རྙེད་པ།" +msgstr "" #: ../fdroidserver/build.py msgid "Scanner found {} problem" @@ -1813,18 +1812,18 @@ msgid "Unnecessary trailing space" msgstr "དགོས་མེད་ཀྱི་རྫེས་ཤུལ་བར་མཚམས།" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unrecognised app field '{fieldname}' in '{path}'" -msgstr "{linedesc}ནང་ངོས་འཛིན་མ་ཐུབ་པའི་རྭ་བ།{field}" +msgstr "" #: ../fdroidserver/metadata.py msgid "Unrecognised app field: " msgstr "ངོས་འཛིན་མ་ཐུབ་པའི་མཉེན་ཆས་རྭ་བ།: " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unrecognised build flag '{build_flag}' in '{path}'" -msgstr "{linedesc}ནང་ངོས་འཛིན་མ་ཐུབ་པའི་རྭ་བ།{field}" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2588,9 +2587,9 @@ msgid "{apkfilename} has multiple {name} files, looks like Master Key exploit!" msgstr "" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " -msgstr "AndroidManifest.xmlལ་ཟླ་ཚེས་མིན་འདུག" +msgstr "" #: ../fdroidserver/update.py #, fuzzy, python-brace-format @@ -2669,9 +2668,9 @@ msgid "{path} already exists, ignoring import results!" msgstr "" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{path} does not exist! Create it by running:" -msgstr "{name} \"{path}\" མིན་འདུག! config.py.ནོར་བཅོས་བྱེད།" +msgstr "" #: ../fdroidserver/update.py #, python-brace-format @@ -2689,14 +2688,14 @@ msgid "{path} more than 200MB, manually upload: {url}" msgstr "" #: ../fdroidserver/mirror.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{url} does not end with \"fdroid\", check the URL path!" -msgstr "local_copy_dir \"fdroid\"གིས་མཇུག་སྐྱོང་མིན་འདུག་ : \"{path}1\"" +msgstr "" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{url} does not start with \"http\"!" -msgstr "local_copy_dir \"fdroid\"གིས་མཇུག་སྐྱོང་མིན་འདུག་ : \"{path}1\"" +msgstr "" #: ../fdroidserver/build.py msgid "{} build failed" diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index d036f86c..a866f5b0 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -4,20 +4,21 @@ # Fynn Godau , 2020. # melusine , 2020. # marzzzello , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-15 17:12+0000\n" -"Last-Translator: marzzzello \n" +"PO-Revision-Date: 2020-11-10 16:20+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: German \n" "Language: de\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 4.3-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -88,9 +89,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "„{path}” vorhanden, aber S3cmd ist nicht installiert!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" ist kein akzeptiertes Format, umwandeln in: {formats}" +msgstr "\"{path}\" ist kein akzeptiertes Format, umwandeln in metadata/*.yml" #: ../fdroidserver/metadata.py #, python-brace-format @@ -878,9 +879,9 @@ msgid "Found non-file at %s" msgstr "Eine Nicht-Datei gefunden bei %s" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "Kopiere {apkfilename} nach {path}" +msgstr "" #: ../fdroidserver/update.py #, python-brace-format @@ -905,9 +906,9 @@ msgid "Git remote set-head failed" msgstr "Git remote set-head fehlgeschlagen" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Git remote set-head fehlgeschlagen" +msgstr "Git remote set-head fehlgeschlagen: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -1021,9 +1022,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "Ungültige VercodeOperation: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "Ungültige VercodeOperation: {field}" +msgstr "" #: ../fdroidserver/metadata.py #, python-format @@ -1078,9 +1079,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Ungültige Umleitung auf Nicht-HTTTPS: {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Alle Metadaten-Dateien betrachten und beenden" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index 274c4c7f..c848753b 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -3,20 +3,21 @@ # This file is distributed under the same license as the PACKAGE package. # Maximiliano Castañón , 2020. # Jo , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-02 19:15+0000\n" -"Last-Translator: Jo \n" +"PO-Revision-Date: 2020-11-10 16:20+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Spanish \n" "Language: es\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 4.3-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py #, fuzzy @@ -87,9 +88,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" existe pero ¡s3cmd no está instalado!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" no es un formato reconocido, convertir a: {formats}" +msgstr "\"{path}\" no es un formato reconocido, convertir a metadata/*.yml" #: ../fdroidserver/metadata.py #, python-brace-format @@ -877,9 +878,9 @@ msgid "Found non-file at %s" msgstr "" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "Procesando {apkfilename}" +msgstr "" #: ../fdroidserver/update.py #, python-brace-format @@ -904,9 +905,9 @@ msgid "Git remote set-head failed" msgstr "" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Git reset falló" +msgstr "Git remote set-head falló: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" diff --git a/locale/es_AR/LC_MESSAGES/fdroidserver.po b/locale/es_AR/LC_MESSAGES/fdroidserver.po index 5dcd04d1..49b4d592 100644 --- a/locale/es_AR/LC_MESSAGES/fdroidserver.po +++ b/locale/es_AR/LC_MESSAGES/fdroidserver.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-01 10:31+0000\n" -"Last-Translator: riveravaldez \n" +"PO-Revision-Date: 2020-11-10 16:20+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Spanish (Argentina) \n" "Language: es_AR\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 4.3-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -1064,9 +1064,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Leer todos los archivos de metadatos y salir" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2327,7 +2327,7 @@ msgstr "" #: ../fdroidserver/deploy.py #, fuzzy, python-brace-format msgid "local_copy_dir does not end with \"fdroid\", perhaps you meant: \"{path}\"" -msgstr "directorio_copia_local no termina en \"fdroid\", quizá quiso escribir: \"{ruta}\"" +msgstr "local_copy_dir no termina en \"fdroid\", quizá quiso escribir: \"{path}\"" #: ../fdroidserver/deploy.py #, fuzzy diff --git a/locale/hu/LC_MESSAGES/fdroidserver.po b/locale/hu/LC_MESSAGES/fdroidserver.po index d24bae2a..a274970b 100644 --- a/locale/hu/LC_MESSAGES/fdroidserver.po +++ b/locale/hu/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. # Balázs Meskó , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-70-g54bc858\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-04-07 13:43+0000\n" -"Last-Translator: Balázs Meskó \n" +"PO-Revision-Date: 2020-11-10 16:21+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Hungarian \n" "Language: hu\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 4.0-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -78,9 +79,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "A(z) „{path}” létezik, de az s3cmd nincs telepítve." #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "A(z) „{path}” nem egy elfogadott formátum, alakítsa át erre: {formats}" +msgstr "A(z) „{path}” nem egy elfogadott formátum, alakítsa át erre: metadata/*.yml" #: ../fdroidserver/metadata.py #, python-brace-format diff --git a/locale/ko/LC_MESSAGES/fdroidserver.po b/locale/ko/LC_MESSAGES/fdroidserver.po index 788a0117..b8c6c8b3 100644 --- a/locale/ko/LC_MESSAGES/fdroidserver.po +++ b/locale/ko/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.8-135-g16dd6d28\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2019-01-19 22:57+0000\n" -"Last-Translator: Seokyong Jung \n" +"PO-Revision-Date: 2020-11-10 16:20+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Korean \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.4-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -859,9 +858,9 @@ msgid "Found non-file at %s" msgstr "" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "{path} 안으로 {apkfilename}을 복사 중" +msgstr "" #: ../fdroidserver/update.py #, python-brace-format @@ -1001,9 +1000,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "잘못된 Vercode연산: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "잘못된 Vercode연산: {field}" +msgstr "" #: ../fdroidserver/metadata.py #, python-format @@ -1058,9 +1057,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "HTTPS가 아닌 곳으로의 잘못된 리다이렉트: {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "모든 메타데이터 파일을 읽고 종료합니다" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1800,9 +1799,9 @@ msgid "Unnecessary trailing space" msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unrecognised app field '{fieldname}' in '{path}'" -msgstr "{path} 안으로 {apkfilename}을 복사 중" +msgstr "" #: ../fdroidserver/metadata.py msgid "Unrecognised app field: " @@ -1921,9 +1920,9 @@ msgid "Uploading {apkfilename} to androidobservatory.org" msgstr "" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Uploading {apkfilename} to virustotal" -msgstr "{path} 안으로 {apkfilename}을 복사 중" +msgstr "" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 1d587503..3482e610 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -6,20 +6,21 @@ # Andrey , 2020. # gardenapple , 2020. # Boris Timofeev , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-10-05 12:34+0000\n" -"Last-Translator: Boris Timofeev \n" +"PO-Revision-Date: 2020-11-10 16:21+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -1015,9 +1016,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "Расхождение версий приложения в метаданных: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "Расхождение версий приложения в метаданных: {field}" +msgstr "" #: ../fdroidserver/metadata.py #, python-format @@ -1072,9 +1073,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Неверное перенаправление (не HTTPS): {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Прочесть все метаданные и выйти" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format diff --git a/locale/sq/LC_MESSAGES/fdroidserver.po b/locale/sq/LC_MESSAGES/fdroidserver.po index f17bcb2e..eec0415c 100644 --- a/locale/sq/LC_MESSAGES/fdroidserver.po +++ b/locale/sq/LC_MESSAGES/fdroidserver.po @@ -1,20 +1,21 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. # Besnik Bleta , 2020. +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-04-26 19:11+0000\n" -"Last-Translator: Besnik Bleta \n" +"PO-Revision-Date: 2020-11-10 16:21+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Albanian \n" "Language: sq\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 4.0.2-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -78,9 +79,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "\"{path}\" ekziston, por s3cmd s’është e instaluar!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" s’është në një format të pranuar, shndërrojeni në: {formats}" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format @@ -868,9 +869,9 @@ msgid "Found non-file at %s" msgstr "" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "po kopjohet {apkfilename} te {path}" +msgstr "" #: ../fdroidserver/update.py #, python-brace-format @@ -895,9 +896,9 @@ msgid "Git remote set-head failed" msgstr "Veprimi “git remote set-head” dështoi" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Veprimi “git remote set-head” dështoi" +msgstr "Veprimi “git remote set-head” dështoi: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -1010,9 +1011,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "VercodeOperationi pavlefshëm: {field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "VercodeOperationi pavlefshëm: {field}" +msgstr "" #: ../fdroidserver/metadata.py #, python-format @@ -1067,9 +1068,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "Ridrejtim i pavlefshëm te non-HTTPS: {before} -> {after} " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Lexo krejt kartelat e tejtëdhënave dhe dil" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format diff --git a/locale/sv/LC_MESSAGES/fdroidserver.po b/locale/sv/LC_MESSAGES/fdroidserver.po index 4acafd43..d3e6bac7 100644 --- a/locale/sv/LC_MESSAGES/fdroidserver.po +++ b/locale/sv/LC_MESSAGES/fdroidserver.po @@ -1,21 +1,20 @@ # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# +# Hans-Christoph Steiner , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2018-10-14 14:43+0000\n" -"Last-Translator: Jonatan Nyberg \n" +"PO-Revision-Date: 2020-11-10 16:21+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Swedish \n" "Language: sv\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 3.2.1\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -1052,9 +1051,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "Läs alla metadatafiler och avsluta" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index d569fda3..2894f7c0 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-11-03 22:53+0000\n" -"Last-Translator: NightFeather \n" +"PO-Revision-Date: 2020-11-10 16:20+0000\n" +"Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.3.2-dev\n" +"X-Generator: Weblate 4.4-dev\n" #: ../fdroidserver/common.py msgid "" @@ -80,9 +80,9 @@ msgid "\"{path}\" exists but s3cmd is not installed!" msgstr "有 \"{path}\" 存在,但是沒有安裝 s3cmd!" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "\"{path}\" 不是可接受的格式,轉換成: {formats}" +msgstr "\"{path}\" 不是可接受的格式,轉換成: metadata/*.yml" #: ../fdroidserver/metadata.py #, python-brace-format @@ -868,9 +868,9 @@ msgid "Found non-file at %s" msgstr "%s 中找到 non-file" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "複製 {apkfilename} 到 {path}" +msgstr "" #: ../fdroidserver/update.py #, python-brace-format @@ -895,9 +895,9 @@ msgid "Git remote set-head failed" msgstr "Git 遠端 set-head 失敗" #: ../fdroidserver/common.py -#, fuzzy, python-format +#, python-format msgid "Git remote set-head failed: \"%s\"" -msgstr "Git 遠端 set-head 失敗" +msgstr "Git 遠端 set-head 失敗: \"%s\"" #: ../fdroidserver/common.py msgid "Git reset failed" @@ -1010,9 +1010,9 @@ msgid "Invalid VercodeOperation: {field}" msgstr "無效的 VercodeOperation:{field}" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid application ID {appid}" -msgstr "無效的 VercodeOperation:{field}" +msgstr "" #: ../fdroidserver/metadata.py #, python-format @@ -1067,9 +1067,9 @@ msgid "Invalid redirect to non-HTTPS: {before} -> {after} " msgstr "無效的重新導向到非 HTTPS:{before}->{after}。 " #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "讀取所有的中介資料檔案並退出" +msgstr "" #: ../fdroidserver/metadata.py #, python-brace-format From 9c72e6f1a8591b3f73e9930eca603037c408e949 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 25 Nov 2020 17:40:49 +0100 Subject: [PATCH 0624/2775] Translated using Weblate: Albanian (sq) by Besnik Bleta Currently translated at 96.8% (555 of 573 strings) Translated using Weblate: Albanian (sq) by Besnik Bleta Currently translated at 80.8% (463 of 573 strings) Co-authored-by: Besnik Bleta Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/sq/ Translation: F-Droid/F-Droid Server --- locale/sq/LC_MESSAGES/fdroidserver.po | 236 +++++++++++++------------- 1 file changed, 114 insertions(+), 122 deletions(-) diff --git a/locale/sq/LC_MESSAGES/fdroidserver.po b/locale/sq/LC_MESSAGES/fdroidserver.po index eec0415c..9e0c98ae 100644 --- a/locale/sq/LC_MESSAGES/fdroidserver.po +++ b/locale/sq/LC_MESSAGES/fdroidserver.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: fdroidserver 1.0.6-349-g907c04ea\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-11-10 16:21+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-11-14 21:55+0000\n" +"Last-Translator: Besnik Bleta \n" "Language-Team: Albanian \n" "Language: sq\n" "MIME-Version: 1.0\n" @@ -26,6 +26,12 @@ msgid "" " tools on https://gitlab.com/fdroid.\n" " " msgstr "" +"\n" +" Kjo është një depo aplikacionesh për t’u përdorur me FDroid. Applikacionet\n" +" në këtë depo ose janë dyorë zyrtarë të montuar nga zhvilluesit e aplikacionit\n" +" origjinal, ose janë dyorë të montuar nga burimi prej f-droid.org duke përdorur\n" +" mjetet në https://gitlab.com/fdroid.\n" +" " #: ../fdroidserver/nightly.py msgid "" @@ -36,13 +42,12 @@ msgstr "" "Kyç SSH Publik për t’u përdorur si Kyç Sendërtimesh:" #: ../fdroidserver/nightly.py -#, fuzzy msgid "" "\n" "SSH public key to be used as deploy key:" msgstr "" "\n" -"Kyç SSH Publik për t’u përdorur si Kyç Sendërtimesh:" +"Kyç SSH Publik për t’u përdorur si kyç sendërtimesh:" #: ../fdroidserver/nightly.py #, python-brace-format @@ -59,7 +64,7 @@ msgid "\"%s/\" has no matching metadata file!" msgstr "\"%s/\" s’ka kartel tejtëdhënash me përputhje!" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "\"{apkfilename}\" is already installed on {dev}." msgstr "'{apkfilename}' është tashmë e instaluar në {dev}." @@ -81,7 +86,7 @@ msgstr "\"{path}\" ekziston, por s3cmd s’është e instaluar!" #: ../fdroidserver/lint.py #, python-brace-format msgid "\"{path}\" is not a supported file format (use: metadata/*.yml)" -msgstr "" +msgstr "\"{path}\" s’është format kartelash i mbuluar (përdorni: metadata/*.yml)" #: ../fdroidserver/metadata.py #, python-brace-format @@ -91,7 +96,7 @@ msgstr "\"{path}\" s’është në një format të pranuar, shndërrojeni në: { #: ../fdroidserver/common.py #, python-brace-format msgid "\"{url}\" is not a valid URL!" -msgstr "" +msgstr "\"{url}\" s’është URL e vlefshme!" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -145,7 +150,7 @@ msgstr "S’u gjet 'keypass' në config.py!" #: ../fdroidserver/common.py msgid "'keystore' is NONE and 'smartcardoptions' is blank!" -msgstr "" +msgstr "'keystore' është NONE dhe 'smartcardoptions' është e zbrazët!" #: ../fdroidserver/index.py ../fdroidserver/common.py msgid "'keystore' not found in config.py!" @@ -267,16 +272,15 @@ msgstr "Sinjalizo gjithashtu mbi probleme formatimi, bie fjala, rewritemeta -l" #: ../fdroidserver/scanner.py msgid "Android AAR library" -msgstr "" +msgstr "Librari Android AAR" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Kartelë APK Android" #: ../fdroidserver/scanner.py -#, fuzzy msgid "Android DEX code" -msgstr "S’u gjet SDK Android!" +msgstr "Kod DEX Android" #: ../fdroidserver/common.py ../fdroidserver/build.py #, python-brace-format @@ -331,17 +335,17 @@ msgstr "URL bazë për t’u pasqyruar, mund të përfshijë kyçin e nënshkrim #: ../fdroidserver/lint.py #, python-brace-format msgid "Branch '{branch}' used as commit in build '{versionName}'" -msgstr "" +msgstr "Dega '{branch}' u përdor si “commit” në montimin '{versionName}'" #: ../fdroidserver/lint.py #, python-brace-format msgid "Branch '{branch}' used as commit in srclib '{srclib}'" -msgstr "" +msgstr "Dega '{branch}' u përdorur si “commit” në srclib '{srclib}'" #: ../fdroidserver/update.py #, python-brace-format msgid "Broken symlink: {path}" -msgstr "" +msgstr "Simlidhje e dëmtuar: {path}" #: ../fdroid ../fdroidserver/__main__.py msgid "Build a package from source" @@ -353,7 +357,7 @@ msgstr "Monto krejt aplikacionet e mundshme" #: ../fdroidserver/lint.py msgid "Build generated by `fdroid import` - remove disable line once ready" -msgstr "" +msgstr "Montim i prodhuar nga `fdroid import` - hiqni rreshtin e çaktivizimit, pasi të jetë gati" #: ../fdroidserver/checkupdates.py msgid "Build metadata git repo has uncommited changes!" @@ -386,14 +390,14 @@ msgstr "S’lexohet dot \"${path}\"!" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot resolve application ID {appid}" msgstr "S’ftillohet dot ID aplikacioni {appid}" #: ../fdroidserver/rewritemeta.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Cannot rewrite \"{path}\"" -msgstr "S’lexohet dot \"${path}\"!" +msgstr "S’rishkruhet dot \"{path}\"" #: ../fdroidserver/rewritemeta.py msgid "Cannot use --list and --to at the same time" @@ -453,7 +457,7 @@ msgstr "Depozito ndryshimet" #: ../fdroidserver/__main__.py msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." -msgstr "" +msgstr "Argumente që përplasen: '--verbose' dhe '--quiet' s’mund të përdoren në të njëjtën kohë." #: ../fdroidserver/common.py #, python-brace-format @@ -461,14 +465,12 @@ msgid "Could not find '{command}' on your system" msgstr "Në sistemin tuaj s’u gjet '{command}'" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version code" msgstr "S’ u gjet dot kod i versionit më të ri" #: ../fdroidserver/import.py -#, fuzzy msgid "Could not find latest version name" -msgstr "S’ u gjet dot emër versioni më të ri" +msgstr "S’ u gjet dot emër i versionit më të ri" #: ../fdroidserver/update.py #, python-brace-format @@ -482,13 +484,12 @@ msgstr "S’u hap dot kartela apk për analizim" #: ../fdroidserver/common.py #, python-brace-format msgid "Could not parse size \"{size}\", wrong type \"{type}\"" -msgstr "" +msgstr "S’u përtyp dot madhësia \"{size}\", lloj i gabuar \"{type}\"" #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/import.py -#, fuzzy msgid "Couldn't find Application ID" -msgstr "S’u gjet dot ID pakete" +msgstr "S’u gjet dot ID Aplikacione" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/import.py @@ -568,12 +569,12 @@ msgstr "Fshi APK-ra dhe/ose OBB-ra pa tejtëdhëna prej depos" #: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting archive, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Po fshihet arkivi, depoja është shumë e madhe ({size} maks. {limit})" #: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "" +msgstr "Po fshihet historik git-mirror, depoja është shumë e madhe ({size} maks. {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -601,7 +602,7 @@ msgstr "Përshkrimi me gjatësi {length} është mbi kufirin prej {limit} shenja #: ../fdroidserver/import.py msgid "Do not add 'disable:' to the generated build entries" -msgstr "" +msgstr "Mos shtoni 'disable:' te zëra të prodhuar të montimit" #: ../fdroidserver/nightly.py msgid "Do not deploy the new files to the repo" @@ -670,7 +671,7 @@ msgstr "Skano dinamikisht APK-ra pas montimi" #: ../fdroidserver/__main__.py msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" -msgstr "" +msgstr "GABIM: Nënurdhri \"server\" është hequr, përdorni \"deploy\"!" #: ../fdroidserver/mirror.py msgid "" @@ -692,7 +693,7 @@ msgstr "Flamurkë e zbrazët montimi te {linedesc}" #: ../fdroidserver/__main__.py #, python-brace-format msgid "Encoding is set to '{enc}' fdroid might run into encoding issues. Please set it to 'UTF-8' for best results." -msgstr "" +msgstr "Si kodim është caktuar '{enc}'. Fdroid mund të hasë probleme kodimi. Për përfundimet më të mira, caktojeni si 'UTF-8'." #: ../fdroidserver/init.py #, python-format @@ -718,9 +719,9 @@ msgid "Extract signatures from APKs" msgstr "Përfto nënshkrime prej APK-sh" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Failed copying {path}: {error}" -msgstr "S’u arrit të lexohej {path}: {error}" +msgstr "S’u arrit të kopjohej {path}: {error}" #: ../fdroidserver/signatures.py #, python-brace-format @@ -786,7 +787,7 @@ msgstr "U sollën nënshkrime për '{apkfilename}' -> '{sigdir}'" #: ../fdroidserver/update.py #, python-brace-format msgid "File disappeared while processing it: {path}" -msgstr "" +msgstr "Kartela u zhduk teksa përpunohej: {path}" #: ../fdroidserver/verify.py ../fdroidserver/stats.py ../fdroidserver/update.py #: ../fdroidserver/rewritemeta.py ../fdroidserver/build.py @@ -800,9 +801,8 @@ msgid "Flattr donation methods belong in the FlattrID flag" msgstr "Metodat e dhurimit përmes Flattr-i i takojnë flamurkës FlattrID" #: ../fdroidserver/lint.py -#, fuzzy msgid "Flattr donation methods belong in the FlattrID: field" -msgstr "Metodat e dhurimit përmes Flattr-i i takojnë flamurkës FlattrID" +msgstr "Metodat e dhurimit përmes Flattr-i i takojnë fushës FlattrID:" #: ../fdroidserver/lint.py msgid "Forbidden HTML tags" @@ -871,7 +871,7 @@ msgstr "" #: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "" +msgstr "U gjet {apkfilename} te {url}" #: ../fdroidserver/update.py #, python-brace-format @@ -918,22 +918,22 @@ msgstr "Me URL Subversion duhet përdorur HTTPS!" #: ../fdroidserver/deploy.py msgid "If a git mirror gets to big, allow the archive to be deleted" -msgstr "" +msgstr "Nëse një pasqyrë git bëhet shumë e madhe, lejoje arkivin të fshihet" #: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "" +msgstr "Nëse ky ngarkim dështon, provoni ta ngarkoni dorazi te {url}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." -msgstr "" +msgstr "Po shpërfillet '{field}' te tejtëdhëna '{metapath}', ngaqë është nxjerrë nga përdorimi." #: ../fdroidserver/update.py #, python-format msgid "Ignoring FUNDING.yml entry longer than 2048: %s" -msgstr "" +msgstr "Po shpërfillen zëra FUNDING.yml më të gjatë se 2048: %s" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -955,15 +955,15 @@ msgstr "Përfshi APKra që janë nënshkruar me algoritme të çaktivizuar, bie #: ../fdroidserver/mirror.py msgid "Include the PGP signature .asc files in the mirror" -msgstr "" +msgstr "Përfshi te pasqyra kartela .asc nënshkrimi PGP" #: ../fdroidserver/mirror.py msgid "Include the build logs in the mirror" -msgstr "" +msgstr "Përfshi te pasqyra regjistrat e montimive" #: ../fdroidserver/mirror.py msgid "Include the source tarballs in the mirror" -msgstr "" +msgstr "Përfshi te pasqyra paketa tarball" #: ../fdroidserver/common.py msgid "Initialising submodules" @@ -978,7 +978,7 @@ msgid "Install built packages on devices" msgstr "Instalo në pajisje paketat montuara" #: ../fdroidserver/install.py -#, fuzzy, python-format +#, python-format msgid "Installing %s..." msgstr "Po instalohet %s…" @@ -988,7 +988,7 @@ msgid "Installing %s…" msgstr "Po instalohet %s…" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Installing '{apkfilename}' on {dev}..." msgstr "Po instalohet '{apkfilename}' në {dev}…" @@ -1013,7 +1013,7 @@ msgstr "VercodeOperationi pavlefshëm: {field}" #: ../fdroidserver/common.py #, python-brace-format msgid "Invalid application ID {appid}" -msgstr "" +msgstr "ID e pavlefshme aplikacioni {appid}" #: ../fdroidserver/metadata.py #, python-format @@ -1070,17 +1070,17 @@ msgstr "Ridrejtim i pavlefshëm te non-HTTPS: {before} -> {after} " #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid scrlib metadata: '{file}' does not exist" -msgstr "" +msgstr "Tejtëdhëna scrlib të pavlefshme: '{file}' s’ekziston" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: could not parse '{file}'" -msgstr "" +msgstr "Tejtëdhëna srclib të pavlefshme: s’u përtyp dot '{file}'" #: ../fdroidserver/metadata.py #, python-brace-format msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" -msgstr "" +msgstr "Tejtëdhëna srclib të pavlefshme: kyçi panjohur '{key}' te kartela '{file}'" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1099,7 +1099,7 @@ msgstr "Nënshkrimi JAR u verifikua: {path}" #: ../fdroidserver/scanner.py msgid "Java JAR file" -msgstr "" +msgstr "Kartelë JAR Java" #: ../fdroidserver/publish.py ../fdroidserver/update.py #: ../fdroidserver/mirror.py @@ -1108,7 +1108,7 @@ msgstr "S’u gjet Java JDK! Instalojeni në vendndodhje standarde ose caktoni j #: ../fdroidserver/scanner.py msgid "Java compiled class" -msgstr "" +msgstr "Klasë Java e përpiluar" #: ../fdroidserver/signindex.py msgid "Java jarsigner not found! Install in standard location or set java_paths!" @@ -1123,14 +1123,13 @@ msgid "Keystore for signing key:\t" msgstr "Depo kyçesh për kyç nënshkrimi:\t" #: ../fdroidserver/lint.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" -msgstr "Parashtrimi '{commit}' i përdorur së fundi duket si etiketë, por si Mënyrë Kontrolli Përditësimesh është '{ucm}'" +msgstr "Parashtrimi '{commit}' i përdorur së fundi duket si etiketë, por si UpdateCheckMode është '{ucm}'" #: ../fdroidserver/lint.py -#, fuzzy msgid "Liberapay donation methods belong in the Liberapay: field" -msgstr "Metodat e dhurimit përmes Liberapay i takojnë flamurkës Liberapay" +msgstr "Metodat e dhurimit përmes Liberapay i takojnë fushës Liberapay:" #: ../fdroidserver/lint.py msgid "Liberapay donation methods belong in the LiberapayID flag" @@ -1158,7 +1157,7 @@ msgstr "Rresht serverwebroot i keqformuar:" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." -msgstr "" +msgstr "Pasqyro depon e plotë dhe arkivin, krejt llojet e kartelave." #: ../fdroidserver/gpgsign.py msgid "Missing output directory" @@ -1254,7 +1253,7 @@ msgstr "S’ka drejtori të panënshkruar - s’ka ç’bëhet" #: ../fdroidserver/common.py msgid "Not a valid size definition: \"{}\"" -msgstr "" +msgstr "Përkufizim jo i vlefshëm për madhësinë: \"{}\"" #: ../fdroidserver/signindex.py msgid "Nothing to do" @@ -1285,7 +1284,7 @@ msgstr "packagename i OBB-së nuk përputhet me ndonjë APK të mbuluar:" #: ../fdroidserver/deploy.py msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" -msgstr "" +msgstr "Makinë jo në linjë, po anashkalohet prodhim pasqyre git, deri sa `fdroid deploy`" #: ../fdroidserver/common.py #, python-brace-format @@ -1310,9 +1309,8 @@ msgid "Only process apps with auto-updates" msgstr "Kryeje vetëm për aplikacione me vetëpërditësime" #: ../fdroidserver/lint.py -#, fuzzy msgid "OpenCollective donation methods belong in the OpenCollective: field" -msgstr "Metodat e dhurimit përmes Flattr-i i takojnë flamurkës FlattrID" +msgstr "Metodat e dhurimit përmes OpenCollective i takojnë fushës OpenCollective:" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1349,7 +1347,7 @@ msgstr "Po anashkalohet versionName i zbrazët te {apkfilename} prej tejtëdhën #: ../fdroidserver/import.py #, python-brace-format msgid "Package \"{appid}\" already exists" -msgstr "" +msgstr "Paketa \"{appid}\" ekziston tashmë" #: ../fdroidserver/common.py #, python-brace-format @@ -1548,7 +1546,7 @@ msgstr "Skano vetëm versionin më të ri të çdo pakete" #: ../fdroidserver/build.py msgid "Scan the resulting APK(s) for known non-free classes." -msgstr "" +msgstr "Kontrollo për klasa jo të lira të ditura APK-në(të) e prodhuara." #: ../fdroid ../fdroidserver/__main__.py msgid "Scan the source code of a package" @@ -1576,7 +1574,7 @@ msgstr "Vëre sahatin në atë kohë duke përdorur:" #: ../fdroidserver/nightly.py msgid "Set maximum releases in repo before older ones are archived" -msgstr "" +msgstr "Caktoni numër maksimum hedhjesh në qarkullim, përpara se të arkivohen të vjetrat" #: ../fdroidserver/build.py #, python-brace-format @@ -1663,12 +1661,12 @@ msgstr "U la të rrjedhë edhe më tepër informacion se sa normalisht" #: ../fdroidserver/nightly.py #, python-brace-format msgid "Striping mystery signature from {apkfilename}" -msgstr "" +msgstr "Po hiqet nënshkrim misterioz nga {apkfilename}" #: ../fdroidserver/nightly.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Stripping mystery signature from {apkfilename}" -msgstr "Po shpërfillen të dhëna të ndenjura fshehtine për {apkfilename}" +msgstr "Stripping mystery signature from {apkfilename}" #: ../fdroidserver/lint.py #, python-format @@ -1730,7 +1728,7 @@ msgstr "Ka një përplasje keyalias-i - botimi u ndal" #: ../fdroidserver/common.py msgid "These are the apps that have been archived from the main repo." -msgstr "" +msgstr "Këto janë aplikacionet që janë arkivuar nga depoja kryesore." #: ../fdroidserver/import.py #, python-format @@ -1743,7 +1741,7 @@ msgstr "Për të përdorur awsbucket, te config.py duhen ujdisur edhe awssecretk #: ../fdroidserver/lint.py msgid "URL must start with https:// or http://" -msgstr "" +msgstr "URL-ja duhet të fillojë me https:// ose http://" #: ../fdroidserver/lint.py msgid "URL shorteners should not be used" @@ -1759,13 +1757,12 @@ msgid "URL {url} in Description: {error}" msgstr "URL {url} te Përshkrim: {error}" #: ../fdroidserver/lint.py -#, fuzzy msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" -msgstr "Etiketë e pavlefshme licence \"%s\"! Përdorni vetëm etiketa nga https://spdx.org/license-list" +msgstr "Etiketë licence \"{}\" e papritur! Përdorni vetëm etiketa të miratuara nga FSF ose OSI, prej https://spdx.org/license-list" #: ../fdroidserver/lint.py msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" -msgstr "" +msgstr "Etiketë e papritur licence \"{}\"! Përdorni vetëm etiketa licencash të formësuara te kartela e formësimit tuaj" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1793,9 +1790,9 @@ msgid "Unknown metadata format: {path}" msgstr "Format i panjohur tejtëdhënash: {path}" #: ../fdroidserver/metadata.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Unknown metadata format: {path} (use: *.yml)" -msgstr "Format i panjohur tejtëdhënash: {path}" +msgstr "Format i panjohur tejtëdhënash: {path} (përdorni: *.yml)" #: ../fdroidserver/common.py msgid "Unknown version of aapt, might cause problems: " @@ -1876,14 +1873,14 @@ msgid "Unused file at %s" msgstr "Kartelë e papërdorur te %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scandelete path: %s" -msgstr "Kartelë e papërdorur te %s" +msgstr "Shteg scandelete i papërdorur: %s" #: ../fdroidserver/scanner.py -#, fuzzy, python-format +#, python-format msgid "Unused scanignore path: %s" -msgstr "Kartelë e papërdorur te %s" +msgstr "Shteg scanignore i papërdorur: %s" #: ../fdroid ../fdroidserver/__main__.py msgid "Update repo information for new packages" @@ -1922,24 +1919,22 @@ msgstr "UpdateCheckMode është ujdisur, por duket sikur checkupdates s’ësht #. Translators: https://developer.android.com/studio/build/application-id #: ../fdroidserver/lint.py -#, fuzzy msgid "UpdateCheckName is set to the known application ID - it can be removed" -msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" +msgstr "Si UpdateCheckName është caktuar ID-ja e aplikacionit të njohur - s’mund të hiqet" #: ../fdroidserver/lint.py -#, fuzzy msgid "UpdateCheckName is set to the known application ID, it can be removed" -msgstr "Si Emër Kontrolli Përditësimesh është caktuar ID aplikacioni i njohur - s’mund të hiqet" +msgstr "Si UpdateCheckName është caktuar ID aplikacioni të njohur - s’mund të hiqet" #: ../fdroidserver/deploy.py #, python-brace-format msgid "Uploading {apkfilename} to androidobservatory.org" -msgstr "" +msgstr "Po ngarkohet {apkfilename} te androidobservatory.org" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Uploading {apkfilename} to virustotal" -msgstr "Po lexohet {apkfilename} prej fshehtine" +msgstr "Po ngarkohet {apkfilename} to virustotal" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -1978,11 +1973,11 @@ msgstr "Po përdoret \"{path}\" për formësim të s3cmd." #: ../fdroidserver/common.py msgid "Using APK Signature v2" -msgstr "" +msgstr "Po përdoret Nënshkrimi APK-je v2" #: ../fdroidserver/common.py msgid "Using APK Signature v3" -msgstr "" +msgstr "Po përdoret Nënshkrimi APK-je v3" #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" @@ -2022,7 +2017,7 @@ msgstr "Po verifikohet nënshkrim treguesi:" #: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." -msgstr "" +msgstr "Kyçi API VirusTotal s’mund të ngarkojë kartela më të mëdha se 2MB, përdorni {url} që të ngarkoni {path}." #: ../fdroid ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" @@ -2037,7 +2032,7 @@ msgid "When linting the entire repository yamllint is disabled by default. This msgstr "" msgid "X.509 'Distiguished Name' used when generating keys" -msgstr "" +msgstr "X.509 'Distinguished Name' i përdorur teksa prodhoheshin kyçe" #: ../fdroidserver/init.py msgid "X.509 'Distinguished Name' used when generating keys" @@ -2049,7 +2044,7 @@ msgstr "Mund të përdorni ANDROID_HOME që të caktoni shtegun për te SDK-ja j #: ../fdroidserver/scanner.py msgid "ZIP file archive" -msgstr "" +msgstr "Arkiv kartelash ZIP" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2075,20 +2070,18 @@ msgstr "mundësi e dykuptimtë: %s (%s?)" #: ../fdroidserver/common.py msgid "apksigner not found, it's required for signing!" -msgstr "" +msgstr "S’u gjet apksigner, është i domosdoshëm për nënshkrim!" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py #: ../fdroidserver/checkupdates.py -#, fuzzy msgid "application ID of file to operate on" -msgstr "applicationId për të cilin të kontrollohet për përditësime" +msgstr "ID aplikacioni e kartelës mbi të cilën të veprohet" #: ../fdroidserver/verify.py ../fdroidserver/publish.py #: ../fdroidserver/build.py ../fdroidserver/scanner.py #: ../fdroidserver/install.py -#, fuzzy msgid "application ID with optional versionCode in the form APPID[:VERCODE]" -msgstr "applicationId me versionCode opsional në formën APPID[:VERCODE]" +msgstr "ID aplikacioni me versionCode opsional në formën APPID[:VERCODE]" #: ../fdroidserver/lint.py ../fdroidserver/rewritemeta.py msgid "applicationId in the form APPID" @@ -2112,9 +2105,8 @@ msgid "argument \"-\" with mode %r" msgstr "argument \"-\" me mënyrën %r" #: ../fdroidserver/nightly.py -#, fuzzy msgid "attempting bare SSH connection to test deploy key:" -msgstr "po tentohet lidhje ssh e zhveshur, për të testuar kyç sendërtimesh:" +msgstr "po tentohet lidhje SSH e zhveshur, për të testuar kyç sendërtimesh:" #: ../fdroidserver/nightly.py msgid "attempting bare ssh connection to test deploy key:" @@ -2122,7 +2114,7 @@ msgstr "po tentohet lidhje ssh e zhveshur, për të testuar kyç sendërtimesh:" #: ../fdroidserver/common.py msgid "can not parse scrlib spec (not a string): '{}'" -msgstr "" +msgstr "s’përtyp dot specifikim scrlib (s’është një varg): '{}'" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2131,9 +2123,9 @@ msgid "can't open '%s': %s" msgstr "s’hapet dot '%s': %s" #: ../fdroidserver/build.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "cannot find required srclibs: \"{path}\"" -msgstr "S’gjendet dot një appid për {path}!" +msgstr "s’gjenden dot srclibs të domosdoshme: \"{path}\"" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2161,7 +2153,7 @@ msgstr "urdhër për t’u ekzekutuar, ose 'init', ose 'update'" #: ../fdroidserver/__main__.py msgid "commands from plugin modules:" -msgstr "" +msgstr "urdhra prej modulesh shtojce:" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2184,15 +2176,15 @@ msgstr "po kopjohet {apkfilename} te {path}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "could not parse '{path}'" -msgstr "" +msgstr "s’u përtyp dot '{path}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (no ref specified): '{}'" -msgstr "" +msgstr "s’u përtyp dot specifikim scrlib (s’u dha referencë): '{}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (too many '@' signs): '{}'" -msgstr "" +msgstr "s’u përtyp dot specifikim scrlib (shumë shenja '@'): '{}'" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2222,7 +2214,7 @@ msgstr "dest= është e domosdoshme për mundësi si %r" #: ../fdroidserver/scanner.py msgid "executable binary, possibly code" -msgstr "" +msgstr "dyor i ekzekutueshëm, ka gjasa të jetë kod" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2279,7 +2271,7 @@ msgstr "veprimi “git svn clone” dështoi" #: ../fdroidserver/scanner.py msgid "gzip file archive" -msgstr "" +msgstr "Arkiv gzip kartelash" #: /usr/lib/python3.5/argparse.py /usr/lib/python3.6/argparse.py #: /usr/lib/python3.7/argparse.py @@ -2464,20 +2456,20 @@ msgstr "mos pranon shkarkim përmes lidhjeje http të pasigurt (përdorni https #: ../fdroidserver/index.py #, python-format msgid "repo_icon %s does not exist, generating placeholder." -msgstr "" +msgstr "repo_icon %s s’ekziston, po prodhohet vendmbajtëse." #: ../fdroidserver/metadata.py msgid "ruamel.yaml not installed, can not write metadata." -msgstr "" +msgstr "ruamel.yaml s’është i instalaur, s’mund të shkruhen tejtëdhëna." #: ../fdroidserver/deploy.py ../fdroidserver/upload.py #, python-brace-format msgid "s3cmd sync indexes {path} to {url} and delete" -msgstr "" +msgstr "s3cmd sync indexes {path} to {url} and delete" #: ../fdroidserver/scanner.py msgid "shared library" -msgstr "" +msgstr "librari e përbashkët" #: /usr/lib/python3.5/optparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/optparse.py @@ -2513,7 +2505,7 @@ msgstr "srclibs-it i mungon emër dhe/ose @" #: ../fdroidserver/scanner.py msgid "static library" -msgstr "" +msgstr "librari statike" #: ../fdroidserver/common.py #, python-brace-format @@ -2569,7 +2561,7 @@ msgstr "" #: ../fdroidserver/update.py msgid "wiki support is deprecated and will be removed in the next release!" -msgstr "" +msgstr "Mbulimi për wiki është nxjerrë nga përdorimi dhe do të hiqet në hedhjen e ardhshme në qarkullim!" #: ../fdroidserver/publish.py #, python-brace-format @@ -2594,9 +2586,9 @@ msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " msgstr "AndroidManifest.xml e {apkfilename} ka një datë të gabuar: " #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{appid} does not have a name! Using application ID instead." -msgstr "{appid} s’ka emër! Në vend të tij po përdoret emër pakete." +msgstr "{appid} s’ka emër! Në vend të tij po përdoret ID aplikacioni." #: ../fdroidserver/update.py #, python-brace-format @@ -2609,9 +2601,9 @@ msgid "{appid} from {path} is not a valid Android Package Name!" msgstr "{appid} prej {path} s’është Emër i vlefshëm Pakete Android!" #: ../fdroidserver/update.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{appid} from {path} is not a valid Android application ID!" -msgstr "{appid} prej {path} s’është Emër i vlefshëm Pakete Android!" +msgstr "{appid} prej {path} s’është ID e vlefshme aplikacioni Android!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format @@ -2647,7 +2639,7 @@ msgstr "{appid}: {field} duhet të jetë një '{type}', por është një '{field #: ../fdroidserver/metadata.py #, python-brace-format msgid "{build_flag} must be an integer, found: {value}" -msgstr "" +msgstr "{build_flag} duhet të jetë numër i plotë, u gjet: {value}" #: ../fdroidserver/metadata.py #, python-brace-format @@ -2657,7 +2649,7 @@ msgstr "{field} e papërfunduar te {name}" #: ../fdroidserver/metadata.py #, python-brace-format msgid "{file} is blank or corrupt!" -msgstr "" +msgstr "{file} është e zbrazët ose e dëmtuar!" #: ../fdroidserver/update.py #, python-brace-format @@ -2667,7 +2659,7 @@ msgstr "{name} \"{path}\" s’ekziston! Ndreqeni te config.py." #: ../fdroidserver/import.py #, python-brace-format msgid "{path} already exists, ignoring import results!" -msgstr "" +msgstr "{path} ekziston tashmë, po shpërfillen përfundimet e importimit!" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2687,7 +2679,7 @@ msgstr "{path} është me madhësi zero!" #: ../fdroidserver/deploy.py #, python-brace-format msgid "{path} more than 200MB, manually upload: {url}" -msgstr "" +msgstr "{path} më tepër se 200MB, ngarkojeni dorazi: {url}" #: ../fdroidserver/mirror.py #, python-brace-format @@ -2695,9 +2687,9 @@ msgid "{url} does not end with \"fdroid\", check the URL path!" msgstr "{url} s’përfundon me \"fdroid\", kontrolloni shtegun e URL-së!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{url} does not start with \"http\"!" -msgstr "{url} s’përfundon me \"fdroid\", kontrolloni shtegun e URL-së!" +msgstr "{url} nuk fillon me \"http\"!" #: ../fdroidserver/build.py msgid "{} build failed" From 5eb5a65c19768da53820a2d4369face81b385b46 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 25 Nov 2020 17:40:50 +0100 Subject: [PATCH 0625/2775] Translated using Weblate: Russian (ru) by Roman Currently translated at 84.4% (484 of 573 strings) Co-authored-by: Roman Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/ru/ Translation: F-Droid/F-Droid Server --- locale/ru/LC_MESSAGES/fdroidserver.po | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 3482e610..341611d3 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -7,13 +7,14 @@ # gardenapple , 2020. # Boris Timofeev , 2020. # Hans-Christoph Steiner , 2020. +# Roman , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 1.0.0-95-gd7af22b\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-11-10 16:21+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-11-18 17:28+0000\n" +"Last-Translator: Roman \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -2496,7 +2497,7 @@ msgstr "показать номер версии программы и выйт #: /usr/lib/python3.6/argparse.py /usr/lib/python3.6/optparse.py #: /usr/lib/python3.7/argparse.py /usr/lib/python3.7/optparse.py msgid "show this help message and exit" -msgstr "показать справочное сообщение и выйти" +msgstr "показать это справочное сообщение и выйти" #: ../fdroidserver/signatures.py msgid "signed APK, either a file-path or HTTPS URL." @@ -2573,7 +2574,7 @@ msgstr "Аpache libcloud: синхронизация с {url}" #: ../fdroidserver/deploy.py msgid "virustotal.com is rate limiting, waiting to retry..." -msgstr "" +msgstr "virustotal.com ограничивает траффик, ждем повторной попытки..." #: ../fdroidserver/update.py msgid "wiki support is deprecated and will be removed in the next release!" From fda56302a3604539f3b8154d609df35aa876481d Mon Sep 17 00:00:00 2001 From: Alvaro Date: Wed, 25 Nov 2020 17:40:50 +0100 Subject: [PATCH 0626/2775] Translated using Weblate: Spanish (es) by Alvaro Currently translated at 55.6% (319 of 573 strings) Co-authored-by: Alvaro Translate-URL: https://hosted.weblate.org/projects/f-droid/fdroidserver/es/ Translation: F-Droid/F-Droid Server --- locale/es/LC_MESSAGES/fdroidserver.po | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index c848753b..aba7edc4 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -4,13 +4,14 @@ # Maximiliano Castañón , 2020. # Jo , 2020. # Hans-Christoph Steiner , 2020. +# Alvaro , 2020. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" "POT-Creation-Date: 2020-10-21 18:05+0200\n" -"PO-Revision-Date: 2020-11-10 16:20+0000\n" -"Last-Translator: Hans-Christoph Steiner \n" +"PO-Revision-Date: 2020-11-20 23:28+0000\n" +"Last-Translator: Alvaro \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" @@ -280,7 +281,7 @@ msgstr "" #: ../fdroidserver/scanner.py msgid "Android APK file" -msgstr "" +msgstr "Fichero APK de Android" #: ../fdroidserver/scanner.py #, fuzzy From 393f88b41ee8030bd8c4b361c8f858d7b2853220 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 25 Nov 2020 17:45:00 +0100 Subject: [PATCH 0627/2775] second alpha 2.0 release 2.0a1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 26722299..31cd1eb9 100755 --- a/setup.py +++ b/setup.py @@ -53,7 +53,7 @@ with open("README.md", "r") as fh: long_description = fh.read() setup(name='fdroidserver', - version='2.0a0', + version='2.0a1', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From 2cb0ff4578c6163f064b70619e65dd6704ae6db5 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Thu, 26 Nov 2020 17:47:04 +0100 Subject: [PATCH 0628/2775] Support underscore (_) in versionCode Example: https://github.com/ubergeek42/weechat-android/blob/v1.3.1/app/build.gradle.kts#L67 --- fdroidserver/common.py | 2 +- tests/common.TestCase | 13 +++++++++++++ .../com.kunzisoft.testcase/build.gradle | 10 ++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 06970d1f..932ab28a 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1520,7 +1520,7 @@ def remove_debuggable_flags(root_dir): os.path.join(root, 'AndroidManifest.xml')) -vcsearch_g = re.compile(r'''\b[Vv]ersionCode\s*=?\s*["']*([0-9]+)["']*''').search +vcsearch_g = re.compile(r'''\b[Vv]ersionCode\s*=?\s*["']*([0-9_]+)["']*''').search vnsearch_g = re.compile(r'''\b[Vv]ersionName\s*=?\s*(["'])((?:(?=(\\?))\3.)*?)\1''').search vnssearch_g = re.compile(r'''\b[Vv]ersionNameSuffix\s*=?\s*(["'])((?:(?=(\\?))\3.)*?)\1''').search psearch_g = re.compile(r'''\b(packageName|applicationId)\s*=*\s*["']([^"']+)["']''').search diff --git a/tests/common.TestCase b/tests/common.TestCase index eff088d6..2677c5f7 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1043,6 +1043,19 @@ class CommonTest(unittest.TestCase): self.assertEqual(('1.0-free', '1', 'com.kunzisoft.fdroidtest.applicationidsuffix'), fdroidserver.common.parse_androidmanifests(paths, app)) + app = fdroidserver.metadata.App() + build = fdroidserver.metadata.Build() + build.gradle = ['underscore'] + app.builds = [build] + app.id = 'com.kunzisoft.fdroidtest.applicationidsuffix.underscore' + paths = [ + os.path.join('source-files', 'com.kunzisoft.testcase', 'build.gradle'), + ] + for path in paths: + self.assertTrue(os.path.isfile(path)) + self.assertEqual(('20180430-underscore', '2018_04_30', 'com.kunzisoft.fdroidtest.applicationidsuffix.underscore'), + fdroidserver.common.parse_androidmanifests(paths, app)) + def test_get_all_gradle_and_manifests(self): a = fdroidserver.common.get_all_gradle_and_manifests(os.path.join('source-files', 'cn.wildfirechat.chat')) paths = [ diff --git a/tests/source-files/com.kunzisoft.testcase/build.gradle b/tests/source-files/com.kunzisoft.testcase/build.gradle index 4319e20d..2753d058 100644 --- a/tests/source-files/com.kunzisoft.testcase/build.gradle +++ b/tests/source-files/com.kunzisoft.testcase/build.gradle @@ -49,6 +49,16 @@ android { // Version code : 1 // Version name : 1.0-free } + underscore { + applicationIdSuffix = ".underscore" + versionCode 2018_04_30 + versionName "20180430-underscore" + buildConfigField "boolean", "FULL_VERSION", "true" + buildConfigField "boolean", "CLOSED_STORE", "true" + // ApplicationId : com.kunzisoft.fdroidtest.applicationidsuffix.underscore + // Version code : 2018_04_30 + // Version name : 20180430-underscore + } } } From 66414a9fc7096cc6f4a3b5e305400741d05f8df1 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Thu, 26 Nov 2020 22:52:52 +0100 Subject: [PATCH 0629/2775] find_sdk_tools_cmd returns non if aapt is not found --- tests/common.TestCase | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/common.TestCase b/tests/common.TestCase index eff088d6..fc968c0f 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -715,10 +715,9 @@ class CommonTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config self._set_build_tools() - try: + aapt = fdroidserver.common.find_sdk_tools_cmd('aapt') + if aapt: config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') - except fdroidserver.exception.FDroidException: - pass # aapt is not required if androguard is present testcases = [ ('repo/obb.main.twoversions_1101613.apk', 'obb.main.twoversions', '1101613', '0.1'), From 60748acb9d39098fb52638bb67cbb9a35a11840e Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Thu, 26 Nov 2020 23:13:30 +0100 Subject: [PATCH 0630/2775] Add missing test files --- MANIFEST.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MANIFEST.in b/MANIFEST.in index 175901c5..e8ded55f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -604,6 +604,7 @@ include tests/metadata-rewrite-yml/org.fdroid.fdroid.yml include tests/metadata/souch.smsbypass.yml include tests/metadata.TestCase include tests/minimal_targetsdk_30_unsigned.apk +include tests/no_targetsdk_minsdk1_unsigned.apk include tests/openssl-version-check-test.py include tests/org.bitbucket.tickytacky.mirrormirror_1.apk include tests/org.bitbucket.tickytacky.mirrormirror_2.apk @@ -675,6 +676,7 @@ include tests/signindex/guardianproject-v1.jar include tests/signindex/testy.jar include tests/signindex/unsigned.jar include tests/source-files/at.bitfire.davdroid/build.gradle +include tests/source-files/cn.wildfirechat.chat include tests/source-files/com.kunzisoft.testcase/build.gradle include tests/source-files/com.nextcloud.client/build.gradle include tests/source-files/com.nextcloud.client.dev/src/generic/fastlane/metadata/android/en-US/full_description.txt From 5c36f844301e499785a6a559dc9d18fd9310a73d Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Thu, 26 Nov 2020 23:13:37 +0100 Subject: [PATCH 0631/2775] Ignore non version number entries in build_tools_path --- fdroidserver/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 06970d1f..fb2bbdab 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -480,7 +480,7 @@ def find_apksigner(): if not os.path.isdir(build_tools_path): return None for f in sorted(os.listdir(build_tools_path), reverse=True): - if not os.path.isdir(os.path.join(build_tools_path, f)): + if not os.path.isdir(os.path.join(build_tools_path, f)) or not isinstance(LooseVersion(f), int): continue if LooseVersion(f) < LooseVersion(MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION): return None From 2cca336a2997f90eb3587f8b127e4e153d05e754 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 27 Nov 2020 11:19:24 +0100 Subject: [PATCH 0632/2775] add gradle 6.7.1 --- gradlew-fdroid | 3 ++- makebuildserver | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gradlew-fdroid b/gradlew-fdroid index a7acb6fe..8ccb7a67 100755 --- a/gradlew-fdroid +++ b/gradlew-fdroid @@ -142,6 +142,7 @@ get_sha() { '6.6') echo 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025' ;; '6.6.1') echo '7873ed5287f47ca03549ab8dcb6dc877ac7f0e3d7b1eb12685161d10080910ac' ;; '6.7') echo '8ad57759019a9233dc7dc4d1a530cefe109dc122000d57f7e623f8cf4ba9dfc4' ;; + '6.7.1') echo '3239b5ed86c3838a37d983ac100573f64c1f3fd8e1eb6c89fa5f9529b5ec091d' ;; *) exit 1 esac } @@ -162,7 +163,7 @@ d_plugin_k=(4.1 4.0 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.3 2.2 2.1.3 2.1 2.0 1.5 d_plugin_v=(6.5 6.1.1 5.6.4 5.4.1 5.1.1 4.10.1 4.6 4.4 4.1 3.3 2.14.1 2.14.1 2.12 2.12 2.4 2.4 2.3 2.2.1 2.2.1 2.1 2.1 1.12 1.12 1.12 1.11 1.10 1.9 1.8 1.6 1.6 1.4 1.4) # All gradle versions we know about -plugin_v=(6.7 6.6.1 6.6 6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) +plugin_v=(6.7.1 6.7 6.6.1 6.6 6.5.1 6.5 6.4.1 6.4 6.3 6.2.2 6.2.1 6.2 6.1.1 6.1 6.0.1 6.0 5.6.4 5.6.3 5.6.2 5.6.1 5.6 5.5.1 5.5 5.4.1 5.4 5.3.1 5.3 5.2.1 5.2 5.1.1 5.1 5.0 4.10.3 4.10.2 4.10.1 4.10 4.9 4.8.1 4.8 4.7 4.6 4.5.1 4.5 4.4.1 4.4 4.3.1 4.3 4.2.1 4.2 4.1 4.0.2 4.0.1 4.0 3.5.1 3.5 3.4.1 3.4 3.3 3.2.1 3.2 3.1 3.0 2.14.1 2.14 2.13 2.12 2.11 2.10 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2.1 2.2 2.1 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.4) v_all=${plugin_v[@]} diff --git a/makebuildserver b/makebuildserver index 62f4c255..347c73fb 100755 --- a/makebuildserver +++ b/makebuildserver @@ -397,8 +397,8 @@ CACHE_FILES = [ '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a'), ('https://services.gradle.org/distributions/gradle-6.6.1-bin.zip', '7873ed5287f47ca03549ab8dcb6dc877ac7f0e3d7b1eb12685161d10080910ac'), - ('https://services.gradle.org/distributions/gradle-6.7-bin.zip', - '8ad57759019a9233dc7dc4d1a530cefe109dc122000d57f7e623f8cf4ba9dfc4'), + ('https://services.gradle.org/distributions/gradle-6.7.1-bin.zip', + '3239b5ed86c3838a37d983ac100573f64c1f3fd8e1eb6c89fa5f9529b5ec091d'), ('https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin', '102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'), ('https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip', From 1e8093ff6e744a3cbda346031104b3e58c77234e Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sun, 29 Nov 2020 09:26:17 +0100 Subject: [PATCH 0633/2775] Revert "find_sdk_tools_cmd returns non if aapt is not found" This reverts commit 66414a9fc7096cc6f4a3b5e305400741d05f8df1. --- tests/common.TestCase | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/common.TestCase b/tests/common.TestCase index 158f7701..2677c5f7 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -715,9 +715,10 @@ class CommonTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config self._set_build_tools() - aapt = fdroidserver.common.find_sdk_tools_cmd('aapt') - if aapt: + try: config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') + except fdroidserver.exception.FDroidException: + pass # aapt is not required if androguard is present testcases = [ ('repo/obb.main.twoversions_1101613.apk', 'obb.main.twoversions', '1101613', '0.1'), From 1c7df94e760b5f332dcf844610daea06308f46be Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 27 Nov 2020 13:36:27 +0100 Subject: [PATCH 0634/2775] purge unneeded 'build_tools' config option Back when fdroidserver was built around aapt, that was needed to guarantee that a compatible version of aapt was used. Now, aapt is only optionally used for getting the APK ID, so this was just complicating maintenance. --- examples/config.yml | 3 --- fdroidserver/common.py | 31 ++++++------------------------- tests/build.TestCase | 19 ++----------------- tests/common.TestCase | 5 ++--- tests/vcs.TestCase | 1 - 5 files changed, 10 insertions(+), 49 deletions(-) diff --git a/examples/config.yml b/examples/config.yml index 555699fd..484ecc71 100644 --- a/examples/config.yml +++ b/examples/config.yml @@ -31,9 +31,6 @@ # java_paths: # 8: /usr/lib/jvm/java-8-openjdk -# Build tools version to be used -# build_tools: 28.0.3 - # Command or path to binary for running Ant # ant: ant diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 19a9abef..9e4f82bf 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -115,7 +115,6 @@ default_config = { 'r16b': None, }, 'cachedir': os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), - 'build_tools': MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION, 'java_paths': None, 'scan_binary': False, 'ant': "ant", @@ -498,18 +497,10 @@ def find_sdk_tools_cmd(cmd): tooldirs = [] if config is not None and 'sdk_path' in config and os.path.exists(config['sdk_path']): # try to find a working path to this command, in all the recent possible paths - if 'build_tools' in config: - build_tools = os.path.join(config['sdk_path'], 'build-tools') - # if 'build_tools' was manually set and exists, check only that one - configed_build_tools = os.path.join(build_tools, config['build_tools']) - if os.path.exists(configed_build_tools): - tooldirs.append(configed_build_tools) - else: - # no configed version, so hunt known paths for it - for f in sorted(os.listdir(build_tools), reverse=True): - if os.path.isdir(os.path.join(build_tools, f)): - tooldirs.append(os.path.join(build_tools, f)) - tooldirs.append(build_tools) + build_tools = os.path.join(config['sdk_path'], 'build-tools') + for f in sorted(os.listdir(build_tools), reverse=True): + if os.path.isdir(os.path.join(build_tools, f)): + tooldirs.append(os.path.join(build_tools, f)) sdk_tools = os.path.join(config['sdk_path'], 'tools') if os.path.exists(sdk_tools): tooldirs.append(sdk_tools) @@ -525,7 +516,8 @@ def find_sdk_tools_cmd(cmd): test_aapt_version(path) return path # did not find the command, exit with error message - ensure_build_tools_exists(config) + if not test_sdk_exists(config): + raise FDroidException(_("Android SDK not found!")) def test_aapt_version(aapt): @@ -578,17 +570,6 @@ def test_sdk_exists(thisconfig): return True -def ensure_build_tools_exists(thisconfig): - if not test_sdk_exists(thisconfig): - raise FDroidException(_("Android SDK not found!")) - build_tools = os.path.join(thisconfig['sdk_path'], 'build-tools') - versioned_build_tools = os.path.join(build_tools, thisconfig['build_tools']) - if not os.path.isdir(versioned_build_tools): - raise FDroidException( - _("Android build-tools path '{path}' does not exist!") - .format(path=versioned_build_tools)) - - def get_local_metadata_files(): '''get any metadata files local to an app's source repo diff --git a/tests/build.TestCase b/tests/build.TestCase index ea1af963..a696f196 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -28,23 +28,10 @@ import fdroidserver.scanner class BuildTest(unittest.TestCase): '''fdroidserver/build.py''' - def _set_build_tools(self): - build_tools = os.path.join(fdroidserver.common.config['sdk_path'], 'build-tools') - if os.path.exists(build_tools): - fdroidserver.common.config['build_tools'] = '' - for f in sorted(os.listdir(build_tools), reverse=True): - versioned = os.path.join(build_tools, f) - if os.path.isdir(versioned) \ - and os.path.isfile(os.path.join(versioned, 'aapt')): - fdroidserver.common.config['build_tools'] = versioned - break - return True - else: - print('no build-tools found: ' + build_tools) - return False - def setUp(self): logging.basicConfig(level=logging.DEBUG) + logger = logging.getLogger('androguard.axml') + logger.setLevel(logging.INFO) # tame the axml debug messages self.basedir = os.path.join(localmodule, 'tests') self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) if not os.path.exists(self.tmpdir): @@ -56,7 +43,6 @@ class BuildTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config fdroidserver.build.config = config - self._set_build_tools() try: config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') except fdroidserver.exception.FDroidException: @@ -183,7 +169,6 @@ class BuildTest(unittest.TestCase): config = dict() config['sdk_path'] = os.getenv('ANDROID_HOME') config['ndk_paths'] = {'r10d': os.getenv('ANDROID_NDK_HOME')} - config['build_tools'] = 'FAKE_BUILD_TOOLS_VERSION' fdroidserver.common.config = config app = fdroidserver.metadata.App() app.id = 'com.gpl.rpg.AndorsTrail' diff --git a/tests/common.TestCase b/tests/common.TestCase index 2677c5f7..d42bfe85 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -42,6 +42,8 @@ class CommonTest(unittest.TestCase): def setUp(self): logging.basicConfig(level=logging.DEBUG) + logger = logging.getLogger('androguard.axml') + logger.setLevel(logging.INFO) # tame the axml debug messages self.basedir = os.path.join(localmodule, 'tests') self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) if not os.path.exists(self.tmpdir): @@ -75,12 +77,10 @@ class CommonTest(unittest.TestCase): def _set_build_tools(self): build_tools = os.path.join(fdroidserver.common.config['sdk_path'], 'build-tools') if os.path.exists(build_tools): - fdroidserver.common.config['build_tools'] = '' for f in sorted(os.listdir(build_tools), reverse=True): versioned = os.path.join(build_tools, f) if os.path.isdir(versioned) \ and os.path.isfile(os.path.join(versioned, 'apksigner')): - fdroidserver.common.config['build_tools'] = versioned break return True else: @@ -235,7 +235,6 @@ class CommonTest(unittest.TestCase): config = dict() config['sdk_path'] = os.getenv('ANDROID_HOME') config['ndk_paths'] = {'r10d': os.getenv('ANDROID_NDK_HOME')} - config['build_tools'] = 'FAKE_BUILD_TOOLS_VERSION' fdroidserver.common.config = config app = fdroidserver.metadata.App() app.id = 'org.fdroid.froid' diff --git a/tests/vcs.TestCase b/tests/vcs.TestCase index a94521fa..a7e7c758 100755 --- a/tests/vcs.TestCase +++ b/tests/vcs.TestCase @@ -59,7 +59,6 @@ class VCSTest(unittest.TestCase): os.mkdir("build") config['sdk_path'] = 'MOCKPATH' config['ndk_paths'] = {'r10d': os.getenv('ANDROID_NDK_HOME')} - config['build_tools'] = 'FAKE_BUILD_TOOLS_VERSION' config['java_paths'] = {'fake': 'fake'} fdroidserver.common.config = config app = fdroidserver.metadata.App() From ce10fcb7591c49aa747404294f2b71fe7243098e Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sun, 29 Nov 2020 10:02:30 +0100 Subject: [PATCH 0635/2775] Check if build_tools path exists before listdir --- fdroidserver/common.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 9e4f82bf..2b82526c 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -498,9 +498,10 @@ def find_sdk_tools_cmd(cmd): if config is not None and 'sdk_path' in config and os.path.exists(config['sdk_path']): # try to find a working path to this command, in all the recent possible paths build_tools = os.path.join(config['sdk_path'], 'build-tools') - for f in sorted(os.listdir(build_tools), reverse=True): - if os.path.isdir(os.path.join(build_tools, f)): - tooldirs.append(os.path.join(build_tools, f)) + if os.path.isdir(build_tools): + for f in sorted(os.listdir(build_tools), reverse=True): + if os.path.isdir(os.path.join(build_tools, f)): + tooldirs.append(os.path.join(build_tools, f)) sdk_tools = os.path.join(config['sdk_path'], 'tools') if os.path.exists(sdk_tools): tooldirs.append(sdk_tools) From 4d78d79280125d36cae831b614124ff57aabff36 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sun, 29 Nov 2020 19:04:12 +0100 Subject: [PATCH 0636/2775] Revert "Ignore non version number entries in build_tools_path" This reverts commit 5c36f844301e499785a6a559dc9d18fd9310a73d. --- fdroidserver/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 19a9abef..932ab28a 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -480,7 +480,7 @@ def find_apksigner(): if not os.path.isdir(build_tools_path): return None for f in sorted(os.listdir(build_tools_path), reverse=True): - if not os.path.isdir(os.path.join(build_tools_path, f)) or not isinstance(LooseVersion(f), int): + if not os.path.isdir(os.path.join(build_tools_path, f)): continue if LooseVersion(f) < LooseVersion(MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION): return None From 25b1f3fe8cc23f0ab35d2178db7de1d081760b61 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sun, 29 Nov 2020 19:04:35 +0100 Subject: [PATCH 0637/2775] Ignore non version number entries in build_tools_path LooseVersion('debian') stay a string and results in a type error. --- fdroidserver/common.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 932ab28a..d821375a 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -482,8 +482,11 @@ def find_apksigner(): for f in sorted(os.listdir(build_tools_path), reverse=True): if not os.path.isdir(os.path.join(build_tools_path, f)): continue - if LooseVersion(f) < LooseVersion(MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION): - return None + try: + if LooseVersion(f) < LooseVersion(MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION): + return None + except TypeError: + continue if os.path.exists(os.path.join(build_tools_path, f, 'apksigner')): apksigner = os.path.join(build_tools_path, f, 'apksigner') logging.info("Using %s " % apksigner) From df160170ca830630b53dc3b797d96539f572713a Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sat, 28 Nov 2020 11:47:26 +0100 Subject: [PATCH 0638/2775] Run test on sdist --- .gitlab-ci.yml | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2adbfc76..dc82c2e4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -113,24 +113,12 @@ ubuntu_lts_ppa: ubuntu_xenial_pip: image: ubuntu:xenial <<: *apt-template - only: - - master@fdroid/fdroidserver script: - apt-get install git default-jdk-headless python3-pip python3-venv rsync zipalign libarchive13 - rm -rf env - pyvenv env - . env/bin/activate - $pip install --upgrade babel pip setuptools - - $pip install -e . - - ./setup.py compile_catalog - - ./tests/run-tests - -pip_install: - image: archlinux/base - only: - - master@fdroid/fdroidserver - script: - - pacman --sync --sysupgrade --refresh --noconfirm git grep python-pip python-virtualenv tar # setup venv to act as release build machine - python -m venv sdist-env - . sdist-env/bin/activate @@ -138,8 +126,16 @@ pip_install: - deactivate - tar tzf dist/fdroidserver-*.tar.gz | grep locale/de/LC_MESSAGES/fdroidserver.mo # back to bare machine to act as user's install machine - - pip install dist/fdroidserver-*.tar.gz + - $pip install --upgrade pip setuptools + - $pip install dist/fdroidserver-*.tar.gz - test -e /usr/share/locale/de/LC_MESSAGES/fdroidserver.mo + - ./tests/run-tests + +pip_install: + image: archlinux/base + script: + - pacman --sync --sysupgrade --refresh --noconfirm git grep python-pip python-virtualenv tar + - pip install -e . - fdroid - fdroid readmeta - fdroid update --help From 4b2e32389945849e85fc49b8bec5973fd3dc3090 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sat, 28 Nov 2020 11:57:23 +0100 Subject: [PATCH 0639/2775] Install more test files --- MANIFEST.in | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index e8ded55f..4a6a5671 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -543,6 +543,7 @@ include tests/dummy-keystore.jks include tests/dump_internal_metadata_format.py include tests/exception.TestCase include tests/extra/manual-vmtools-test.py +include tests/funding-usernames.yaml include tests/getsig/getsig.java include tests/getsig/make.sh include tests/getsig/run.sh @@ -550,6 +551,7 @@ include tests/gnupghome/pubring.gpg include tests/gnupghome/random_seed include tests/gnupghome/secring.gpg include tests/gnupghome/trustdb.gpg +include tests/gradle-maven-blocks.yaml include tests/import_proxy.py include tests/import.TestCase include tests/index.TestCase @@ -605,6 +607,7 @@ include tests/metadata/souch.smsbypass.yml include tests/metadata.TestCase include tests/minimal_targetsdk_30_unsigned.apk include tests/no_targetsdk_minsdk1_unsigned.apk +include tests/no_targetsdk_minsdk30_unsigned.apk include tests/openssl-version-check-test.py include tests/org.bitbucket.tickytacky.mirrormirror_1.apk include tests/org.bitbucket.tickytacky.mirrormirror_2.apk @@ -676,7 +679,34 @@ include tests/signindex/guardianproject-v1.jar include tests/signindex/testy.jar include tests/signindex/unsigned.jar include tests/source-files/at.bitfire.davdroid/build.gradle -include tests/source-files/cn.wildfirechat.chat +include tests/source-files/cn.wildfirechat.chat/avenginekit/build.gradle +include tests/source-files/cn.wildfirechat.chat/build.gradle +include tests/source-files/cn.wildfirechat.chat/chat/build.gradle +include tests/source-files/cn.wildfirechat.chat/client/build.gradle +include tests/source-files/cn.wildfirechat.chat/client/src/main/AndroidManifest.xml +include tests/source-files/cn.wildfirechat.chat/emojilibrary/build.gradle +include tests/source-files/cn.wildfirechat.chat/gradle/build_libraries.gradle +include tests/source-files/cn.wildfirechat.chat/imagepicker/build.gradle +include tests/source-files/cn.wildfirechat.chat/mars-core-release/build.gradle +include tests/source-files/cn.wildfirechat.chat/push/build.gradle +include tests/source-files/cn.wildfirechat.chat/settings.gradle +include tests/source-files/com.anpmech.launcher/app/build.gradle +include tests/source-files/com.anpmech.launcher/app/src/main/AndroidManifest.xml +include tests/source-files/com.anpmech.launcher/build.gradle +include tests/source-files/com.anpmech.launcher/settings.gradle +include tests/source-files/com.integreight.onesheeld/build.gradle +include tests/source-files/com.integreight.onesheeld/gradle/wrapper/gradle-wrapper.properties +include tests/source-files/com.integreight.onesheeld/localeapi/build.gradle +include tests/source-files/com.integreight.onesheeld/localeapi/src/main/AndroidManifest.xml +include tests/source-files/com.integreight.onesheeld/oneSheeld/build.gradle +include tests/source-files/com.integreight.onesheeld/oneSheeld/src/main/AndroidManifest.xml +include tests/source-files/com.integreight.onesheeld/pagerIndicator/build.gradle +include tests/source-files/com.integreight.onesheeld/pagerIndicator/src/main/AndroidManifest.xml +include tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/build.gradle +include tests/source-files/com.integreight.onesheeld/pullToRefreshlibrary/src/main/AndroidManifest.xml +include tests/source-files/com.integreight.onesheeld/quickReturnHeader/build.gradle +include tests/source-files/com.integreight.onesheeld/quickReturnHeader/src/main/AndroidManifest.xml +include tests/source-files/com.integreight.onesheeld/settings.gradle include tests/source-files/com.kunzisoft.testcase/build.gradle include tests/source-files/com.nextcloud.client/build.gradle include tests/source-files/com.nextcloud.client.dev/src/generic/fastlane/metadata/android/en-US/full_description.txt @@ -701,11 +731,65 @@ include tests/source-files/firebase-whitelisted/app/build.gradle include tests/source-files/firebase-whitelisted/build.gradle include tests/source-files/open-keychain/open-keychain/build.gradle include tests/source-files/open-keychain/open-keychain/OpenKeychain/build.gradle +include tests/source-files/org.mozilla.rocket/app/build.gradle +include tests/source-files/org.tasks/app/build.gradle.kts +include tests/source-files/org.tasks/build.gradle +include tests/source-files/org.tasks/build.gradle.kts +include tests/source-files/org.tasks/buildSrc/build.gradle.kts +include tests/source-files/org.tasks/settings.gradle.kts include tests/source-files/osmandapp/osmand/build.gradle +include tests/source-files/se.manyver/android/app/build.gradle +include tests/source-files/se.manyver/android/build.gradle +include tests/source-files/se.manyver/android/gradle.properties +include tests/source-files/se.manyver/android/gradle/wrapper/gradle-wrapper.properties +include tests/source-files/se.manyver/android/settings.gradle +include tests/source-files/se.manyver/app.json +include tests/source-files/se.manyver/index.android.js +include tests/source-files/se.manyver/package.json +include tests/source-files/se.manyver/react-native.config.js +include tests/source-files/ut.ewh.audiometrytest/app/build.gradle +include tests/source-files/ut.ewh.audiometrytest/app/src/main/AndroidManifest.xml +include tests/source-files/ut.ewh.audiometrytest/build.gradle +include tests/source-files/ut.ewh.audiometrytest/settings.gradle include tests/source-files/Zillode/syncthing-silk/build.gradle include tests/SpeedoMeterApp.main_1.apk include tests/stats/known_apks.txt include tests/testcommon.py +include tests/triple-t-2/build/org.piwigo.android/app/build.gradle +include tests/triple-t-2/build/org.piwigo.android/app/.gitignore +include tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/constants.xml +include tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/strings.xml +include tests/triple-t-2/build/org.piwigo.android/app/src/main/java/org/piwigo/PiwigoApplication.java +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-email.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/contact-website.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/default-language.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/full-description.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/short-description.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/de-DE/title.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/full-description.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/feature-graphic/piwigo-full.png +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/icon/piwigo-icon.png +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/01_Login.jpg +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/02_Albums.jpg +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/03_Photos.jpg +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/04_Albums_horizontal.jpg +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/phone-screenshots/05_Menu.jpg +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/graphics/tablet-screenshots/01_Login.png +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/short-description.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/en-US/title.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/full-description.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/short-description.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/fr-FR/title.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/full-description.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/short-description.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/listings/kn-IN/title.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/de-DE/default.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/en-US/default.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/fr-FR/default.txt +include tests/triple-t-2/build/org.piwigo.android/app/src/main/play/release-notes/kn-IN/default.txt +include tests/triple-t-2/build/org.piwigo.android/build.gradle +include tests/triple-t-2/build/org.piwigo.android/settings.gradle +include tests/triple-t-2/metadata/org.piwigo.android.yml include tests/update.TestCase include tests/urzip.apk include tests/urzip-badcert.apk @@ -716,3 +800,7 @@ include tests/v2.only.sig_2.apk include tests/valid-package-names/random-package-names include tests/valid-package-names/RandomPackageNames.java include tests/valid-package-names/test.py +include tests/Virgin-islands-british_centralamerica_2.obf.zip +include tests/xref/metadata/aarddict.android.yml +include tests/xref/metadata/org.coolreader.yml +include tests/xref/metadata/org.geometerplus.zlibrary.ui.android.yml From 00f5ff876224ac036ce58846aaf62170e9f35e4c Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 30 Nov 2020 11:22:45 +0100 Subject: [PATCH 0640/2775] gitlab-ci: remove workaround, Debian's apksigner now works w/o binfmt --- .gitlab-ci.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dc82c2e4..101ef314 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -78,16 +78,14 @@ debian_testing: python3-defusedxml python3-setuptools zipalign - # Debian has apksigner depend on binfmt support which isn't very docker friendly - # We create a shell wrapper instead - - echo -e '#!/bin/sh\njava -jar /usr/lib/android-sdk/build-tools/debian/apksigner.jar "$@"' > /usr/local/bin/apksigner - - chmod +x /usr/local/bin/apksigner - python3 -c 'import fdroidserver' - python3 -c 'import androguard' - cd tests - ./run-tests -# test using LTS set up with the PPA, including Recommends +# Test using latest LTS set up with the PPA, including Recommends. +# bionic's apksigner, which comes from Recommends:, requires binfmt +# support in the kernel. ubuntu_lts_ppa: image: ubuntu:latest <<: *apt-template @@ -109,7 +107,6 @@ ubuntu_lts_ppa: - ./run-tests # test using Xenial LTS with all depends from pypi -# apksigner is recommended, but requires binfmt support in the kernel ubuntu_xenial_pip: image: ubuntu:xenial <<: *apt-template From 77db3ea709f253ca27721a2c4bb74dd54acde6de Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 30 Nov 2020 12:35:51 +0100 Subject: [PATCH 0641/2775] mirror: if index is verified, save a copy in the local mirror --- fdroidserver/mirror.py | 11 +++++++---- tests/run-tests | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/fdroidserver/mirror.py b/fdroidserver/mirror.py index 983a9dcd..89da89f8 100644 --- a/fdroidserver/mirror.py +++ b/fdroidserver/mirror.py @@ -87,7 +87,8 @@ def main(): def _get_index(section, etag=None): url = _append_to_url_path(section) - return index.download_repo_index(url, etag=etag) + data, etag = index.download_repo_index(url, etag=etag) + return data, etag, _append_to_url_path(section, 'index-v1.jar') else: def _get_index(section, etag=None): import io @@ -99,7 +100,7 @@ def main(): with zipfile.ZipFile(io.BytesIO(content)) as zip: jsoncontents = zip.open('index-v1.json').read() data = json.loads(jsoncontents.decode('utf-8')) - return data, etag + return data, etag, None # no verified index file to return ip = None try: @@ -138,14 +139,16 @@ def main(): for section in sections: sectiondir = os.path.join(basedir, section) - data, etag = _get_index(section) + urls = [] + data, etag, index_url = _get_index(section) + if index_url: + urls.append(index_url) os.makedirs(sectiondir, exist_ok=True) os.chdir(sectiondir) for icondir in icondirs: os.makedirs(os.path.join(sectiondir, icondir), exist_ok=True) - urls = [] for packageName, packageList in data['packages'].items(): for package in packageList: to_fetch = [] diff --git a/tests/run-tests b/tests/run-tests index 8645a366..7300e9aa 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -1254,6 +1254,39 @@ if which apksigner; then fi +#------------------------------------------------------------------------------# +echo_header 'test mirroring a repo' + +if which wget; then + REPOROOT=`create_test_dir` + cd $WORKSPACE/tests + test -d archive || mkdir archive + cp repo/index-v1.json $REPOROOT/ + $fdroid signindex + mv $REPOROOT/index-v1.json repo/index-v1.json + + port=321${RANDOM:3} + timeout 5m python3 -m http.server $port --bind 127.0.0.1 > http.server.log 2>&1 & + http_server_pid=$! + + cd $REPOROOT + http_proxy= HTTP_PROXY= $fdroid mirror http://127.0.0.1:${port}/ + test -e 127.0.0.1\:${port}/repo/souch.smsbypass_9.apk + test -e 127.0.0.1\:${port}/repo/icons-640/souch.smsbypass.9.png + # the index shouldn't be saved unless it was verified + ! test -e 127.0.0.1\:${port}/repo/index-v1.jar + ! http_proxy= HTTP_PROXY= $fdroid mirror "http://127.0.0.1:${port}/?fingerprint=asdfasdf" + ! test -e 127.0.0.1\:${port}/repo/index-v1.jar + http_proxy= HTTP_PROXY= $fdroid mirror "http://127.0.0.1:${port}/?fingerprint=F49AF3F11EFDDF20DFFD70F5E3117B9976674167ADCA280E6B1932A0601B26F6" + test -e 127.0.0.1\:${port}/repo/index-v1.jar + + # clean up + kill -9 $http_server_pid + rm -f 127.0.0.1\:${port}/repo/*.apk 127.0.0.1\:${port}/repo/*/*/*/*.png +else + echo "WARNING: wget not installed, skipping" +fi + #------------------------------------------------------------------------------# # remove this to prevent git conflicts and complaining From cc5c52791f05a1fa22f4fd592baafd20b94a67c1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 20 Nov 2020 11:19:01 +0100 Subject: [PATCH 0642/2775] use smallest possible valid .obf.zip file in tests Virgin-islands-british_centralamerica_2.obf.zip is 1MB, while Norway_bouvet_europe_2.obf.zip is 12KB. This file gets copied a lot in the test runs so it adds up fast. --- MANIFEST.in | 2 +- tests/Norway_bouvet_europe_2.obf.zip | Bin 0 -> 12227 bytes ...in-islands-british_centralamerica_2.obf.zip | Bin 916622 -> 0 bytes tests/update.TestCase | 6 +++--- 4 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 tests/Norway_bouvet_europe_2.obf.zip delete mode 100644 tests/Virgin-islands-british_centralamerica_2.obf.zip diff --git a/MANIFEST.in b/MANIFEST.in index 4a6a5671..064d220e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -800,7 +800,7 @@ include tests/v2.only.sig_2.apk include tests/valid-package-names/random-package-names include tests/valid-package-names/RandomPackageNames.java include tests/valid-package-names/test.py -include tests/Virgin-islands-british_centralamerica_2.obf.zip +include tests/Norway_bouvet_europe_2.obf.zip include tests/xref/metadata/aarddict.android.yml include tests/xref/metadata/org.coolreader.yml include tests/xref/metadata/org.geometerplus.zlibrary.ui.android.yml diff --git a/tests/Norway_bouvet_europe_2.obf.zip b/tests/Norway_bouvet_europe_2.obf.zip new file mode 100644 index 0000000000000000000000000000000000000000..70b58b541a5e3f0dfbda1b58a5b67225dc0321b7 GIT binary patch literal 12227 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 nF^Pqv3(5bY_ay&|-jn<zc|{~`tR|78CU*os=^ literal 0 HcmV?d00001 diff --git a/tests/Virgin-islands-british_centralamerica_2.obf.zip b/tests/Virgin-islands-british_centralamerica_2.obf.zip deleted file mode 100644 index d2a334afcbbf6f2c738ed13fc1c3d3812027cde9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 916622 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≤|PE9{4N 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

t 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≪a^&vxK%e`ym32bJ(SpJ4mRdh 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 diff --git a/tests/update.TestCase b/tests/update.TestCase index 3dfd0f57..dd3db64e 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -471,7 +471,7 @@ class UpdateTest(unittest.TestCase): os.mkdir('stats') with open(os.path.join('stats', 'known_apks.txt'), 'w') as fp: fp.write('se.manyver_30.apk se.manyver 2018-10-10\n') - filename = 'Virgin-islands-british_centralamerica_2.obf.zip' + filename = 'Norway_bouvet_europe_2.obf.zip' shutil.copy(os.path.join(self.basedir, filename), 'repo') knownapks = fdroidserver.common.KnownApks() files, fcachechanged = fdroidserver.update.scan_repo_files(dict(), 'repo', knownapks, False) @@ -482,8 +482,8 @@ class UpdateTest(unittest.TestCase): self.assertEqual(filename, info['apkName']) self.assertEqual(datetime, type(info['added'])) self.assertEqual(os.path.getsize(os.path.join('repo', filename)), info['size']) - self.assertEqual('402ee0799d5da535276b5a3672fb049d6df3e1727cfb35369c8962c4a42cac3d', - info['packageName']) + self.assertEqual('531190bdbc07e77d5577249949106f32dac7f62d38d66d66c3ae058be53a729d', + info['hash']) def test_read_added_date_from_all_apks(self): config = dict() From 4b9297dfa6bf58d04739ad57bd4046c8881f5a41 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 3 Dec 2020 16:04:02 +0100 Subject: [PATCH 0643/2775] gitlab-ci: only run arch/pip job on final merged commits Each of these takes a while to run, and this one rarely catches issues separately from the main jobs. --- .gitlab-ci.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 101ef314..16c394ed 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -106,7 +106,11 @@ ubuntu_lts_ppa: - cd tests - ./run-tests -# test using Xenial LTS with all depends from pypi +# Test using Xenial LTS with all depends from pypi. The venv is used +# to isolate the dist tarball generation environment from the clean +# install environment. Xenial's pip is too old to install all the +# dependencies, so this has to uppgrade pip and setuptools in order to +# run the install. ubuntu_xenial_pip: image: ubuntu:xenial <<: *apt-template @@ -128,8 +132,11 @@ ubuntu_xenial_pip: - test -e /usr/share/locale/de/LC_MESSAGES/fdroidserver.mo - ./tests/run-tests -pip_install: +# test install process on a bleeding edge distro with pip +arch_pip_install: image: archlinux/base + only: + - master@fdroid/fdroidserver script: - pacman --sync --sysupgrade --refresh --noconfirm git grep python-pip python-virtualenv tar - pip install -e . From 126b85972dda48f0ab603e987887e626f7e4ea4e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 27 Nov 2020 11:00:08 +0100 Subject: [PATCH 0644/2775] release v2.0a2 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 31cd1eb9..b6565617 100755 --- a/setup.py +++ b/setup.py @@ -53,7 +53,7 @@ with open("README.md", "r") as fh: long_description = fh.read() setup(name='fdroidserver', - version='2.0a1', + version='2.0a2', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From e8395b5fe93def9358dfc71ba76d890548ad83f6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 27 Nov 2020 11:00:08 +0100 Subject: [PATCH 0645/2775] release v2.0a3 somehow I messed up and uploaded 2.0a2 that was incomplete, so now 2.0a3 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b6565617..5437b420 100755 --- a/setup.py +++ b/setup.py @@ -53,7 +53,7 @@ with open("README.md", "r") as fh: long_description = fh.read() setup(name='fdroidserver', - version='2.0a2', + version='2.0a3', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', From ed0102754ac5b4d9e9fb2ab6e461f0567dd3abd7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 4 Dec 2020 11:23:22 +0100 Subject: [PATCH 0646/2775] gitlab-ci: remove rules:, they create weird "pipelines" --- .gitlab-ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 16c394ed..37bd0e28 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -246,14 +246,14 @@ gradle: # this tests the basic setup of the 'fdroid build' CI job in fdroiddata fdroiddata fdroid build: - image: registry.gitlab.com/fdroid/ci-images-client:latest - rules: - - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH - changes: - - buildserver/provision-apt-get-install - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - changes: - - buildserver/provision-apt-get-install + image: registry.gitlab.com/fdroid/ci-images-client + only: + refs: + - branches + - pipelines + - web + changes: + - buildserver/provision-apt-get-install script: - bash buildserver/provision-apt-get-install http://deb.debian.org/debian - apt-get dist-upgrade From 15a6e2d3a0ffaaf762d975602f8950c6dab0429b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 4 Dec 2020 11:25:02 +0100 Subject: [PATCH 0647/2775] gitlab-ci: switch archived ci-images-server to ci-images-base ci-images-server was created separately from ci-images-base back in the day when we had to support Debian/stretch without stretch-backports. Those days are gone now, so ci-images-server has been archived and should no longer be used. --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 37bd0e28..fe2f5c6e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,7 +6,7 @@ variables: test: - image: registry.gitlab.com/fdroid/ci-images-server:latest + image: registry.gitlab.com/fdroid/ci-images-base script: - $pip install -e .[test] # the `fdroid build` test in tests/run-tests needs android-23 @@ -22,7 +22,7 @@ test: # The COMMIT_ID should be bumped after each release, so that the list # of sed hacks needed does not continuously grow. metadata_v0: - image: registry.gitlab.com/fdroid/ci-images-server:latest + image: registry.gitlab.com/fdroid/ci-images-base variables: GIT_DEPTH: 1000 RELEASE_COMMIT_ID: 37f37ebd88e79ebe93239b72ed5503d5bde13f4b # 2.0a~ From 5df13bcb8cebe23bd9f59d6700cd064738bd255e Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sat, 5 Dec 2020 14:24:50 +0100 Subject: [PATCH 0648/2775] Catch exception when testing find_sdk_tools_cmd In 1c7df94e find_sdk_tools_cmd was changed to throw an FDroidException when the sdk tools where not found instead of returning None. --- tests/common.TestCase | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/common.TestCase b/tests/common.TestCase index d42bfe85..4ba80c0d 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -92,10 +92,12 @@ class CommonTest(unittest.TestCase): if os.path.exists(os.path.join(os.getenv('ANDROID_HOME'), 'tools', 'android')): tools.append('android') for cmd in tools: - path = fdroidserver.common.find_sdk_tools_cmd(cmd) - if path is not None: + try: + path = fdroidserver.common.find_sdk_tools_cmd(cmd) self.assertTrue(os.path.exists(path)) self.assertTrue(os.path.isfile(path)) + except fdroidserver.exception.FDroidException: + pass def test_find_sdk_tools_cmd(self): fdroidserver.common.config = dict() From 828d6015efc0f18fe4f7de1139ff3065169ead93 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 17 Nov 2020 14:17:08 +0100 Subject: [PATCH 0649/2775] purge code that modifies the app description, including linkifying closes #845 --- fdroidserver/index.py | 2 +- fdroidserver/lint.py | 2 +- fdroidserver/metadata.py | 225 +------ fdroidserver/readmeta.py | 2 +- fdroidserver/rewritemeta.py | 2 +- fdroidserver/update.py | 15 +- tests/dump_internal_metadata_format.py | 2 +- tests/metadata.TestCase | 17 +- tests/repo/index-v1.json | 8 +- tests/repo/index.xml | 52 +- tests/update.TestCase | 18 +- tests/xref/metadata/aarddict.android.yml | 104 ---- tests/xref/metadata/org.coolreader.yml | 551 ----------------- .../org.geometerplus.zlibrary.ui.android.yml | 556 ------------------ 14 files changed, 68 insertions(+), 1488 deletions(-) delete mode 100644 tests/xref/metadata/aarddict.android.yml delete mode 100644 tests/xref/metadata/org.coolreader.yml delete mode 100644 tests/xref/metadata/org.geometerplus.zlibrary.ui.android.yml diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 078b64fb..e707824d 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -405,7 +405,7 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing addElement('icon', app.icon, doc, apel) addElementCheckLocalized('desc', app, 'Description', doc, apel, - '

No description available

') + 'No description available') addElement('license', app.License, doc, apel) if app.Categories: diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index dd48e05f..7ee37865 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -583,7 +583,7 @@ def main(): config = common.read_config(options) # Get all apps... - allapps = metadata.read_metadata(xref=True) + allapps = metadata.read_metadata() apps = common.read_app_args(options.appid, allapps, False) anywarns = check_for_unsupported_metadata_files() diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 79195289..2b6c8482 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -21,10 +21,7 @@ import os import re import glob -import html import logging -import textwrap -import io import yaml try: from yaml import CSafeLoader as SafeLoader @@ -467,196 +464,6 @@ def check_metadata(app): v.check(app[k], app.id) -# Formatter for descriptions. Create an instance, and call parseline() with -# each line of the description source from the metadata. At the end, call -# end() and then text_txt and text_html will contain the result. -class DescriptionFormatter: - - stNONE = 0 - stPARA = 1 - stUL = 2 - stOL = 3 - - def __init__(self, linkres): - self.bold = False - self.ital = False - self.state = self.stNONE - self.laststate = self.stNONE - self.text_html = '' - self.text_txt = '' - self.html = io.StringIO() - self.text = io.StringIO() - self.para_lines = [] - self.linkResolver = None - self.linkResolver = linkres - - def endcur(self, notstates=None): - if notstates and self.state in notstates: - return - if self.state == self.stPARA: - self.endpara() - elif self.state == self.stUL: - self.endul() - elif self.state == self.stOL: - self.endol() - - def endpara(self): - self.laststate = self.state - self.state = self.stNONE - whole_para = ' '.join(self.para_lines) - self.addtext(whole_para) - wrapped = textwrap.fill(whole_para, 80, - break_long_words=False, - break_on_hyphens=False) - self.text.write(wrapped) - self.html.write('

') - del self.para_lines[:] - - def endul(self): - self.html.write('') - self.laststate = self.state - self.state = self.stNONE - - def endol(self): - self.html.write('') - self.laststate = self.state - self.state = self.stNONE - - def formatted(self, txt, htmlbody): - res = '' - if htmlbody: - txt = html.escape(txt, quote=False) - while True: - index = txt.find("''") - if index == -1: - return res + txt - res += txt[:index] - txt = txt[index:] - if txt.startswith("'''"): - if htmlbody: - if self.bold: - res += '
' - else: - res += '' - self.bold = not self.bold - txt = txt[3:] - else: - if htmlbody: - if self.ital: - res += '
' - else: - res += '' - self.ital = not self.ital - txt = txt[2:] - - def linkify(self, txt): - res_plain = '' - res_html = '' - while True: - index = txt.find("[") - if index == -1: - return (res_plain + self.formatted(txt, False), res_html + self.formatted(txt, True)) - res_plain += self.formatted(txt[:index], False) - res_html += self.formatted(txt[:index], True) - txt = txt[index:] - if txt.startswith("[["): - index = txt.find("]]") - if index == -1: - _warn_or_exception(_("Unterminated ]]")) - url = txt[2:index] - if self.linkResolver: - url, urltext = self.linkResolver.resolve_description_link(url) - else: - urltext = url - res_html += '' + html.escape(urltext, quote=False) + '' - res_plain += urltext - txt = txt[index + 2:] - else: - index = txt.find("]") - if index == -1: - _warn_or_exception(_("Unterminated ]")) - url = txt[1:index] - index2 = url.find(' ') - if index2 == -1: - urltxt = url - else: - urltxt = url[index2 + 1:] - url = url[:index2] - if url == urltxt: - _warn_or_exception(_("URL title is just the URL, use brackets: [URL]")) - res_html += '' + html.escape(urltxt, quote=False) + '' - res_plain += urltxt - if urltxt != url: - res_plain += ' (' + url + ')' - txt = txt[index + 1:] - - def addtext(self, txt): - p, h = self.linkify(txt) - self.html.write(h) - - def parseline(self, line): - if not line: - self.endcur() - elif line.startswith('* '): - self.endcur([self.stUL]) - if self.state != self.stUL: - self.html.write('