diff --git a/.bandit b/.bandit index 3dc1625b..dc28620f 100644 --- a/.bandit +++ b/.bandit @@ -1,3 +1,3 @@ [bandit] -skips: B110,B404,B408,B603,B607 +skips: B110,B404,B408,B603,B607,B322 targets: . diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a176097f..f66e1ce6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,22 @@ --- +# Use merge request pipelines when a merge request is open for the branch. +# Use branch pipelines when a merge request is not open for the branch. +# https://docs.gitlab.com/ci/yaml/workflow/#switch-between-branch-pipelines-and-merge-request-pipelines +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS + when: never + - if: $CI_COMMIT_BRANCH + + +stages: + - lint + - test # default for jobs that do not specify stage: + - deploy + + variables: pip: pip3 --timeout 100 --retries 10 # speed up git checkout phase @@ -50,6 +67,7 @@ metadata_v0: - git checkout $RELEASE_COMMIT_ID - cd .. - git clone --depth 1 https://gitlab.com/fdroid/fdroiddata.git + - rm -f fdroiddata/config.yml # ignore config for this test - cd fdroiddata - ../tests/dump_internal_metadata_format.py - cd .. @@ -80,12 +98,31 @@ metadata_v0: # Ubuntu and other distros often lack https:// support - grep Debian /etc/issue.net && { find /etc/apt/sources.list* -type f | xargs sed -i s,http:,https:, ; } + # The official Debian docker images ship without ca-certificates, + # TLS certificates cannot be verified until that is installed. The + # following code turns off TLS verification, and enables HTTPS, so + # at least unverified TLS is used for apt-get instead of plain + # HTTP. Once ca-certificates is installed, the CA verification is + # enabled by removing this config. This set up makes the initial + # `apt-get update` and `apt-get install` look the same as verified + # TLS to the network observer and hides the metadata. - echo 'Acquire::https::Verify-Peer "false";' > /etc/apt/apt.conf.d/99nocacertificates - apt-get update - apt-get install ca-certificates - rm /etc/apt/apt.conf.d/99nocacertificates - apt-get dist-upgrade +# For jobs that only need to run when there are changes to Python files. +.python-rules-changes: &python-rules-changes + rules: + - changes: + - .gitlab-ci.yml + - fdroid + - makebuildserver + - setup.py + - fdroidserver/*.py + - tests/*.py + # Since F-Droid uses Debian as its default platform, from production # servers to CI to contributor machines, it is important to know when @@ -94,8 +131,8 @@ metadata_v0: debian_testing: image: debian:testing <<: *apt-template - only: - - master@fdroid/fdroidserver + rules: + - if: $CI_COMMIT_BRANCH == "master" && $CI_PROJECT_PATH == "fdroid/fdroidserver" script: - apt-get install aapt @@ -123,8 +160,8 @@ debian_testing: ubuntu_lts_ppa: image: ubuntu:latest <<: *apt-template - only: - - master@fdroid/fdroidserver + rules: + - if: $CI_COMMIT_BRANCH == "master" && $CI_PROJECT_PATH == "fdroid/fdroidserver" script: - export ANDROID_HOME=/usr/lib/android-sdk - apt-get install gnupg @@ -183,24 +220,9 @@ ubuntu_jammy_pip: - LANGUAGE='de' fdroid --help | grep 'Gültige Befehle sind' -# The gradlew-fdroid tests are isolated from the rest of the test -# suite, so they run as their own job. -gradlew-fdroid: - image: debian:bookworm-slim - <<: *apt-template - only: - changes: - - .gitlab-ci.yml - - gradlew-fdroid - - tests/test_gradlew-fdroid - script: - - apt-get install ca-certificates curl default-jdk-headless shellcheck unzip - - shellcheck --severity=error --color gradlew-fdroid tests/test_gradlew-fdroid - - ./tests/test_gradlew-fdroid - - # Run all the various linters and static analysis tools. -lint_format_bandit_checks: +hooks/pre-commit: + stage: lint image: debian:bookworm-slim variables: LANG: C.UTF-8 @@ -215,34 +237,60 @@ lint_format_bandit_checks: make pycodestyle pyflakes3 - pylint python3-dev python3-git python3-nose python3-pip python3-yaml - shellcheck + - ./hooks/pre-commit + +bandit: + image: debian:bookworm-slim + <<: *python-rules-changes + <<: *apt-template + script: + - apt-get install python3-pip - $pip install --break-system-packages bandit - - 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 - - bandit - -r - -ii - --ini .bandit - || set_error - - pylint --output-format=colorized --reports=n + - bandit -r -ii --ini .bandit + +pylint: + stage: lint + image: debian:bookworm-slim + <<: *python-rules-changes + <<: *apt-template + script: + - apt-get install pylint python3-pip + - $pip install --break-system-packages pylint-gitlab + - pylint --output-format=colorized,pylint_gitlab.GitlabCodeClimateReporter:pylint-report.json fdroid makebuildserver setup.py fdroidserver/*.py tests/*.py - || set_error - - shellcheck --exclude SC2046,SC2090 --severity=warning --color tests/run-tests - || set_error - - exit $EXITVALUE + artifacts: + reports: + codequality: pylint-report.json + when: always +shellcheck: + stage: lint + image: debian:bookworm-slim + rules: + - changes: + - .gitlab-ci.yml + - hooks/install-hooks.sh + - hooks/pre-commit + - tests/run-tests + <<: *apt-template + script: + - apt-get install shellcheck + # TODO GitLab Code Quality report https://github.com/koalaman/shellcheck/issues/3155 + - shellcheck --exclude SC2046,SC2090 --severity=warning --color + hooks/install-hooks.sh + hooks/pre-commit + tests/run-tests + # Check all the dependencies in Debian to mirror production. CVEs are # generally fixed in the latest versions in pip/pypi.org, so it isn't # so important to scan that kind of install in CI. @@ -250,10 +298,7 @@ lint_format_bandit_checks: safety: image: debian:bookworm-slim rules: - # once only:/changes: are ported to rules:, this could be removed: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - when: never - - if: $CI_PIPELINE_SOURCE == "push" && $SAFETY_API_KEY + - if: $SAFETY_API_KEY changes: - .gitlab-ci.yml - .safety-policy.yml @@ -276,13 +321,10 @@ safety: # TODO tests/*/*/*.yaml are not covered yamllint: + stage: lint image: debian:bookworm-slim rules: - # once only:/changes: are ported to rules:, this could be removed: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - when: never - - if: $CI_PIPELINE_SOURCE == "push" - changes: + - changes: - .gitlab-ci.yml - .safety-policy.yml - .yamllint @@ -303,8 +345,8 @@ yamllint: tests/*/*/.*.yml -# Run all the various linters and static analysis tools. locales: + stage: lint image: debian:bookworm-slim variables: LANG: C.UTF-8 @@ -323,6 +365,7 @@ locales: black: + stage: lint image: debian:bookworm-slim <<: *apt-template script: @@ -375,8 +418,8 @@ fedora_latest: macOS: tags: - saas-macos-medium-m1 - only: - - master@fdroid/fdroidserver + rules: + - if: $CI_COMMIT_BRANCH == "master" && $CI_PROJECT_PATH == "fdroid/fdroidserver" script: - export HOMEBREW_CURL_RETRIES=10 - brew update > /dev/null @@ -387,7 +430,7 @@ macOS: - brew install --cask android-commandlinetools temurin # temurin is a JDK # test suite dependencies - - brew install dash bash coreutils gnu-sed + - brew install bash coreutils gnu-sed # TODO port tests/run-tests to POSIX and gsed, it has a couple GNU-isms like du --bytes - export PATH="$(brew --prefix fdroidserver)/libexec/bin:$(brew --prefix coreutils)/libexec/gnubin:$PATH" @@ -404,53 +447,45 @@ macOS: - echo "macOS sticks with bash 3.x because of licenses, so avoid new bash syntax" - /bin/bash --version - - /bin/bash -n gradlew-fdroid tests/run-tests + - /bin/bash -n tests/run-tests # test fdroidserver from git with current package's dependencies - fdroid="$(brew --prefix fdroidserver)/libexec/bin/python3 $PWD/fdroid" ./tests/run-tests gradle: - image: debian:bookworm-slim + image: debian:trixie-slim <<: *apt-template - variables: - GIT_DEPTH: 1000 + rules: + - changes: + - .gitlab-ci.yml + - makebuildserver script: - apt-get install ca-certificates git - openssh-client - python3-bs4 python3-colorama - python3-git - python3-gitlab python3-packaging python3-requests - # if this is a merge request fork, then only check if relevant files 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"; - test "$f" == "gradlew-fdroid" && export CHANGED="yes"; - done; - test -z "$CHANGED" && exit; - fi - ./tests/gradle-release-checksums.py # Run an actual build in a simple, faked version of the buildserver guest VM. fdroid build: image: registry.gitlab.com/fdroid/fdroidserver:buildserver - only: - changes: - - .gitlab-ci.yml - - fdroidserver/build.py - - fdroidserver/common.py - - fdroidserver/exception.py - - fdroidserver/metadata.py - - fdroidserver/net.py - - fdroidserver/scanner.py - - fdroidserver/vmtools.py + rules: + - changes: + - .gitlab-ci.yml + - fdroidserver/build.py + - fdroidserver/common.py + - fdroidserver/exception.py + - fdroidserver/metadata.py + - fdroidserver/net.py + - fdroidserver/scanner.py + - fdroidserver/vmtools.py + # for the docker: job which depends on this one + - makebuildserver + - buildserver/* cache: key: "$CI_JOB_NAME" paths: @@ -486,6 +521,8 @@ fdroid build: env HOME=$home_vagrant fdroid" + - git -C $home_vagrant/gradlew-fdroid pull + - chown -R vagrant $home_vagrant - chown -R vagrant $fdroidserver/.git - chown vagrant $fdroidserver/ @@ -511,11 +548,11 @@ fdroid build: plugin_fetchsrclibs: image: debian:bookworm-slim <<: *apt-template - only: - changes: - - .gitlab-ci.yml - - examples/fdroid_fetchsrclibs.py - - fdroidserver/__main__.py + rules: + - changes: + - .gitlab-ci.yml + - examples/fdroid_fetchsrclibs.py + - fdroidserver/__main__.py script: - apt-get install curl @@ -555,8 +592,8 @@ plugin_fetchsrclibs: servergitmirrors: image: debian:bookworm-slim <<: *apt-template - only: - - master@fdroid/fdroidserver + rules: + - if: $CI_COMMIT_BRANCH == "master" && $CI_PROJECT_PATH == "fdroid/fdroidserver" script: - apt-get install default-jdk-headless @@ -598,6 +635,7 @@ servergitmirrors: Build documentation: image: debian:bookworm-slim + <<: *python-rules-changes <<: *apt-template script: - apt-get install make python3-sphinx python3-numpydoc python3-pydata-sphinx-theme pydocstyle fdroidserver @@ -617,8 +655,8 @@ Build documentation: Windows: tags: - windows - only: - - windows + rules: + - if: $CI_COMMIT_BRANCH == "windows" script: - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" - choco install --no-progress -y git --force --params "/GitAndUnixToolsOnPath" @@ -669,7 +707,9 @@ pages: artifacts: paths: - public - needs: ["Build documentation"] + needs: + - job: "Build documentation" + optional: true rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' # only publish pages on default (master) branch @@ -681,13 +721,12 @@ pages: docker: dependencies: - fdroid build - only: - changes: - - .gitlab-ci.yml - - makebuildserver - - buildserver/* - variables: - - $CI_COMMIT_BRANCH == "master" || $CI_PROJECT_NAMESPACE != "fdroid" + rules: + - if: $CI_COMMIT_BRANCH == "master" && $CI_PROJECT_PATH == "fdroid/fdroidserver" + changes: + - .gitlab-ci.yml + - makebuildserver + - buildserver/* image: docker:dind services: - docker:dind @@ -714,11 +753,12 @@ docker: # PUBLISH is the signing server. It has a very minimal manual setup. PUBLISH: - image: debian:bullseye-backports + image: debian:bookworm-backports + <<: *python-rules-changes script: - apt-get update - apt-get -qy upgrade - - apt-get -qy install --no-install-recommends -t bullseye-backports + - apt-get -qy install --no-install-recommends -t bookworm-backports androguard apksigner curl diff --git a/.well-known/funding-manifest-urls b/.well-known/funding-manifest-urls new file mode 100644 index 00000000..9935b4d4 --- /dev/null +++ b/.well-known/funding-manifest-urls @@ -0,0 +1 @@ +https://f-droid.org/funding.json diff --git a/CHANGELOG.md b/CHANGELOG.md index f21550a2..5aeeca43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,49 @@ 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/) +## [2.4.2] - 2025-06-24 + +### Fixed + +* nightly: fix bug that clones nightly repo to wrong location + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1672 +* Sync translations for all supported languages: es pl ru + +## [2.4.1] - 2025-06-23 + +### Added + +* build: Clearer error messages when working with Git. +* verify: generate .json files that list all reports + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1632 + +### Fixed + +* deploy: use master branch when working complete git-mirror repo + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1666 +* update: use ctime/mtime to control _strip_and_copy_image runs + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1665 +* update: If categories.yml only has icon:, then add name: + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1659 +* update: fix handling of Triple-T 1.0.0 graphics + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1652 +* update: never execute any VCS e.g. git + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1630 +* config: lazyload environment variables in config.yml + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1645 +* config: make localized name/description/icon optional + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1649 +* lint: add repo_key_sha256 to list of valid config keys + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1643 +* build: calculate all combinations of gradle flavors + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1638 +* build: set SOURCE_DATE_EPOCH from app's git otherwise fdroiddata metadata file + https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1653 +* Sync translations for all supported languages: ca cs de fr ga ja pl pt pt_BR + pt_PT ru sq tr uk zh_Hans + +### Removed + ## [2.4.0] - 2025-03-25 ### Added diff --git a/MANIFEST.in b/MANIFEST.in index e833d6f6..77c176d4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -20,6 +20,7 @@ include examples/template.yml include examples/Vagrantfile.yaml include gradlew-fdroid include LICENSE +include locale/ba/LC_MESSAGES/fdroidserver.po include locale/bo/LC_MESSAGES/fdroidserver.po include locale/ca/LC_MESSAGES/fdroidserver.po include locale/cs/LC_MESSAGES/fdroidserver.po @@ -803,6 +804,7 @@ include tests/source-files/firebase-allowlisted/app/build.gradle include tests/source-files/firebase-allowlisted/build.gradle include tests/source-files/firebase-suspect/app/build.gradle include tests/source-files/firebase-suspect/build.gradle +include tests/source-files/flavor.test/build.gradle include tests/source-files/info.guardianproject.ripple/build.gradle include tests/source-files/lockfile.test/flutter/.dart_tool/flutter_gen/pubspec.yaml include tests/source-files/lockfile.test/flutter/pubspec.lock @@ -868,6 +870,10 @@ include tests/test_signatures.py include tests/test_signindex.py include tests/test_update.py include tests/test_vcs.py +include tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/featureGraphic/play_store_feature_graphic.png +include tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/icon/icon.png +include tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/phoneScreenshots/1.png +include tests/triple-t-1-graphics/metadata/de.wivewa.dialer.yml include tests/triple-t-2/build/org.piwigo.android/app/.gitignore include tests/triple-t-2/build/org.piwigo.android/app/build.gradle include tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/constants.xml diff --git a/buildserver/Dockerfile b/buildserver/Dockerfile index 3e863df5..27ada3f8 100644 --- a/buildserver/Dockerfile +++ b/buildserver/Dockerfile @@ -37,11 +37,22 @@ RUN useradd --create-home -s /bin/bash vagrant && echo -n 'vagrant:vagrant' | ch # # Ensure fdroidserver's dependencies are marked manual before purging # unneeded packages, otherwise, all its dependencies get purged. +# +# The official Debian docker images ship without ca-certificates, so +# TLS certificates cannot be verified until that is installed. The +# following code temporarily turns off TLS verification, and enables +# HTTPS, so at least unverified TLS is used for apt-get instead of +# plain HTTP. Once ca-certificates is installed, the CA verification +# is enabled by removing the newly created config file. This set up +# makes the initial `apt-get update` and `apt-get install` look the +# same as verified TLS to the network observer and hides the metadata. RUN printf "path-exclude=/usr/share/locale/*\npath-exclude=/usr/share/man/*\npath-exclude=/usr/share/doc/*\npath-include=/usr/share/doc/*/copyright\n" >/etc/dpkg/dpkg.cfg.d/01_nodoc \ && mkdir -p /usr/share/man/man1 \ + && echo 'Acquire::https::Verify-Peer "false";' > /etc/apt/apt.conf.d/99nocacertificates \ + && find /etc/apt/sources.list* -type f -exec sed -i s,http:,https:, {} \; \ && apt-get update \ && apt-get install ca-certificates \ - && sed -i 's,http:,https:,' /etc/apt/sources.list.d/debian.sources \ + && rm /etc/apt/apt.conf.d/99nocacertificates \ && apt-get upgrade \ && apt-get dist-upgrade \ && apt-get install openssh-client iproute2 python3 openssh-server sudo \ diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index fed5fa57..ca39c47b 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -104,6 +104,7 @@ apt-get upgrade apt-get update || apt-get update packages=" + androguard/bookworm-backports apksigner default-jdk-headless default-jre-headless diff --git a/buildserver/provision-gradle b/buildserver/provision-gradle index ca48bcf7..a282a4c5 100644 --- a/buildserver/provision-gradle +++ b/buildserver/provision-gradle @@ -25,7 +25,12 @@ fi chmod -R a+rX /opt/gradle test -e /opt/gradle/bin || mkdir -p /opt/gradle/bin -ln -fs /home/vagrant/fdroidserver/gradlew-fdroid /opt/gradle/bin/gradle +git clone --depth 1 https://gitlab.com/fdroid/gradlew-fdroid.git /home/vagrant/gradlew-fdroid/ +chmod 0755 /home/vagrant/gradlew-fdroid/gradlew-fdroid +chmod -R u+rwX,a+rX,go-w /home/vagrant/gradlew-fdroid/ +ln -fs /home/vagrant/gradlew-fdroid/gradlew-fdroid /opt/gradle/bin/gradle +ln -fs /home/vagrant/gradlew-fdroid/gradlew-fdroid /usr/local/bin/ + chown -h vagrant:vagrant /opt/gradle/bin/gradle chown vagrant:vagrant /opt/gradle/versions chmod 0755 /opt/gradle/versions diff --git a/dev/fdroid_scan-binary.py b/dev/fdroid_scan-binary.py deleted file mode 100644 index 896c2cc4..00000000 --- a/dev/fdroid_scan-binary.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -# -# an fdroid plugin for setting up srclibs -# -# The 'fdroid build' gitlab-ci job uses --on-server, which does not -# set up the srclibs. This plugin does the missing setup. - -import glob -import os -from argparse import ArgumentParser -from fdroidserver import _, common, scanner - - -fdroid_summary = 'Run scanner.scan_binary on APKs' - - -def main(): - parser = ArgumentParser() - common.setup_global_opts(parser) - parser.add_argument("APK", nargs='*', help=_("Path to a signed or unsigned APK.")) - options = common.parse_args(parser) - common.read_config() - if options.APK: - apks = options.APK - else: - apks = glob.glob(os.path.join('unsigned', '*.apk')) - - errors = 0 - for apk in apks: - print('Scanning', apk, '...') - if scanner.scan_binary(apk): - print("ERROR: Found blocklisted packages in:", apk) - errors += 1 - exit(errors) - - -if __name__ == "__main__": - main() diff --git a/docs/source/conf.py b/docs/source/conf.py index 382d8feb..c20542de 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -12,6 +12,7 @@ # import os import sys + sys.path.insert(0, os.path.abspath('../../fdroidserver')) # -- Project information ----------------------------------------------------- diff --git a/examples/fdroid_clean_repos.py b/examples/fdroid_clean_repos.py index cf6259a7..6b19cacc 100644 --- a/examples/fdroid_clean_repos.py +++ b/examples/fdroid_clean_repos.py @@ -6,7 +6,6 @@ import argparse import logging from fdroidserver import _, common, metadata - from fdroidserver.exception import VCSException fdroid_summary = 'reset app VCSs to the latest version' diff --git a/examples/fdroid_export_keystore_to_nitrokey.py b/examples/fdroid_export_keystore_to_nitrokey.py index 8fa81ffe..6e920a78 100644 --- a/examples/fdroid_export_keystore_to_nitrokey.py +++ b/examples/fdroid_export_keystore_to_nitrokey.py @@ -4,6 +4,7 @@ import os from argparse import ArgumentParser + from fdroidserver import common from fdroidserver.common import FDroidPopen from fdroidserver.exception import BuildException diff --git a/examples/fdroid_exportkeystore.py b/examples/fdroid_exportkeystore.py index 435874a5..f2a16980 100644 --- a/examples/fdroid_exportkeystore.py +++ b/examples/fdroid_exportkeystore.py @@ -4,6 +4,7 @@ import os from argparse import ArgumentParser + from fdroidserver import common from fdroidserver.common import FDroidPopen from fdroidserver.exception import BuildException diff --git a/examples/fdroid_extract_repo_pubkey.py b/examples/fdroid_extract_repo_pubkey.py index f3c51767..cb5a895c 100644 --- a/examples/fdroid_extract_repo_pubkey.py +++ b/examples/fdroid_extract_repo_pubkey.py @@ -4,6 +4,7 @@ # from argparse import ArgumentParser + from fdroidserver import common, index fdroid_summary = 'export the keystore in standard PEM format' diff --git a/examples/fdroid_fetchsrclibs.py b/examples/fdroid_fetchsrclibs.py index e4a105e2..aba6f7fa 100644 --- a/examples/fdroid_fetchsrclibs.py +++ b/examples/fdroid_fetchsrclibs.py @@ -8,6 +8,7 @@ import argparse import os import pprint + from fdroidserver import _, common, metadata fdroid_summary = 'prepare the srclibs for `fdroid build --on-server`' diff --git a/examples/fdroid_nitrokeyimport.py b/examples/fdroid_nitrokeyimport.py index 9b458103..d17a6186 100644 --- a/examples/fdroid_nitrokeyimport.py +++ b/examples/fdroid_nitrokeyimport.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from argparse import ArgumentParser + from fdroidserver import common from fdroidserver.common import FDroidPopen from fdroidserver.exception import BuildException diff --git a/fdroidserver/__init__.py b/fdroidserver/__init__.py index 9e4c197f..fdf64421 100644 --- a/fdroidserver/__init__.py +++ b/fdroidserver/__init__.py @@ -3,7 +3,6 @@ import glob import os import sys - # support running straight from git and standard installs rootpaths = [ os.path.realpath(os.path.join(os.path.dirname(__file__), '..')), @@ -15,7 +14,10 @@ rootpaths = [ localedir = None for rootpath in rootpaths: - if len(glob.glob(os.path.join(rootpath, 'locale', '*', 'LC_MESSAGES', 'fdroidserver.mo'))) > 0: + found_mo = glob.glob( + os.path.join(rootpath, 'locale', '*', 'LC_MESSAGES', 'fdroidserver.mo') + ) + if len(found_mo) > 0: localedir = os.path.join(rootpath, 'locale') break @@ -24,39 +26,52 @@ gettext.textdomain('fdroidserver') _ = gettext.gettext -from fdroidserver.exception import (FDroidException, - MetaDataException, - VerificationException) # NOQA: E402 +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 +from fdroidserver.common import genkeystore as generate_keystore # NOQA: E402 +from fdroidserver.common import verify_apk_signature + verify_apk_signature # NOQA: B101 generate_keystore # NOQA: B101 -from fdroidserver.index import (download_repo_index, - download_repo_index_v1, - download_repo_index_v2, - get_mirror_service_urls, - make as make_index) # NOQA: E402 +from fdroidserver.index import ( + download_repo_index, + download_repo_index_v1, + download_repo_index_v2, + get_mirror_service_urls, +) +from fdroidserver.index import make as make_index # NOQA: E402 + download_repo_index # NOQA: B101 download_repo_index_v1 # NOQA: B101 download_repo_index_v2 # 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 +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.deploy import (update_awsbucket, - update_servergitmirrors, - update_serverwebroots, - update_serverwebroot) # NOQA: E402 +from fdroidserver.deploy import ( + update_awsbucket, + update_servergitmirrors, + update_serverwebroot, # NOQA: E402 + update_serverwebroots, +) + update_awsbucket # NOQA: B101 update_servergitmirrors # NOQA: B101 update_serverwebroots # NOQA: B101 diff --git a/fdroidserver/__main__.py b/fdroidserver/__main__.py index 14813fa1..71c39b2c 100755 --- a/fdroidserver/__main__.py +++ b/fdroidserver/__main__.py @@ -18,20 +18,20 @@ # 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 importlib.metadata +import logging import os import pkgutil -import logging -import importlib.metadata - -import git -import fdroidserver.common -import fdroidserver.metadata -from fdroidserver import _ +import re +import sys from argparse import ArgumentError from collections import OrderedDict +import git + +import fdroidserver.common +import fdroidserver.metadata +from fdroidserver import _ COMMANDS = OrderedDict([ ("build", _("Build a package from source")), diff --git a/fdroidserver/apksigcopier.py b/fdroidserver/apksigcopier.py index 2ab0b8c4..f36de2eb 100644 --- a/fdroidserver/apksigcopier.py +++ b/fdroidserver/apksigcopier.py @@ -68,9 +68,18 @@ import struct import sys import zipfile import zlib - from collections import namedtuple -from typing import Any, BinaryIO, Callable, Dict, Iterable, Iterator, Optional, Tuple, Union +from typing import ( + Any, + BinaryIO, + Callable, + Dict, + Iterable, + Iterator, + Optional, + Tuple, + Union, +) __version__ = "1.1.1" NAME = "apksigcopier" diff --git a/fdroidserver/btlog.py b/fdroidserver/btlog.py index df889396..7ca3ddbf 100755 --- a/fdroidserver/btlog.py +++ b/fdroidserver/btlog.py @@ -28,22 +28,21 @@ # the F-Droid client. import collections -import defusedxml.minidom -import git import glob -import os import json import logging -import requests +import os import shutil import tempfile import zipfile from argparse import ArgumentParser from typing import Optional -from . import _ -from . import common -from . import deploy +import defusedxml.minidom +import git +import requests + +from . import _, common, deploy from .exception import FDroidException diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 41df2c1c..2e716c10 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -18,31 +18,27 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import os -import shutil +import argparse import glob -import subprocess +import logging +import os import posixpath import re +import shutil +import subprocess import tarfile -import threading -import traceback -import time -import requests import tempfile -import argparse -import logging +import threading +import time +import traceback from gettext import ngettext from pathlib import Path -from . import _ -from . import common -from . import net -from . import metadata -from . import scanner -from . import vmtools +import requests + +from . import _, common, metadata, net, scanner, vmtools from .common import FDroidPopen -from .exception import FDroidException, BuildException, VCSException +from .exception import BuildException, FDroidException, VCSException try: import paramiko @@ -155,9 +151,7 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force): ftp.mkdir('fdroidserver') ftp.chdir('fdroidserver') ftp.put(os.path.join(serverpath, '..', 'fdroid'), 'fdroid') - ftp.put(os.path.join(serverpath, '..', 'gradlew-fdroid'), 'gradlew-fdroid') ftp.chmod('fdroid', 0o755) # nosec B103 permissions are appropriate - ftp.chmod('gradlew-fdroid', 0o755) # nosec B103 permissions are appropriate send_dir(os.path.join(serverpath)) ftp.chdir(homedir) @@ -479,7 +473,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext logging.critical("Android NDK '%s' is not a directory!" % ndk_path) raise FDroidException() - common.set_FDroidPopen_env(build) + common.set_FDroidPopen_env(app, build) # create ..._toolsversion.log when running in builder vm if onserver: @@ -541,13 +535,13 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext if build.preassemble: gradletasks += build.preassemble - flavours = build.gradle - if flavours == ['yes']: - flavours = [] + flavors = build.gradle + if flavors == ['yes']: + flavors = [] - flavours_cmd = ''.join([transform_first_char(flav, str.upper) for flav in flavours]) + flavors_cmd = ''.join([transform_first_char(flav, str.upper) for flav in flavors]) - gradletasks += ['assemble' + flavours_cmd + 'Release'] + gradletasks += ['assemble' + flavors_cmd + 'Release'] cmd = [config['gradle']] if build.gradleprops: @@ -721,8 +715,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext bindir = os.path.join(root_dir, 'bin') if os.path.isdir(os.path.join(build_dir, '.git')): - import git - commit_id = common.get_head_commit_id(git.repo.Repo(build_dir)) + commit_id = str(common.get_head_commit_id(build_dir)) else: commit_id = build.commit @@ -764,11 +757,11 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext # really old path os.path.join(root_dir, 'build', 'apk'), ] - # If we build with gradle flavours with gradle plugin >= 3.0 the APK will be in - # a subdirectory corresponding to the flavour command used, but with different + # If we build with gradle flavors with gradle plugin >= 3.0 the APK will be in + # a subdirectory corresponding to the flavor command used, but with different # capitalization. - if flavours_cmd: - apk_dirs.append(os.path.join(root_dir, 'build', 'outputs', 'apk', transform_first_char(flavours_cmd, str.lower), 'release')) + if flavors_cmd: + apk_dirs.append(os.path.join(root_dir, 'build', 'outputs', 'apk', transform_first_char(flavors_cmd, str.lower), 'release')) for apks_dir in apk_dirs: for apkglob in ['*-release-unsigned.apk', '*-unsigned.apk', '*.apk']: apks = glob.glob(os.path.join(apks_dir, apkglob)) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 60e22347..cff7bcd7 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -19,28 +19,30 @@ # along with this program. If not, see . import configparser -import git +import copy +import logging import os import re -import urllib.request -import urllib.error -import time import subprocess import sys -from argparse import ArgumentParser +import time import traceback -import logging -import copy +import urllib.error import urllib.parse +import urllib.request +from argparse import ArgumentParser from pathlib import Path from typing import Optional -from . import _ -from . import common -from . import metadata -from . import net -from .exception import VCSException, NoSubmodulesException, FDroidException, MetaDataException +import git +from . import _, common, metadata, net +from .exception import ( + FDroidException, + MetaDataException, + NoSubmodulesException, + VCSException, +) # https://gitlab.com/fdroid/checkupdates-runner/-/blob/1861899262a62a4ed08fa24e5449c0368dfb7617/.gitlab-ci.yml#L36 BOT_EMAIL = 'fdroidci@bubu1.eu' @@ -724,7 +726,7 @@ def checkout_appid_branch(appid): try: git_repo.remotes.origin.fetch(f'{appid}:refs/remotes/origin/{appid}') except Exception as e: - logging.warning('"%s" branch not found on origin remote:\n\t%s', appid, e) + logging.debug('"%s" branch not found on origin remote:\n\t%s', appid, e) if appid in git_repo.remotes.origin.refs: start_point = f"origin/{appid}" for commit in git_repo.iter_commits( @@ -749,7 +751,7 @@ def get_changes_versus_ref(git_repo, ref, f): return changes -def push_commits(branch_name='checkupdates', verbose=False): +def push_commits(branch_name='checkupdates'): """Make git branch then push commits as merge request. The appid is parsed from the actual file that was changed so that @@ -769,6 +771,10 @@ def push_commits(branch_name='checkupdates', verbose=False): * https://docs.gitlab.com/ee/user/project/push_options.html """ + if branch_name != "checkupdates": + if callable(getattr(git.SymbolicReference, "_check_ref_name_valid", None)): + git.SymbolicReference._check_ref_name_valid(branch_name) + git_repo = git.Repo.init('.') upstream_main = get_upstream_main_branch(git_repo) files = set() @@ -783,6 +789,10 @@ def push_commits(branch_name='checkupdates', verbose=False): if not files: return + # https://git-scm.com/docs/git-check-ref-format Git refname can't end with .lock + if branch_name.endswith(".lock"): + branch_name = f"{branch_name}_" + remote = git_repo.remotes.origin if branch_name in remote.refs: if not get_changes_versus_ref(git_repo, f'origin/{branch_name}', files[0]): @@ -806,21 +816,10 @@ def push_commits(branch_name='checkupdates', verbose=False): if current_version_only: push_options.append('merge_request.draft') - progress = None - if verbose: - import clint.textui - - progress_bar = clint.textui.progress.Bar() - - class MyProgressPrinter(git.RemoteProgress): - def update(self, op_code, current, maximum=None, message=None): - if isinstance(maximum, float): - progress_bar.show(current, maximum) - - progress = MyProgressPrinter() + progress = git.RemoteProgress() pushinfos = remote.push( - branch_name, + f"HEAD:refs/heads/{branch_name}", progress=progress, force=True, set_upstream=True, @@ -828,22 +827,22 @@ def push_commits(branch_name='checkupdates', verbose=False): ) for pushinfo in pushinfos: + logging.info(pushinfo.summary) + # Show potentially useful messages from git remote + if progress: + for line in progress.other_lines: + logging.info(line) if pushinfo.flags & ( git.remote.PushInfo.ERROR | git.remote.PushInfo.REJECTED | git.remote.PushInfo.REMOTE_FAILURE | git.remote.PushInfo.REMOTE_REJECTED ): - # Show potentially useful messages from git remote - if progress: - for line in progress.other_lines: - if line.startswith('remote:'): - logging.debug(line) raise FDroidException( f'{remote.url} push failed: {pushinfo.flags} {pushinfo.summary}' ) else: - logging.debug(remote.url + ': ' + pushinfo.summary) + logging.info(remote.url + ': ' + pushinfo.summary) def prune_empty_appid_branches(git_repo=None, main_branch='main'): @@ -953,7 +952,7 @@ def main(): exit_code = 1 if options.appid and options.merge_request: - push_commits(verbose=options.verbose) + push_commits() prune_empty_appid_branches() status_update_json(processed, failed) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index f473efd7..ec0079af 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -52,52 +52,58 @@ environment variable to include. """ +import ast +import base64 import copy import difflib -from typing import List -import git +import filecmp import glob -import io -import os -import sys -import re -import ast import gzip +import hashlib +import io +import itertools +import json +import logging +import operator +import os +import re import shutil +import socket import stat import subprocess -import time -import operator -import logging -import hashlib -import socket -import base64 -import zipfile +import sys import tempfile -import json -from pathlib import Path - -import defusedxml.ElementTree as XMLElementTree - +import time +import zipfile from argparse import BooleanOptionalAction -from asn1crypto import cms from base64 import urlsafe_b64encode from binascii import hexlify from datetime import datetime, timedelta, timezone +from pathlib import Path from queue import Queue +from typing import List from urllib.parse import urlparse, urlsplit, urlunparse from zipfile import ZipFile +import defusedxml.ElementTree as XMLElementTree +import git +from asn1crypto import cms + import fdroidserver.metadata from fdroidserver import _ -from fdroidserver._yaml import yaml, config_dump -from fdroidserver.exception import FDroidException, VCSException, NoSubmodulesException, \ - BuildException, VerificationException, MetaDataException -from .asynchronousfilereader import AsynchronousFileReader -from .looseversion import LooseVersion +from fdroidserver._yaml import config_dump, yaml +from fdroidserver.exception import ( + BuildException, + FDroidException, + MetaDataException, + NoSubmodulesException, + VCSException, + VerificationException, +) from . import apksigcopier, common - +from .asynchronousfilereader import AsynchronousFileReader +from .looseversion import LooseVersion # The path to this fdroidserver distribution FDROID_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) @@ -182,7 +188,7 @@ default_config = { 'scan_binary': False, 'ant': "ant", 'mvn3': "mvn", - 'gradle': os.path.join(FDROID_PATH, 'gradlew-fdroid'), + 'gradle': shutil.which('gradlew-fdroid'), 'sync_from_local_copy_dir': False, 'allow_disabled_algorithms': False, 'keep_when_not_allowed': False, @@ -545,6 +551,60 @@ def config_type_check(path, data): ) +class _Config(dict): + def __init__(self, default={}): + super(_Config, self).__init__(default) + self.loaded = {} + + def lazyget(self, key): + if key not in self.loaded: + value = super(_Config, self).__getitem__(key) + + if key == 'serverwebroot': + roots = parse_list_of_dicts(value) + rootlist = [] + for d in roots: + # since this is used with rsync, where trailing slashes have + # meaning, ensure there is always a trailing slash + rootstr = d.get('url') + if not rootstr: + logging.error('serverwebroot: has blank value!') + continue + if rootstr[-1] != '/': + rootstr += '/' + d['url'] = rootstr.replace('//', '/') + rootlist.append(d) + self.loaded[key] = rootlist + + elif key == 'servergitmirrors': + self.loaded[key] = parse_list_of_dicts(value) + + elif isinstance(value, dict) and 'env' in value and len(value) == 1: + var = value['env'] + if var in os.environ: + self.loaded[key] = os.getenv(var) + else: + logging.error( + _( + 'Environment variable {var} from {configname} is not set!' + ).format(var=value['env'], configname=key) + ) + self.loaded[key] = None + else: + self.loaded[key] = value + + return self.loaded[key] + + def __getitem__(self, key): + return self.lazyget(key) + + def get(self, key, default=None, /): + try: + return self.lazyget(key) + except KeyError: + return default + + def read_config(): """Read the repository config. @@ -600,25 +660,7 @@ def read_config(): fill_config_defaults(config) - if 'serverwebroot' in config: - roots = parse_list_of_dicts(config['serverwebroot']) - rootlist = [] - for d in roots: - # since this is used with rsync, where trailing slashes have - # meaning, ensure there is always a trailing slash - rootstr = d.get('url') - if not rootstr: - logging.error('serverwebroot: has blank value!') - continue - if rootstr[-1] != '/': - rootstr += '/' - d['url'] = rootstr.replace('//', '/') - rootlist.append(d) - config['serverwebroot'] = rootlist - if 'servergitmirrors' in config: - config['servergitmirrors'] = parse_list_of_dicts(config['servergitmirrors']) - limit = config['git_mirror_size_limit'] config['git_mirror_size_limit'] = parse_human_readable_size(limit) @@ -641,15 +683,7 @@ def read_config(): continue elif isinstance(dictvalue, dict): for k, v in dictvalue.items(): - if k == 'env': - env = os.getenv(v) - if env: - config[configname] = env - else: - confignames_to_delete.add(configname) - logging.error(_('Environment variable {var} from {configname} is not set!') - .format(var=k, configname=configname)) - else: + if k != 'env': confignames_to_delete.add(configname) logging.error(_('Unknown entry {key} in {configname}') .format(key=k, configname=configname)) @@ -669,6 +703,7 @@ def read_config(): ) ) + config = _Config(config) return config @@ -782,7 +817,10 @@ def load_localized_config(name, repodir): icons_dir = os.path.join(repodir, 'icons') if not os.path.exists(icons_dir): os.makedirs(icons_dir, exist_ok=True) - shutil.copy(os.path.join("config", value), icons_dir) + src = os.path.join("config", value) + dest = os.path.join(icons_dir, os.path.basename(src)) + if not os.path.exists(dest) or not filecmp.cmp(src, dest): + shutil.copy2(src, dest) ret[afname][key][locale] = file_entry( os.path.join(icons_dir, value) ) @@ -1201,6 +1239,25 @@ def get_src_tarball_name(appid, versionCode): return f"{appid}_{versionCode}_src.tar.gz" +def get_source_date_epoch(build_dir): + """Return timestamp suitable for the SOURCE_DATE_EPOCH variable. + + https://reproducible-builds.org/docs/source-date-epoch/ + + """ + try: + return git.repo.Repo(build_dir).git.log(n=1, pretty='%ct') + except Exception as e: + logging.warning('%s: %s', e.__class__.__name__, build_dir) + build_dir = Path(build_dir) + appid = build_dir.name + data_dir = build_dir.parent.parent + metadata_file = f'metadata/{appid}.yml' + if (data_dir / '.git').exists() and (data_dir / metadata_file).exists(): + repo = git.repo.Repo(data_dir) + return repo.git.log('-n1', '--pretty=%ct', '--', metadata_file) + + def get_build_dir(app): """Get the dir that this app will be built in.""" if app.RepoType == 'srclib': @@ -1286,12 +1343,29 @@ def write_status_json(output, pretty=False, name=None): rsync_status_file_to_repo(path, repo_subdir='status') -def get_head_commit_id(git_repo): - """Get git commit ID for HEAD as a str.""" +def get_head_commit_id(git_repo_dir): + """Get git commit ID for HEAD as a str. + + This only reads files, so it should be safe to use on untrusted + repos. It was created to avoid running the git executable, no + matter what. It uses a tiny subset of the git.Repo class to avoid + setting up the git executable. + + """ try: - return git_repo.head.commit.hexsha - except ValueError: - return "None" + if type(git_repo_dir) is git.Repo: + d = git_repo_dir.git_dir + else: + d = os.path.join(git_repo_dir, '.git') + repo = type( + 'Repo', + (object,), + {'common_dir': d, 'git_dir': d, 're_hexsha_only': git.Repo.re_hexsha_only}, + )() + return git.refs.symbolic.SymbolicReference.dereference_recursive(repo, 'HEAD') + except (FileNotFoundError, ValueError) as e: + msg = _("Cannot read {path}: {error}").format(path=os.getcwd(), error=str(e)) + logging.debug(msg) def setup_vcs(app): @@ -1318,6 +1392,7 @@ def getvcs(vcstype, remote, local): """ if vcstype == 'git': return vcs_git(remote, local) + logging.warning(_("RepoType {type} is deprecated, please switch to git.").format(type=vcstype)) if vcstype == 'git-svn': return vcs_gitsvn(remote, local) if vcstype == 'hg': @@ -1523,10 +1598,15 @@ class vcs_git(vcs): it! This is called as a safety check. """ - p = FDroidPopen(['git', 'rev-parse', '--show-toplevel'], cwd=self.local, output=False) + cmd = ['git', 'rev-parse', '--show-toplevel'] + p = FDroidPopen(cmd, cwd=self.local, output=False) result = p.output.rstrip() + if p.returncode > 0: + raise VCSException( + f"`{' '.join(cmd)}` failed, (in '{os.path.abspath(self.local)}') {result}" + ) if Path(result) != Path(self.local).resolve(): - raise VCSException('Repository mismatch') + raise VCSException(f"Repository mismatch ('{self.local}' != '{result}')") def gotorevisionx(self, rev): if not os.path.exists(self.local): @@ -1946,7 +2026,7 @@ def retrieve_string_singleline(app_dir, string, xmlfiles=None): return retrieve_string(app_dir, string, xmlfiles).replace('\n', ' ').strip() -def manifest_paths(app_dir, flavours): +def manifest_paths(app_dir, flavors): """Return list of existing files that will be used to find the highest vercode.""" possible_manifests = \ [Path(app_dir) / 'AndroidManifest.xml', @@ -1956,18 +2036,18 @@ def manifest_paths(app_dir, flavours): Path(app_dir) / 'build-extras.gradle', Path(app_dir) / 'build.gradle.kts'] - for flavour in flavours: - if flavour == 'yes': + for flavor in flavors: + if flavor == 'yes': continue possible_manifests.append( - Path(app_dir) / 'src' / flavour / 'AndroidManifest.xml') + Path(app_dir) / 'src' / flavor / 'AndroidManifest.xml') return [path for path in possible_manifests if path.is_file()] -def fetch_real_name(app_dir, flavours): +def fetch_real_name(app_dir, flavors): """Retrieve the package name. Returns the name, or None if not found.""" - for path in manifest_paths(app_dir, flavours): + for path in manifest_paths(app_dir, flavors): if not path.suffix == '.xml' or not path.is_file(): continue logging.debug("fetch_real_name: Checking manifest at %s" % path) @@ -2085,17 +2165,17 @@ def parse_androidmanifests(paths, app): vercode = None package = None - flavours = None + flavors = None temp_app_id = None temp_version_name = None if len(app.get('Builds', [])) > 0 and 'gradle' in app['Builds'][-1] and app['Builds'][-1].gradle: - flavours = app['Builds'][-1].gradle + flavors = app['Builds'][-1].gradle if path.suffix == '.gradle' or path.name.endswith('.gradle.kts'): with open(path, 'r', encoding='utf-8') as f: android_plugin_file = False - inside_flavour_group = 0 - inside_required_flavour = 0 + inside_flavor_group = 0 + inside_required_flavor = 0 for line in f: if gradle_comment.match(line): continue @@ -2110,8 +2190,8 @@ def parse_androidmanifests(paths, app): if matches: temp_version_name = matches - if inside_flavour_group > 0: - if inside_required_flavour > 1: + if inside_flavor_group > 0: + if inside_required_flavor > 1: matches = psearch_g(line) if matches: s = matches.group(2) @@ -2141,29 +2221,29 @@ def parse_androidmanifests(paths, app): if matches: vercode = version_code_string_to_int(matches.group(1)) - if inside_required_flavour > 0: + if inside_required_flavor > 0: if '{' in line: - inside_required_flavour += 1 + inside_required_flavor += 1 if '}' in line: - inside_required_flavour -= 1 - if inside_required_flavour == 1: - inside_required_flavour -= 1 - elif flavours: - for flavour in flavours: - if re.match(r'.*[\'"\s]{flavour}[\'"\s].*\{{.*'.format(flavour=flavour), line): - inside_required_flavour = 2 + inside_required_flavor -= 1 + if inside_required_flavor == 1: + inside_required_flavor -= 1 + elif flavors: + for flavor in flavors: + if re.match(r'.*[\'"\s]{flavor}[\'"\s].*\{{.*'.format(flavor=flavor), line): + inside_required_flavor = 2 break - if re.match(r'.*[\'"\s]{flavour}[\'"\s].*'.format(flavour=flavour), line): - inside_required_flavour = 1 + if re.match(r'.*[\'"\s]{flavor}[\'"\s].*'.format(flavor=flavor), line): + inside_required_flavor = 1 break if '{' in line: - inside_flavour_group += 1 + inside_flavor_group += 1 if '}' in line: - inside_flavour_group -= 1 + inside_flavor_group -= 1 else: if "productFlavors" in line: - inside_flavour_group = 1 + inside_flavor_group = 1 if not package: matches = psearch_g(line) if matches: @@ -2507,9 +2587,9 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= with open(path, 'w', encoding='iso-8859-1') as f: f.write(props) - flavours = [] + flavors = [] if build.build_method() == 'gradle': - flavours = build.gradle + flavors = build.gradle if build.target: n = build.target.split('-')[1] @@ -2531,7 +2611,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= # Insert version code and number into the manifest if necessary if build.forceversion: logging.info("Changing the version name") - for path in manifest_paths(root_dir, flavours): + for path in manifest_paths(root_dir, flavors): if not os.path.isfile(path): continue if path.suffix == '.xml': @@ -2545,7 +2625,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver= if build.forcevercode: logging.info("Changing the version code") - for path in manifest_paths(root_dir, flavours): + for path in manifest_paths(root_dir, flavors): if not path.is_file(): continue if path.suffix == '.xml': @@ -2657,17 +2737,17 @@ def getpaths_map(build_dir, globpaths): paths[p] = [r[len(str(build_dir)) + 1:] for r in glob.glob(full_path)] if not paths[p]: not_found_paths.append(p) + return paths, not_found_paths + + +def getpaths(build_dir, globpaths): + """Extend via globbing the paths from a field and return them as a set.""" + paths_map, not_found_paths = getpaths_map(build_dir, globpaths) if not_found_paths: raise FDroidException( "Some glob paths did not match any files/dirs:\n" + "\n".join(not_found_paths) ) - return paths - - -def getpaths(build_dir, globpaths): - """Extend via globbing the paths from a field and return them as a set.""" - paths_map = getpaths_map(build_dir, globpaths) paths = set() for k, v in paths_map.items(): for p in v: @@ -2828,9 +2908,9 @@ def is_debuggable_or_testOnly(apkfile): return False try: # these were moved in androguard 4.0 - from androguard.core.axml import AXMLParser, format_value, START_TAG + from androguard.core.axml import START_TAG, AXMLParser, format_value except ImportError: - from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG + from androguard.core.bytecodes.axml import START_TAG, AXMLParser, format_value _androguard_logging_level() with ZipFile(apkfile) as apk: @@ -2902,9 +2982,23 @@ def get_apk_id_androguard(apkfile): try: # these were moved in androguard 4.0 - from androguard.core.axml import AXMLParser, format_value, START_TAG, END_TAG, TEXT, END_DOCUMENT + from androguard.core.axml import ( + END_DOCUMENT, + END_TAG, + START_TAG, + TEXT, + AXMLParser, + format_value, + ) except ImportError: - from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG, END_TAG, TEXT, END_DOCUMENT + from androguard.core.bytecodes.axml import ( + END_DOCUMENT, + END_TAG, + START_TAG, + TEXT, + AXMLParser, + format_value, + ) _androguard_logging_level() appid = None @@ -3180,12 +3274,16 @@ def remove_signing_keys(build_dir): logging.info("Cleaned %s of keysigning configs at %s" % (propfile, path)) -def set_FDroidPopen_env(build=None): +def set_FDroidPopen_env(app=None, build=None): """Set up the environment variables for the build environment. There is only a weak standard, the variables used by gradle, so also set up the most commonly used environment variables for SDK and NDK. Also, if there is no locale set, this will set the locale (e.g. LANG) to en_US.UTF-8. + + If an App instance is provided, then the SOURCE_DATE_EPOCH + environment variable will be set based on that app's source repo. + """ global env, orig_path @@ -3208,6 +3306,8 @@ def set_FDroidPopen_env(build=None): if missinglocale: env['LANG'] = 'en_US.UTF-8' + if app: + env['SOURCE_DATE_EPOCH'] = get_source_date_epoch(get_build_dir(app)) if build is not None: path = build.ndk_path() paths = orig_path.split(os.pathsep) @@ -3410,22 +3510,6 @@ def apk_signer_fingerprint(apk_path): return signer_fingerprint(cert_encoded) -def apk_signer_fingerprint_short(apk_path): - """Get 7 hex digit SHA-256 fingerprint string for the first signer from given APK. - - Parameters - ---------- - apk_path - path to APK - - Returns - ------- - first 7 chars of the standard SHA-256 signer fingerprint - - """ - return apk_signer_fingerprint(apk_path)[:7] - - def metadata_get_sigdir(appid, vercode=None): """Get signature directory for app.""" if vercode: @@ -3958,11 +4042,13 @@ def compare_apks(apk1, apk2, tmp_dir, log_dir=None): f.extractall(path=os.path.join(apk2dir, 'content')) if set_command_in_config('apktool'): - if subprocess.call([config['apktool'], 'd', absapk1, '--output', 'apktool'], - cwd=apk1dir) != 0: + if subprocess.call( + [config['apktool'], 'd', absapk1, '--output', 'apktool'], cwd=apk1dir + ): return "Failed to run apktool " + apk1 - if subprocess.call([config['apktool'], 'd', absapk2, '--output', 'apktool'], - cwd=apk2dir) != 0: + if subprocess.call( + [config['apktool'], 'd', absapk2, '--output', 'apktool'], cwd=apk2dir + ): return "Failed to run apktool " + apk2 p = FDroidPopen(['diff', '-r', apk1dir, apk2dir], output=False) @@ -4790,6 +4876,20 @@ def calculate_archive_policy(app, default): return archive_policy +def calculate_gradle_flavor_combination(flavors): + """Calculate all combinations of gradle flavors.""" + combination_lists = itertools.product(*[[flavor, ''] for flavor in flavors]) + combinations = [ + re.sub( + r' +\w', + lambda pat: pat.group(0)[-1].upper(), + ' '.join(combination_list).strip(), + ) + for combination_list in combination_lists + ] + return combinations + + FDROIDORG_MIRRORS = [ { 'isPrimary': True, diff --git a/fdroidserver/deploy.py b/fdroidserver/deploy.py index ad108340..b4f98f34 100644 --- a/fdroidserver/deploy.py +++ b/fdroidserver/deploy.py @@ -16,28 +16,28 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import sys import glob import hashlib import json +import logging import os +import pathlib import re +import shutil import subprocess +import sys import time import urllib -from typing import Dict, List -from git import Repo -import yaml from argparse import ArgumentParser -import logging -import pathlib -import shutil +from typing import Dict, List + import git +import yaml +from git import Repo + import fdroidserver.github -from . import _ -from . import common -from . import index +from . import _, common, index from .exception import FDroidException config = None @@ -349,8 +349,8 @@ def update_awsbucket_libcloud(repo_section, is_index_only=False): import libcloud.security libcloud.security.VERIFY_SSL_CERT = True - from libcloud.storage.types import Provider, ContainerDoesNotExistError from libcloud.storage.providers import get_driver + from libcloud.storage.types import ContainerDoesNotExistError, Provider if not config.get('awsaccesskeyid') or not config.get('awssecretkey'): raise FDroidException( @@ -617,6 +617,13 @@ def update_servergitmirrors(servergitmirrors, repo_section): For history, there is the archive section, and there is the binary transparency log. + This will attempt to use the existing remote branch so that it does + not have to push all of the files in the repo each time. Old setups + or runs of `fdroid nightly` might use the "master" branch. For the + "index only" mode, it will recreate the branch from scratch each + time since usually all the files are changed. In any case, the + index files are small compared to the full repo. + """ from clint.textui import progress @@ -687,7 +694,7 @@ def update_servergitmirrors(servergitmirrors, repo_section): if is_index_only: local_branch_name = 'index_only' else: - local_branch_name = 'full' + local_branch_name = GIT_BRANCH if local_branch_name in repo.heads: repo.git.switch(local_branch_name) else: @@ -847,9 +854,10 @@ def upload_to_android_observatory(repo_section): 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 + from . import net + apkfilename = os.path.basename(path) r = requests.post( 'https://androidobservatory.org/', diff --git a/fdroidserver/exception.py b/fdroidserver/exception.py index a598b368..682ccef7 100644 --- a/fdroidserver/exception.py +++ b/fdroidserver/exception.py @@ -35,6 +35,10 @@ class VCSException(FDroidException): pass +class NoVersionCodeException(FDroidException): + pass + + class NoSubmodulesException(VCSException): pass diff --git a/fdroidserver/github.py b/fdroidserver/github.py index 0a6844d9..34a3ee53 100644 --- a/fdroidserver/github.py +++ b/fdroidserver/github.py @@ -18,8 +18,8 @@ import json import pathlib -import urllib.request import urllib.parse +import urllib.request class GithubApi: diff --git a/fdroidserver/gpgsign.py b/fdroidserver/gpgsign.py index 4ba6ebd5..4341cb36 100644 --- a/fdroidserver/gpgsign.py +++ b/fdroidserver/gpgsign.py @@ -16,14 +16,13 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import os import glob -from argparse import ArgumentParser import logging +import os import time +from argparse import ArgumentParser -from . import _ -from . import common +from . import _, common from .common import FDroidPopen from .exception import FDroidException diff --git a/fdroidserver/import_subcommand.py b/fdroidserver/import_subcommand.py index b9f9a4c4..345c2891 100644 --- a/fdroidserver/import_subcommand.py +++ b/fdroidserver/import_subcommand.py @@ -342,7 +342,7 @@ def main(): app.AutoUpdateMode = 'Version' app.UpdateCheckMode = 'Tags' - build.commit = common.get_head_commit_id(git_repo) + build.commit = common.get_head_commit_id(tmp_importer_dir) # Extract some information... paths = get_all_gradle_and_manifests(tmp_importer_dir) diff --git a/fdroidserver/index.py b/fdroidserver/index.py index 6df110dd..b63729e4 100644 --- a/fdroidserver/index.py +++ b/fdroidserver/index.py @@ -30,6 +30,7 @@ these installed on the signing server. """ +import calendar import collections import hashlib import json @@ -41,20 +42,27 @@ import sys import tempfile import urllib.parse import zipfile -import calendar from binascii import hexlify, unhexlify from datetime import datetime, timezone from pathlib import Path from xml.dom.minidom import Document -from . import _ -from . import common -from . import metadata -from . import signindex -from fdroidserver.common import ANTIFEATURES_CONFIG_NAME, CATEGORIES_CONFIG_NAME, CONFIG_CONFIG_NAME, MIRRORS_CONFIG_NAME, RELEASECHANNELS_CONFIG_NAME, DEFAULT_LOCALE, FDroidPopen, FDroidPopenBytes, load_publish_signer_fingerprints from fdroidserver._yaml import yaml +from fdroidserver.common import ( + ANTIFEATURES_CONFIG_NAME, + CATEGORIES_CONFIG_NAME, + CONFIG_CONFIG_NAME, + DEFAULT_LOCALE, + MIRRORS_CONFIG_NAME, + RELEASECHANNELS_CONFIG_NAME, + FDroidPopen, + FDroidPopenBytes, + load_publish_signer_fingerprints, +) from fdroidserver.exception import FDroidException, VerificationException +from . import _, common, metadata, signindex + def make(apps, apks, repodir, archive): """Generate the repo index files. @@ -152,11 +160,6 @@ def _should_file_be_generated(path, magic_string): def make_website(apps, repodir, repodict): - _ignored, repo_pubkey_fingerprint = extract_pubkey() - repo_pubkey_fingerprint_stripped = repo_pubkey_fingerprint.replace(" ", "") - link = repodict["address"] - link_fingerprinted = ('{link}?fingerprint={fingerprint}' - .format(link=link, fingerprint=repo_pubkey_fingerprint_stripped)) # do not change this string, as it will break updates for files with older versions of this string autogenerate_comment = "auto-generated - fdroid index updates will overwrite this file" @@ -168,6 +171,13 @@ def make_website(apps, repodir, repodict): if _should_file_be_generated(html_file, autogenerate_comment): import qrcode + + _ignored, repo_pubkey_fingerprint = extract_pubkey() + repo_pubkey_fingerprint_stripped = repo_pubkey_fingerprint.replace(" ", "") + link = repodict["address"] + link_fingerprinted = '{link}?fingerprint={fingerprint}'.format( + link=link, fingerprint=repo_pubkey_fingerprint_stripped + ) qrcode.make(link_fingerprinted).save(os.path.join(repodir, "index.png")) with open(html_file, 'w') as f: name = repodict["name"] @@ -585,7 +595,10 @@ def convert_version(version, app, repodir): ver["file"]["ipfsCIDv1"] = ipfsCIDv1 if "srcname" in version: - ver["src"] = common.file_entry(os.path.join(repodir, version["srcname"])) + ver["src"] = common.file_entry( + os.path.join(repodir, version["srcname"]), + version["srcnameSha256"], + ) if "obbMainFile" in version: ver["obbMainFile"] = common.file_entry( @@ -681,9 +694,13 @@ def v2_repo(repodict, repodir, archive): config = common.load_localized_config(CONFIG_CONFIG_NAME, repodir) if config: - repo["name"] = config["archive" if archive else "repo"]["name"] - repo["description"] = config["archive" if archive else "repo"]["description"] - repo["icon"] = config["archive" if archive else "repo"]["icon"] + localized_config = config["archive" if archive else "repo"] + if "name" in localized_config: + repo["name"] = localized_config["name"] + if "description" in localized_config: + repo["description"] = localized_config["description"] + if "icon" in localized_config: + repo["icon"] = localized_config["icon"] repo["address"] = repodict["address"] if "mirrors" in repodict: @@ -769,7 +786,9 @@ def make_v2(apps, packages, repodir, repodict, requestsdict, signer_fingerprints # include definitions for "auto-defined" categories, e.g. just used in app metadata for category in sorted(categories_used_by_apps): if category not in output['repo'][CATEGORIES_CONFIG_NAME]: - output['repo'][CATEGORIES_CONFIG_NAME][category] = {"name": {DEFAULT_LOCALE: category}} + output['repo'][CATEGORIES_CONFIG_NAME][category] = dict() + if 'name' not in output['repo'][CATEGORIES_CONFIG_NAME][category]: + output['repo'][CATEGORIES_CONFIG_NAME][category]['name'] = {DEFAULT_LOCALE: category} # do not include defined categories if no apps use them for category in list(output['repo'].get(CATEGORIES_CONFIG_NAME, list())): if category not in categories_used_by_apps: @@ -948,7 +967,7 @@ def make_v1(apps, packages, repodir, repodict, requestsdict, signer_fingerprints for k, v in sorted(package.items()): if not v: continue - if k in ('icon', 'icons', 'icons_src', 'ipfsCIDv1', 'name'): + if k in ('icon', 'icons', 'icons_src', 'ipfsCIDv1', 'name', 'srcnameSha256'): continue if k == 'antiFeatures': d[k] = sorted(v.keys()) diff --git a/fdroidserver/init.py b/fdroidserver/init.py index a5575fea..39b18c1a 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -19,16 +19,15 @@ # along with this program. If not, see . import glob +import logging import os import re import shutil import socket import sys from argparse import ArgumentParser -import logging -from . import _ -from . import common +from . import _, common from .exception import FDroidException config = {} diff --git a/fdroidserver/install.py b/fdroidserver/install.py index 74754520..8c1dc948 100644 --- a/fdroidserver/install.py +++ b/fdroidserver/install.py @@ -17,24 +17,21 @@ # 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 glob import locale import logging +import os +import sys import termios import tty - -import defusedxml.ElementTree as XMLElementTree - from argparse import ArgumentParser, BooleanOptionalAction from pathlib import Path from urllib.parse import urlencode, urlparse, urlunparse -from . import _ -from . import common, github, index, net -from .exception import FDroidException +import defusedxml.ElementTree as XMLElementTree +from . import _, common, github, index, net +from .exception import FDroidException DEFAULT_IPFS_GATEWAYS = ("https://gateway.ipfs.io/ipfs/",) MAVEN_CENTRAL_MIRRORS = [ diff --git a/fdroidserver/lint.py b/fdroidserver/lint.py index 6a4299bd..f384cb62 100644 --- a/fdroidserver/lint.py +++ b/fdroidserver/lint.py @@ -24,9 +24,10 @@ import urllib.parse from argparse import ArgumentParser from pathlib import Path -from . import _, common, metadata, rewritemeta from fdroidserver._yaml import yaml +from . import _, common, metadata, rewritemeta + config = None @@ -274,6 +275,7 @@ check_config_keys = ( 'repo', 'repo_description', 'repo_icon', + 'repo_key_sha256', 'repo_keyalias', 'repo_maxage', 'repo_name', diff --git a/fdroidserver/looseversion.py b/fdroidserver/looseversion.py index 0c785d69..c2a32213 100644 --- a/fdroidserver/looseversion.py +++ b/fdroidserver/looseversion.py @@ -115,7 +115,7 @@ __license__ = "Python License 2.0" # been done in the StrictVersion class above. This works great as long # as everyone can go along with bondage and discipline. Hopefully a # (large) subset of Python module programmers will agree that the -# particular flavour of bondage and discipline provided by StrictVersion +# particular flavor of bondage and discipline provided by StrictVersion # provides enough benefit to be worth using, and will submit their # version numbering scheme to its domination. The free-thinking # anarchists in the lot will never give in, though, and something needs diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 08d275ae..0d9195be 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -18,20 +18,19 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import git -from pathlib import Path -import math -import platform -import os -import re import logging -import ruamel.yaml +import math +import os +import platform +import re from collections import OrderedDict +from pathlib import Path -from . import common -from . import _ -from .exception import MetaDataException +import ruamel.yaml + +from . import _, common from ._yaml import yaml +from .exception import MetaDataException srclibs = None warnings_action = None @@ -538,10 +537,10 @@ def read_srclibs(): srclibs = {} - srcdir = Path('srclibs') - srcdir.mkdir(exist_ok=True) + srclibs_dir = Path('srclibs') + srclibs_dir.mkdir(exist_ok=True) - for metadatapath in sorted(srcdir.glob('*.yml')): + for metadatapath in sorted(srclibs_dir.glob('*.yml')): srclibs[metadatapath.stem] = parse_yaml_srclib(metadatapath) @@ -658,14 +657,12 @@ def parse_metadata(metadatapath): build_dir = common.get_build_dir(app) metadata_in_repo = build_dir / '.fdroid.yml' if metadata_in_repo.is_file(): - try: - commit_id = common.get_head_commit_id(git.Repo(build_dir)) + commit_id = common.get_head_commit_id(build_dir) + if commit_id is not None: logging.debug( _('Including metadata from %s@%s') % (metadata_in_repo, commit_id) ) - # See https://github.com/PyCQA/pylint/issues/2856 . - # pylint: disable-next=no-member - except git.exc.InvalidGitRepositoryError: + else: logging.debug( _('Including metadata from {path}').format(path=metadata_in_repo) ) diff --git a/fdroidserver/mirror.py b/fdroidserver/mirror.py index 80f8394f..b06df3b1 100644 --- a/fdroidserver/mirror.py +++ b/fdroidserver/mirror.py @@ -7,13 +7,10 @@ import posixpath import socket import subprocess import sys -from argparse import ArgumentParser import urllib.parse +from argparse import ArgumentParser -from . import _ -from . import common -from . import index -from . import update +from . import _, common, index, update def _run_wget(path, urls, verbose=False): @@ -133,6 +130,7 @@ def main(): import io import json import zipfile + from . import net url = _append_to_url_path(section, 'index-v1.jar') diff --git a/fdroidserver/net.py b/fdroidserver/net.py index 1ec7d096..fe097fd5 100644 --- a/fdroidserver/net.py +++ b/fdroidserver/net.py @@ -21,10 +21,11 @@ import copy import logging import os import random -import requests import tempfile import time import urllib + +import requests import urllib3 from requests.adapters import HTTPAdapter, Retry diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 3eb4333c..372390ea 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -19,24 +19,25 @@ import base64 import datetime -import git import hashlib +import inspect import logging import os -import paramiko import platform import shutil import ssl import subprocess import sys import tempfile -import yaml -from urllib.parse import urlparse from argparse import ArgumentParser from typing import Optional +from urllib.parse import urlparse -from . import _ -from . import common +import git +import paramiko +import yaml + +from . import _, common from .exception import VCSException # hard coded defaults for Android ~/.android/debug.keystore files @@ -176,7 +177,9 @@ def _ssh_key_from_debug_keystore(keystore: Optional[str] = None) -> str: return ssh_private_key_file -def get_repo_base_url(clone_url: str, repo_git_base: str, force_type: Optional[str] = None) -> str: +def get_repo_base_url( + clone_url: str, repo_git_base: str, force_type: Optional[str] = None +) -> str: """Generate the base URL for the F-Droid repository. Parameters @@ -203,6 +206,41 @@ def get_repo_base_url(clone_url: str, repo_git_base: str, force_type: Optional[s sys.exit(1) +def clone_git_repo(clone_url, git_mirror_path): + """Clone a git repo into the given path, failing if a password is required. + + If GitPython's safe mode is present, this will use that. Otherwise, + this includes a very limited version of the safe mode just to ensure + this won't hang on password prompts. + + https://github.com/gitpython-developers/GitPython/pull/2029 + + """ + logging.debug(_('cloning {url}').format(url=clone_url)) + try: + sig = inspect.signature(git.Repo.clone_from) + if 'safe' in sig.parameters: + git.Repo.clone_from(clone_url, git_mirror_path, safe=True) + else: + git.Repo.clone_from( + clone_url, + git_mirror_path, + env={ + 'GIT_ASKPASS': '/bin/true', + 'SSH_ASKPASS': '/bin/true', + 'GIT_USERNAME': 'u', + 'GIT_PASSWORD': 'p', + 'GIT_HTTP_USERNAME': 'u', + 'GIT_HTTP_PASSWORD': 'p', + 'GIT_SSH': '/bin/false', # for git < 2.3 + 'GIT_TERMINAL_PROMPT': '0', + }, + ) + except git.exc.GitCommandError as e: + logging.warning(_('WARNING: only public git repos are supported!')) + raise VCSException(f'git clone {clone_url} failed:', str(e)) from e + + def main(): """Deploy to F-Droid repository or generate SSH private key from keystore. @@ -288,19 +326,27 @@ def main(): # we are in GitLab CI repo_git_base = os.getenv('CI_PROJECT_PATH') + NIGHTLY clone_url = os.getenv('CI_PROJECT_URL') + NIGHTLY - repo_base = get_repo_base_url(clone_url, repo_git_base, force_type='gitlab.com') + repo_base = get_repo_base_url( + clone_url, repo_git_base, force_type='gitlab.com' + ) servergitmirror = 'git@' + urlparse(clone_url).netloc + ':' + repo_git_base - deploy_key_url = clone_url + '/-/settings/repository#js-deploy-keys-settings' + deploy_key_url = ( + f'{clone_url}/-/settings/repository#js-deploy-keys-settings' + ) git_user_name = os.getenv('GITLAB_USER_NAME') git_user_email = os.getenv('GITLAB_USER_EMAIL') elif 'TRAVIS_REPO_SLUG' in os.environ: # we are in Travis CI repo_git_base = os.getenv('TRAVIS_REPO_SLUG') + NIGHTLY clone_url = 'https://github.com/' + repo_git_base - repo_base = get_repo_base_url(clone_url, repo_git_base, force_type='github.com') + repo_base = get_repo_base_url( + clone_url, repo_git_base, force_type='github.com' + ) servergitmirror = 'git@github.com:' + repo_git_base - deploy_key_url = ('https://github.com/' + repo_git_base + '/settings/keys' - + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys') + deploy_key_url = ( + f'https://github.com/{repo_git_base}/settings/keys' + + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys' + ) git_user_name = repo_git_base git_user_email = os.getenv('USER') + '@' + platform.node() elif ( @@ -309,23 +355,35 @@ def main(): and 'CIRCLE_PROJECT_REPONAME' in os.environ ): # we are in Circle CI - repo_git_base = (os.getenv('CIRCLE_PROJECT_USERNAME') - + '/' + os.getenv('CIRCLE_PROJECT_REPONAME') + NIGHTLY) + repo_git_base = ( + os.getenv('CIRCLE_PROJECT_USERNAME') + + '/' + + os.getenv('CIRCLE_PROJECT_REPONAME') + + NIGHTLY + ) clone_url = os.getenv('CIRCLE_REPOSITORY_URL') + NIGHTLY - repo_base = get_repo_base_url(clone_url, repo_git_base, force_type='github.com') + repo_base = get_repo_base_url( + clone_url, repo_git_base, force_type='github.com' + ) servergitmirror = 'git@' + urlparse(clone_url).netloc + ':' + repo_git_base - deploy_key_url = ('https://github.com/' + repo_git_base + '/settings/keys' - + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys') + deploy_key_url = ( + f'https://github.com/{repo_git_base}/settings/keys' + + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys' + ) git_user_name = os.getenv('CIRCLE_USERNAME') git_user_email = git_user_name + '@' + platform.node() elif 'GITHUB_ACTIONS' in os.environ: # we are in Github actions - repo_git_base = (os.getenv('GITHUB_REPOSITORY') + NIGHTLY) - clone_url = (os.getenv('GITHUB_SERVER_URL') + '/' + repo_git_base) - repo_base = get_repo_base_url(clone_url, repo_git_base, force_type='github.com') + repo_git_base = os.getenv('GITHUB_REPOSITORY') + NIGHTLY + clone_url = os.getenv('GITHUB_SERVER_URL') + '/' + repo_git_base + repo_base = get_repo_base_url( + clone_url, repo_git_base, force_type='github.com' + ) servergitmirror = 'git@' + urlparse(clone_url).netloc + ':' + repo_git_base - deploy_key_url = ('https://github.com/' + repo_git_base + '/settings/keys' - + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys') + deploy_key_url = ( + f'https://github.com/{repo_git_base}/settings/keys' + + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys' + ) git_user_name = os.getenv('GITHUB_ACTOR') git_user_email = git_user_name + '@' + platform.node() else: @@ -338,14 +396,11 @@ def main(): git_mirror_repodir = os.path.join(git_mirror_fdroiddir, 'repo') git_mirror_metadatadir = os.path.join(git_mirror_fdroiddir, 'metadata') if not os.path.isdir(git_mirror_repodir): - logging.debug(_('cloning {url}').format(url=clone_url)) - vcs = common.getvcs('git', clone_url, git_mirror_path) - p = vcs.git(['clone', '--', vcs.remote, str(vcs.local)]) - if p.returncode != 0: - print('WARNING: only public git repos are supported!') - raise VCSException('git clone %s failed:' % clone_url, p.output) + clone_git_repo(clone_url, git_mirror_path) if not os.path.isdir(git_mirror_repodir): os.makedirs(git_mirror_repodir, mode=0o755) + if os.path.exists('LICENSE'): + shutil.copy2('LICENSE', git_mirror_path) mirror_git_repo = git.Repo.init(git_mirror_path) writer = mirror_git_repo.config_writer() @@ -364,9 +419,13 @@ You can use it with the [F-Droid](https://f-droid.org/) Android app. [![{repo_url}]({repo_url}/icons/icon.png)](https://fdroid.link/#{repo_url}) -Last updated: {date}'''.format(repo_git_base=repo_git_base, - repo_url=repo_url, - date=datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')) +Last updated: {date}'''.format( + repo_git_base=repo_git_base, + repo_url=repo_url, + date=datetime.datetime.now(datetime.timezone.utc).strftime( + '%Y-%m-%d %H:%M:%S UTC' + ), + ) with open(readme_path, 'w') as fp: fp.write(readme) mirror_git_repo.git.add(all=True) @@ -427,10 +486,9 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, common.assert_config_keystore(config) logging.debug( - _('Run over {cibase} to find -debug.apk. and skip repo_basedir {repo_basedir}').format( - cibase=cibase, - repo_basedir=repo_basedir - ) + _( + 'Run over {cibase} to find -debug.apk. and skip repo_basedir {repo_basedir}' + ).format(cibase=cibase, repo_basedir=repo_basedir) ) for root, dirs, files in os.walk(cibase): @@ -518,10 +576,16 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base, if not os.path.exists(androiddir): os.mkdir(androiddir) logging.info(_('created {path}').format(path=androiddir)) - logging.error(_('{path} does not exist! Create it by running:').format(path=options.keystore) - + '\n keytool -genkey -v -keystore ' + options.keystore + ' -storepass android \\' - + '\n -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 \\' - + '\n -dname "CN=Android Debug,O=Android,C=US"') + logging.error( + _('{path} does not exist! Create it by running:').format( + path=options.keystore + ) + + '\n keytool -genkey -v -keystore ' + + options.keystore + + ' -storepass android \\' + + '\n -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 \\' + + '\n -dname "CN=Android Debug,O=Android,C=US"' + ) sys.exit(1) ssh_dir = os.path.join(os.getenv('HOME'), '.ssh') privkey = _ssh_key_from_debug_keystore(options.keystore) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index 4c0bd791..42945166 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -28,23 +28,21 @@ mostly reports success by moving an APK from unsigned/ to repo/ """ -import sys +import glob +import hashlib +import json +import logging import os import re import shutil -import glob -import hashlib -from argparse import ArgumentParser -from collections import OrderedDict -import logging -from gettext import ngettext -import json +import sys import time import zipfile +from argparse import ArgumentParser +from collections import OrderedDict +from gettext import ngettext -from . import _ -from . import common -from . import metadata +from . import _, common, metadata from .common import FDroidPopen from .exception import BuildException, FDroidException diff --git a/fdroidserver/readmeta.py b/fdroidserver/readmeta.py index b8049a9f..b3ef7c3b 100644 --- a/fdroidserver/readmeta.py +++ b/fdroidserver/readmeta.py @@ -17,8 +17,8 @@ # along with this program. If not, see . from argparse import ArgumentParser -from . import common -from . import metadata + +from . import common, metadata def main(): diff --git a/fdroidserver/rewritemeta.py b/fdroidserver/rewritemeta.py index 9f3316b4..4bbe810d 100644 --- a/fdroidserver/rewritemeta.py +++ b/fdroidserver/rewritemeta.py @@ -17,16 +17,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from argparse import ArgumentParser -import logging import io -import tempfile +import logging import shutil +import tempfile +from argparse import ArgumentParser from pathlib import Path -from . import _ -from . import common -from . import metadata +from . import _, common, metadata config = None diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index c6cd57a0..0d5a3ecf 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -270,9 +270,10 @@ def get_gradle_compile_commands(build): 'runtimeOnly', ] buildTypes = ['', 'release'] - flavors = [''] if build.gradle and build.gradle != ['yes']: - flavors += build.gradle + flavors = common.calculate_gradle_flavor_combination(build.gradle) + else: + flavors = [''] return [''.join(c) for c in itertools.product(flavors, buildTypes, compileCommands)] @@ -728,6 +729,7 @@ def scan_source(build_dir, build=metadata.Build(), json_per_build=None): 'www.jitpack.io', 'repo.maven.apache.org/maven2', 'oss.jfrog.org/artifactory/oss-snapshot-local', + 'central.sonatype.com/repository/maven-snapshots/', 'oss.sonatype.org/content/repositories/snapshots', 'oss.sonatype.org/content/repositories/releases', 'oss.sonatype.org/content/groups/public', @@ -749,8 +751,12 @@ def scan_source(build_dir, build=metadata.Build(), json_per_build=None): ] ] - scanignore = common.getpaths_map(build_dir, build.scanignore) - scandelete = common.getpaths_map(build_dir, build.scandelete) + scanignore, scanignore_not_found_paths = common.getpaths_map( + build_dir, build.scanignore + ) + scandelete, scandelete_not_found_paths = common.getpaths_map( + build_dir, build.scandelete + ) scanignore_worked = set() scandelete_worked = set() @@ -1108,11 +1114,19 @@ def scan_source(build_dir, build=metadata.Build(), json_per_build=None): json_per_build, ) + for p in scanignore_not_found_paths: + logging.error(_("Non-exist scanignore path: %s") % p) + count += 1 + for p in scanignore: if p not in scanignore_worked: logging.error(_('Unused scanignore path: %s') % p) count += 1 + for p in scandelete_not_found_paths: + logging.error(_("Non-exist scandelete path: %s") % p) + count += 1 + for p in scandelete: if p not in scandelete_worked: logging.error(_('Unused scandelete path: %s') % p) @@ -2217,8 +2231,7 @@ SUSS_DEFAULT = r'''{ "https://www.android.com/gms/" ], "gradle_signatures": [ - "com.google.gms(?!.google-services)", - "com.google.android.gms(?!.oss-licenses-plugin)", + "com.google.android.gms(?!.(oss-licenses-plugin|strict-version-matcher-plugin))", "com.google.android.ump", "androidx.core:core-google-shortcuts", "androidx.credentials:credentials-play-services-auth", @@ -2234,7 +2247,19 @@ SUSS_DEFAULT = r'''{ "com.yayandroid:locationmanager", "(?. +import logging +import os +import re +import sys from argparse import ArgumentParser -import re -import os -import sys -import logging - -from . import _ -from . import common +from . import _, common from .exception import FDroidException diff --git a/fdroidserver/signindex.py b/fdroidserver/signindex.py index 4ca2d569..47cd5ec2 100644 --- a/fdroidserver/signindex.py +++ b/fdroidserver/signindex.py @@ -17,15 +17,13 @@ # along with this program. If not, see . import json +import logging import os import time import zipfile from argparse import ArgumentParser -import logging -from . import _ -from . import common -from . import metadata +from . import _, common, metadata from .exception import FDroidException config = None diff --git a/fdroidserver/tail.py b/fdroidserver/tail.py index 8107f10d..2bea3504 100644 --- a/fdroidserver/tail.py +++ b/fdroidserver/tail.py @@ -28,8 +28,8 @@ Example import os import sys -import time import threading +import time class Tail(object): diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 4e5aad9e..52e9f7f0 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -20,25 +20,27 @@ # along with this program. If not, see . import argparse -import sys -import os -import shutil +import copy +import filecmp import glob -import logging -import re -import socket -import warnings -import zipfile import hashlib import json +import logging +import os +import re +import shutil +import socket +import sys import time -import yaml -import copy +import warnings +import zipfile +from argparse import ArgumentParser +from datetime import datetime, timezone +from pathlib import Path + import asn1crypto.cms import defusedxml.ElementTree as ElementTree -from datetime import datetime, timezone -from argparse import ArgumentParser -from pathlib import Path +import yaml try: from yaml import CSafeLoader as SafeLoader @@ -48,14 +50,13 @@ except ImportError: import collections from binascii import hexlify -from . import _ -from . import common -from . import metadata -from .common import DEFAULT_LOCALE -from .exception import BuildException, FDroidException, VerificationException +from PIL import Image, PngImagePlugin + import fdroidserver.index -from PIL import Image, PngImagePlugin +from . import _, common, metadata +from .common import DEFAULT_LOCALE +from .exception import BuildException, FDroidException, NoVersionCodeException, VerificationException if hasattr(Image, 'DecompressionBombWarning'): warnings.simplefilter('error', Image.DecompressionBombWarning) @@ -133,7 +134,7 @@ def disabled_algorithms_allowed(): or common.default_config['allow_disabled_algorithms']) -def status_update_json(apps, apks): +def status_update_json(output, apps, apks): """Output a JSON file with metadata about this `fdroid update` run. Parameters @@ -145,7 +146,6 @@ def status_update_json(apps, apks): """ logging.debug(_('Outputting JSON')) - output = common.setup_status_output(start_timestamp) output['antiFeatures'] = dict() output['disabled'] = [] output['archivePolicy0'] = [] @@ -370,6 +370,12 @@ def get_cache(): v['antiFeatures'] = {k: {} for k in sorted(v['antiFeatures'])} if 'added' in v: v['added'] = datetime.fromtimestamp(v['added'], tz=timezone.utc) + if v.get('srcname') and not v.get('srcnameSha256'): + f = f'archive/{v["srcname"]}' + if not os.path.exists(f): + f = f'repo/{v["srcname"]}' + if os.path.exists(f): + v['srcnameSha256'] = common.sha256sum(f) return apkcache @@ -801,14 +807,18 @@ def _strip_and_copy_image(in_file, outpath): 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. + This only uses ctime/mtime to check for a new file since this + process actually modifies the resulting file to strip out the EXIF. + Therefore, whenever the file needs to be stripped, it will have a + newer ctime and most likely a different size. The mtime is copied + from the source to the destination, so it can be the same. 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 %s %s', in_file, outpath) @@ -824,12 +834,11 @@ def _strip_and_copy_image(in_file, outpath): 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 + if os.path.exists(out_file) and ( + os.path.getmtime(in_file) <= os.path.getmtime(out_file) + and os.path.getctime(in_file) <= os.path.getctime(out_file) + ): + return extension = common.get_extension(in_file)[1] if extension == 'png': @@ -1115,6 +1124,9 @@ def copy_triple_t_store_metadata(apps): repofilename = os.path.basename(f) if segments[-2] == 'listing': locale = segments[-3] + if dirname in GRAPHIC_NAMES: + repofilename = dirname + '.' + extension + dirname = '' elif segments[-4] == 'listings': # v2.x locale = segments[-3] if dirname in tt_graphic_names: @@ -1142,6 +1154,7 @@ def insert_localized_app_metadata(apps): metadata// fastlane/metadata/android// + /fastlane/metadata/android// src//fastlane/metadata/android// ...as well as the /metadata// directory. @@ -1161,7 +1174,7 @@ def insert_localized_app_metadata(apps): https://f-droid.org/en/docs/All_About_Descriptions_Graphics_and_Screenshots/#in-the-apps-build-metadata-in-an-fdroiddata-collection """ sourcedirs = glob.glob(os.path.join('build', '[A-Za-z]*', 'src', '[A-Za-z]*', 'fastlane', 'metadata', 'android', '[a-z][a-z]*')) - sourcedirs += glob.glob(os.path.join('build', '[A-Za-z]*', 'fastlane', 'metadata', 'android', '[a-z][a-z]*')) + sourcedirs += glob.glob(os.path.join('build', '[A-Za-z]*', '**', 'fastlane', 'metadata', 'android', '[a-z][a-z]*'), recursive=True) sourcedirs += glob.glob(os.path.join('build', '[A-Za-z]*', 'metadata', '[a-z][a-z]*')) sourcedirs += glob.glob(os.path.join('metadata', '[A-Za-z]*', '[a-z][a-z]*')) @@ -1177,17 +1190,40 @@ def insert_localized_app_metadata(apps): locale = segments[-1] destdir = os.path.join('repo', packageName, locale) - # flavours specified in build receipt - build_flavours = "" - if ( - apps[packageName] - and len(apps[packageName].get('Builds', [])) > 0 - and 'gradle' in apps[packageName]['Builds'][-1] - ): - build_flavours = apps[packageName]['Builds'][-1]['gradle'] + builds = apps.get(packageName, {}).get('Builds', []) + found_in_subdir = ( + builds + and len(segments) > 6 + and segments[-4] == "fastlane" + and segments[-3] == "metadata" + and segments[-2] == "android" + and '/'.join(segments[2:-4]) == builds[-1].get('subdir') + ) - if len(segments) >= 5 and segments[4] == "fastlane" and segments[3] not in build_flavours: - logging.debug("ignoring due to wrong flavour") + # flavors specified in build receipt + build_flavors = [] + if builds and 'gradle' in builds[-1] and builds[-1]['gradle'] != ['yes']: + build_flavors = common.calculate_gradle_flavor_combination( + builds[-1]['gradle'] + ) + found_in_flavor = ( + len(segments) > 7 + and segments[2] == 'src' + and segments[4] == "fastlane" + and segments[3] in build_flavors + ) + + if ( + not found_in_subdir + and not found_in_flavor + and segments[0] == 'build' + and segments[2] not in ('metadata', 'fastlane') + ): + logging.debug( + 'Not scanning "{dir}" with unknown subdir or gradle flavor "{value}"'.format( + dir=os.path.relpath(root), value=segments[3] + ) + ) continue for f in files: @@ -1225,9 +1261,7 @@ def insert_localized_app_metadata(apps): try: versionCode = int(base) locale = segments[-2] - if versionCode in [ - a["versionCode"] for a in apps[packageName]["Builds"] - ]: + if versionCode in [b["versionCode"] for b in builds]: _set_localized_text_entry( apps[packageName], locale, @@ -1452,19 +1486,18 @@ def insert_localized_ios_app_metadata(apps_with_packages): fdroidserver.update.copy_ios_screenshots_to_repo(screenshots, package_name) # lookup icons, copy them and put them into app - icon_path = _get_ipa_icon(Path('build') / package_name) + icon_src = _get_ipa_icon(Path('build') / package_name) icon_dest = Path('repo') / package_name / 'icon.png' # for now just assume png - icon_stat = os.stat(icon_path) app['iconv2'] = { DEFAULT_LOCALE: { 'name': str(icon_dest).lstrip('repo'), 'sha256': common.sha256sum(icon_dest), - 'size': icon_stat.st_size, + 'size': os.path.getsize(icon_src), } } - if not icon_dest.exists(): + if not icon_dest.exists() or not filecmp.cmp(icon_src, icon_dest): icon_dest.parent.mkdir(parents=True, exist_ok=True) - shutil.copy(icon_path, icon_dest) + shutil.copy2(icon_src, icon_dest) def scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False): @@ -1543,8 +1576,10 @@ def scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False): repo_file['packageName'] = m.group(1) repo_file['versionCode'] = int(m.group(2)) srcfilename = name + b'_src.tar.gz' - if os.path.exists(os.path.join(repodir, srcfilename)): + srcpath = os.path.join(repodir, srcfilename) + if os.path.exists(srcpath): repo_file['srcname'] = srcfilename.decode() + repo_file['srcnameSha256'] = common.sha256sum(srcpath.decode()) repo_file['size'] = stat.st_size apkcache[name_utf8] = repo_file @@ -1766,6 +1801,7 @@ def scan_apk_androguard(apk, apkfile): xml = apkobject.get_android_manifest_xml() androidmanifest_xml = apkobject.xml['AndroidManifest.xml'] + if len(xml.nsmap) > 0: # one of them surely will be the Android one, or its corrupt xmlns = common.XMLNS_ANDROID @@ -1775,8 +1811,12 @@ def scan_apk_androguard(apk, apkfile): xmlns = '{}' vcstr = androidmanifest_xml.get(xmlns + 'versionCode') + logging.debug("Version Code: %r (%s)" % (vcstr, apkfile)) - if vcstr.startswith('0x'): + if not vcstr: + raise NoVersionCodeException(_("APK file {path} does not have a version code " + "in its manifest").format(path=apkfile)) + elif vcstr.startswith('0x'): apk['versionCode'] = int(vcstr, 16) else: apk['versionCode'] = int(vcstr) @@ -1924,6 +1964,10 @@ def process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk=Fal logging.warning(_("Skipping '{apkfilename}' with invalid signature!") .format(apkfilename=apkfilename)) return True, None, False + except NoVersionCodeException: + logging.warning(_("Skipping '{apkfilename}' without versionCode!") + .format(apkfilename=apkfilename)) + return True, None, False if apps: if apk['packageName'] in apps: @@ -1962,8 +2006,10 @@ def process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk=Fal apk['apkName'] = apkfilename srcfilename = apkfilename[:-4] + "_src.tar.gz" - if os.path.exists(os.path.join(repodir, srcfilename)): + srcpath = os.path.join(repodir, srcfilename) + if os.path.exists(srcpath): apk['srcname'] = srcfilename + apk['srcnameSha256'] = common.sha256sum(srcpath) # verify the jar signature is correct, allow deprecated # algorithms only if the APK is in the archive. @@ -2801,7 +2847,7 @@ def main(): output_status_stage(status_output, 'make_binary_transparency_log') btlog.make_binary_transparency_log(repodirs) - status_update_json(apps, apks + archapks) + status_update_json(status_output, apps, apks + archapks) logging.info(_("Finished")) diff --git a/fdroidserver/verify.py b/fdroidserver/verify.py index 63540147..897463ae 100644 --- a/fdroidserver/verify.py +++ b/fdroidserver/verify.py @@ -16,18 +16,17 @@ # 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 glob import json import logging -import requests +import os +import sys from argparse import ArgumentParser from collections import OrderedDict -from . import _ -from . import common -from . import net +import requests + +from . import _, common, net from .exception import FDroidException config = None @@ -58,8 +57,8 @@ def _add_diffoscope_info(d): ] d['diffoscope']['External-Tools-Required'] = external_tools - from diffoscope.tools import OS_NAMES, get_current_os from diffoscope.external_tools import EXTERNAL_TOOLS + from diffoscope.tools import OS_NAMES, get_current_os current_os = get_current_os() os_list = [current_os] if (current_os in OS_NAMES) else iter(OS_NAMES) @@ -144,23 +143,44 @@ def write_json_report(url, remote_apk, unsigned_apk, compare_result): with open(jsonfile, 'w') as fp: json.dump(data, fp, sort_keys=True) - if output['verified']: - jsonfile = 'unsigned/verified.json' - data = get_verified_json(jsonfile) - packageName = output['local']['packageName'] + appid, version_code = os.path.basename(unsigned_apk[:-4]).rsplit('_', 1) + appid_base = unsigned_apk.rsplit('_', 1)[0] + apkReports = sorted( + glob.glob(f'{appid_base}_[0-9]*.json'), # don't include .json + key=lambda s: int(s[:-9].rsplit('_', 1)[1]), # numeric sort by versionCode + ) + with open(apkReports[-1]) as fp: + reports = json.load(fp) + appid_output = {'apkReports': apkReports} + most_recent = 0 + for report_time, run in reports.items(): + if float(report_time) > most_recent: + most_recent = float(report_time) + appid_output['lastRunVerified'] = run['verified'] + with open(f'{appid_base}.json', 'w') as fp: + json.dump(appid_output, fp, cls=common.Encoder, sort_keys=True) - if packageName not in data['packages']: - data['packages'][packageName] = [] - found = False - output_dump = json.dumps(output, sort_keys=True) - for p in data['packages'][packageName]: - if output_dump == json.dumps(p, sort_keys=True): - found = True - break - if not found: - data['packages'][packageName].insert(0, json.loads(output_dump)) - with open(jsonfile, 'w') as fp: - json.dump(data, fp, cls=common.Encoder, sort_keys=True) + if output['verified']: + write_verified_json(output) + + +def write_verified_json(output): + jsonfile = 'unsigned/verified.json' + data = get_verified_json(jsonfile) + packageName = output['local']['packageName'] + + if packageName not in data['packages']: + data['packages'][packageName] = [] + found = False + output_dump = json.dumps(output, sort_keys=True) + for p in data['packages'][packageName]: + if output_dump == json.dumps(p, sort_keys=True): + found = True + break + if not found: + data['packages'][packageName].insert(0, json.loads(output_dump)) + with open(jsonfile, 'w') as fp: + json.dump(data, fp, cls=common.Encoder, sort_keys=True) def main(): diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index 0251e179..2ba92ad6 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -16,16 +16,16 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from os.path import isdir, isfile, basename, abspath, expanduser -import os import json +import logging +import os import shutil import subprocess import textwrap -import logging -from .common import FDroidException - import threading +from os.path import abspath, basename, expanduser, isdir, isfile + +from .common import FDroidException lock = threading.Lock() diff --git a/gradlew-fdroid b/gradlew-fdroid deleted file mode 100755 index 1fdc68c2..00000000 --- a/gradlew-fdroid +++ /dev/null @@ -1,308 +0,0 @@ -#!/bin/bash - -bindir="$(dirname $0)" -basedir="$(dirname $bindir)" -# Check if GRADLE_VERSION_DIR/CACHEDIR is set from environment -if [ -z "$GRADLE_VERSION_DIR" ]; then - gradle_version_dir="${basedir}/versions" -else - gradle_version_dir="$GRADLE_VERSION_DIR" -fi -BUILDSERVER_CACHEDIR=/vagrant/cache -if [ -n "$CACHEDIR" ]; then - cachedir="$CACHEDIR" -elif [ -d $BUILDSERVER_CACHEDIR ]; then - cachedir=$BUILDSERVER_CACHEDIR -fi -args=("$@") - -run_gradle() { - if [ ! -d "${gradle_version_dir}/${v_found}" ]; then - download_gradle ${v_found} - fi - # shellcheck disable=SC2145 - echo "Running ${gradle_version_dir}/${v_found}/bin/gradle ${args[@]}" - "${gradle_version_dir}/${v_found}/bin/gradle" "${args[@]}" - exit $? -} - -download_gradle() { - URL="https://downloads.gradle.org/distributions/gradle-${1}-bin.zip" - shasum=$(get_sha $1) - if [ $? != 0 ]; then - echo "No hash for gradle version $1! Exiting..." - exit 1 - fi - if [ -n "${cachedir}" ] && [ -e "${cachedir}/gradle-$1-bin.zip" ]; then - echo "Using cached ${cachedir}/gradle-$1-bin.zip ..." - gradle_zip="${cachedir}/gradle-$1-bin.zip" - else - echo "Downloading missing gradle version $1" - echo cachedir $cachedir - if [[ -n "${cachedir}" && ! -d "${cachedir}" ]]; then - mkdir -p "${cachedir}" - fi - if [[ -n "${cachedir}" && -d "${cachedir}" && -w "${cachedir}" ]]; then - tmpdir="${cachedir}" - else - tmpdir=$(mktemp -d) - fi - curl -o "${tmpdir}/gradle-$1-bin.zip" --silent --fail --show-error --location --retry 3 --retry-all-errors "${URL}" - gradle_zip="${tmpdir}/gradle-$1-bin.zip" - fi - echo "${shasum} ${gradle_zip}" | sha256sum -c - - if [ $? != 0 ]; then - echo "gradle download checksum mismatch! Exiting..." - exit 1 - fi - mkdir -p "${gradle_version_dir}/" - unzip -q -d "${gradle_version_dir}" "${gradle_zip}" - mv "${gradle_version_dir}/gradle-$1" "${gradle_version_dir}/${v_found}" -} - -get_sha() { - case $1 in - '0.7') echo '4e354fcb0d5c0b0e7789cd6ee900456edaf993f6dd890c4a1c217d90d2a6a6ad' ;; - '0.8') echo '940e623ea98e40ea9ad398770a6ebb91a61c0869d394dda81aa86b0f4f0025e7' ;; - '0.9') echo '994e46d4b467254a0f25ce92b602618331b9b3ac8b32a094fd84ff0e0ceec135' ;; - '0.9.1') echo '5d48cba95db031ec109ae9ab60561e960b6507046036e8191aa78572ec27e2a5' ;; - '0.9.2') echo 'f94d7642348c558fc05ab5fd6fb947fb1ed8fed5931ddb73dd04fb0de22d669b' ;; - '1.0') echo '894bca0360a7e2040815096788f118a2dd106ff6694221b274efb9c32bce0384' ;; - '1.1') echo '552c1fc9f3a1b9668b79cc447370f0263e664ffb6d5c6e1c21e77ce0c8a20d4c' ;; - '1.2') echo 'eb53da3704d24cabb7565f34a3bf16bcd863c4b0c139917606fb15d4f27c7bdf' ;; - '1.3') echo 'ada68561efbb9f1cae0f9063974cbde15c180351a2f92bc2f1106e39ddcae5ba' ;; - '1.4') echo 'cd99e85fbcd0ae8b99e81c9992a2f10cceb7b5f009c3720ef3a0078f4f92e94e' ;; - '1.5') echo 'a5511a0659caa47d9d74fd2844c9da43157d2f78e63a0223c6289d88f5aaecbe' ;; - '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.0') echo 'a1eb880c8755333c4d33c4351b269bebe517002532d3142c0b6164c9e8c081c3' ;; - '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' ;; - '5.6.3') echo '60a6d8f687e3e7a4bc901cc6bc3db190efae0f02f0cc697e323e0f9336f224a3' ;; - '5.6.4') echo '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d' ;; - '6.0') echo '5a3578b9f0bb162f5e08cf119f447dfb8fa950cedebb4d2a977e912a11a74b91' ;; - '6.0.1') echo 'd364b7098b9f2e58579a3603dc0a12a1991353ac58ed339316e6762b21efba44' ;; - '6.1') echo 'd0c43d14e1c70a48b82442f435d06186351a2d290d72afd5b8866f15e6d7038a' ;; - '6.1.1') echo '9d94e6e4a28ad328072ef6e56bce79a810494ae756751fdcedffdeaf27c093b1' ;; - '6.2') echo 'b93a5f30d01195ec201e240f029c8b42d59c24086b8d1864112c83558e23cf8a' ;; - '6.2.1') echo 'a68ca7ba57f3404c3f6fc1f70a02d3a7d78652e6b46bbfaff83fc9a17168c279' ;; - '6.2.2') echo '0f6ba231b986276d8221d7a870b4d98e0df76e6daf1f42e7c0baec5032fb7d17' ;; - '6.3') echo '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768' ;; - '6.4') echo 'b888659f637887e759749f6226ddfcb1cb04f828c58c41279de73c463fdbacc9' ;; - '6.4.1') echo 'e58cdff0cee6d9b422dcd08ebeb3177bc44eaa09bd9a2e838ff74c408fe1cbcd' ;; - '6.5') echo '23e7d37e9bb4f8dabb8a3ea7fdee9dd0428b9b1a71d298aefd65b11dccea220f' ;; - '6.5.1') echo '50a7d30529fa939721fe9268a0205142f3f2302bcac5fb45b27a3902e58db54a' ;; - '6.6') echo 'e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025' ;; - '6.6.1') echo '7873ed5287f47ca03549ab8dcb6dc877ac7f0e3d7b1eb12685161d10080910ac' ;; - '6.7') echo '8ad57759019a9233dc7dc4d1a530cefe109dc122000d57f7e623f8cf4ba9dfc4' ;; - '6.7.1') echo '3239b5ed86c3838a37d983ac100573f64c1f3fd8e1eb6c89fa5f9529b5ec091d' ;; - '6.8') echo 'e2774e6fb77c43657decde25542dea710aafd78c4022d19b196e7e78d79d8c6c' ;; - '6.8.1') echo 'fd591a34af7385730970399f473afabdb8b28d57fd97d6625c388d090039d6fd' ;; - '6.8.2') echo '8de6efc274ab52332a9c820366dd5cf5fc9d35ec7078fd70c8ec6913431ee610' ;; - '6.8.3') echo '7faa7198769f872826c8ef4f1450f839ec27f0b4d5d1e51bade63667cbccd205' ;; - '6.9') echo '765442b8069c6bee2ea70713861c027587591c6b1df2c857a23361512560894e' ;; - '6.9.1') echo '8c12154228a502b784f451179846e518733cf856efc7d45b2e6691012977b2fe' ;; - '6.9.2') echo '8b356fd8702d5ffa2e066ed0be45a023a779bba4dd1a68fd11bc2a6bdc981e8f' ;; - '6.9.3') echo 'dcf350b8ae1aa192fc299aed6efc77b43825d4fedb224c94118ae7faf5fb035d' ;; - '6.9.4') echo '3e240228538de9f18772a574e99a0ba959e83d6ef351014381acd9631781389a' ;; - '7.0') echo 'eb8b89184261025b0430f5b2233701ff1377f96da1ef5e278af6ae8bac5cc305' ;; - '7.0.1') echo 'dccda8aa069563c8ba2f6cdfd0777df0e34a5b4d15138ca8b9757e94f4e8a8cb' ;; - '7.0.2') echo '0e46229820205440b48a5501122002842b82886e76af35f0f3a069243dca4b3c' ;; - '7.1') echo '2debee19271e1b82c6e41137d78e44e6e841035230a1a169ca47fd3fb09ed87b' ;; - '7.1.1') echo 'bf8b869948901d422e9bb7d1fa61da6a6e19411baa7ad6ee929073df85d6365d' ;; - '7.2') echo 'f581709a9c35e9cb92e16f585d2c4bc99b2b1a5f85d2badbd3dc6bff59e1e6dd' ;; - '7.3') echo 'de8f52ad49bdc759164f72439a3bf56ddb1589c4cde802d3cec7d6ad0e0ee410' ;; - '7.3.1') echo '9afb3ca688fc12c761a0e9e4321e4d24e977a4a8916c8a768b1fe05ddb4d6b66' ;; - '7.3.2') echo '23b89f8eac363f5f4b8336e0530c7295c55b728a9caa5268fdd4a532610d5392' ;; - '7.3.3') echo 'b586e04868a22fd817c8971330fec37e298f3242eb85c374181b12d637f80302' ;; - '7.4') echo '8cc27038d5dbd815759851ba53e70cf62e481b87494cc97cfd97982ada5ba634' ;; - '7.4.1') echo 'e5444a57cda4a95f90b0c9446a9e1b47d3d7f69057765bfb54bd4f482542d548' ;; - '7.4.2') echo '29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda' ;; - '7.5') echo 'cb87f222c5585bd46838ad4db78463a5c5f3d336e5e2b98dc7c0c586527351c2' ;; - '7.5.1') echo 'f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4' ;; - '7.6') echo '7ba68c54029790ab444b39d7e293d3236b2632631fb5f2e012bb28b4ff669e4b' ;; - '7.6.1') echo '6147605a23b4eff6c334927a86ff3508cb5d6722cd624c97ded4c2e8640f1f87' ;; - '7.6.2') echo 'a01b6587e15fe7ed120a0ee299c25982a1eee045abd6a9dd5e216b2f628ef9ac' ;; - '7.6.3') echo '740c2e472ee4326c33bf75a5c9f5cd1e69ecf3f9b580f6e236c86d1f3d98cfac' ;; - '7.6.4') echo 'bed1da33cca0f557ab13691c77f38bb67388119e4794d113e051039b80af9bb1' ;; - '8.0') echo '4159b938ec734a8388ce03f52aa8f3c7ed0d31f5438622545de4f83a89b79788' ;; - '8.0.1') echo '1b6b558be93f29438d3df94b7dfee02e794b94d9aca4611a92cdb79b6b88e909' ;; - '8.0.2') echo 'ff7bf6a86f09b9b2c40bb8f48b25fc19cf2b2664fd1d220cd7ab833ec758d0d7' ;; - '8.1') echo 'a62c5f99585dd9e1f95dab7b9415a0e698fa9dd1e6c38537faa81ac078f4d23e' ;; - '8.1.1') echo 'e111cb9948407e26351227dabce49822fb88c37ee72f1d1582a69c68af2e702f' ;; - '8.2') echo '38f66cd6eef217b4c35855bb11ea4e9fbc53594ccccb5fb82dfd317ef8c2c5a3' ;; - '8.2.1') echo '03ec176d388f2aa99defcadc3ac6adf8dd2bce5145a129659537c0874dea5ad1' ;; - '8.3') echo '591855b517fc635b9e04de1d05d5e76ada3f89f5fc76f87978d1b245b4f69225' ;; - '8.4') echo '3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae' ;; - '8.5') echo '9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026' ;; - '8.6') echo '9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c' ;; - '8.7') echo '544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d' ;; - '8.8') echo 'a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612' ;; - '8.9') echo 'd725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab' ;; - '8.10') echo '5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a' ;; - '8.10.1') echo '1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1' ;; - '8.10.2') echo '31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26' ;; - '8.11') echo '57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9' ;; - '8.11.1') echo 'f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6' ;; - '8.12') echo '7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03' ;; - '8.12.1') echo '8d97a97984f6cbd2b85fe4c60a743440a347544bf18818048e611f5288d46c94' ;; - '8.13') echo '20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78' ;; - *) exit 1 - esac -} - -contains() { - local e - for e in $2; do - [[ $e == $1 ]] && return 0; - done - return 1 -} - -# key-value pairs of what gradle version (value) each gradle plugin version -# (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#updating-gradle -d_gradle_plugin_ver_k=(8.4 8.3 8.2 8.1 8.0 7.4 7.3 7.2 7.1 7.0 4.2 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) -d_plugin_min_gradle_v=(8.6 8.4 8.2 8.0 8.0 7.5 7.4 7.3.3 7.2 7.0.2 6.7.1 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=(8.13 8.12.1 8.12 8.11.1 8.11 8.10.2 8.10.1 8.10 8.9 8.8 8.7 8.6 8.5 8.4 8.3 8.2.1 8.2 8.1.1 8.1 8.0.2 8.0.1 8.0 7.6.4 7.6.3 7.6.2 7.6.1 7.6 7.5.1 7.5 7.4.2 7.4.1 7.4 7.3.3 7.3.2 7.3.1 7.3 7.2 7.1.1 7.1 7.0.2 7.0.1 7.0 6.9.4 6.9.3 6.9.2 6.9.1 6.9 6.8.3 6.8.2 6.8.1 6.8 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 2.0 1.12 1.11 1.10 1.9 1.8 1.7 1.6 1.5 1.4 1.3 1.2 1.1 1.0 0.9.2 0.9.1 0.9 0.8 0.7) - -v_all=${plugin_v[@]} - -# Earliest file takes priority -# Last key takes priority if there are duplicates (matching java.util.Properties) -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} - fi - done < $f - [[ -n $wrapper_ver ]] && break -done - -if [[ -n $wrapper_ver ]]; then - v_found=$wrapper_ver - echo "Found $v_found via distributionUrl" - run_gradle -fi - -# Earliest takes priority -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%[\'\"]*} - elif [[ -z "$wrapper_ver" && $line == *'gradleVersion = '* ]]; then - wrapper_ver=${line#*gradleVersion*=*[\'\"]} - wrapper_ver=${wrapper_ver%[\'\"]*} - fi - done < $f -done - -if [[ -n $wrapper_ver ]]; then - v_found=$wrapper_ver - echo "Found $v_found via gradleVersion" - run_gradle -fi - -if [[ -n $plugin_pver ]]; then - i=0 - match=false - for k in "${d_gradle_plugin_ver_k[@]}"; do - if [[ $plugin_pver == ${k}* ]]; then - plugin_ver=${d_plugin_min_gradle_v[$i]} - match=true - break - fi - let i++ - done - if $match; then - v_found=$plugin_ver - echo "Found $v_found via gradle plugin version $k" - fi -fi - -# Find the highest version available -for v in ${plugin_v[*]}; do - if contains $v "${v_all[*]}"; then - v_def=$v - break - fi -done - -if [[ -z $v_found ]]; then - echo "No suitable gradle version found - defaulting to $v_def" - v_found=$v_def -fi - -run_gradle diff --git a/hooks/install-hooks.sh b/hooks/install-hooks.sh index 69b314d4..e266301b 100755 --- a/hooks/install-hooks.sh +++ b/hooks/install-hooks.sh @@ -2,7 +2,7 @@ # # Install all the client hooks -BASE_DIR="$(cd $(dirname $0); pwd -P)" +BASE_DIR="$(cd $(dirname $0) || exit; pwd -P)" HOOK_NAMES="applypatch-msg pre-applypatch post-applypatch pre-commit prepare-commit-msg commit-msg post-commit pre-rebase post-checkout post-merge pre-receive update post-receive post-update pre-auto-gc" HOOK_DIR="$(git rev-parse --show-toplevel)/.git/hooks" diff --git a/hooks/pre-commit b/hooks/pre-commit index c0859570..a147e689 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -11,7 +11,7 @@ if [ -z "$files" ]; then PY_FILES="fdroid makebuildserver setup.py fdroidserver/*.py examples/*.py tests/*-release-checksums.py" PY_TEST_FILES="tests/test_*.py" SH_FILES="hooks/pre-commit" - BASH_FILES="gradlew-fdroid jenkins-build-all jenkins-setup-build-environment jenkins-test completion/bash-completion buildserver/provision-*" + BASH_FILES="jenkins-build-all jenkins-setup-build-environment jenkins-test completion/bash-completion buildserver/provision-*" RB_FILES="buildserver/Vagrantfile" YML_FILES=".*.yml .yamllint */*.yml */*.yaml" else @@ -36,7 +36,7 @@ else *.rb) RB_FILES+=" $f" ;; - *.yml|.*.yml|.yamllint) + *.yml|*.yaml|.yamllint) YML_FILES+=" $f" ;; *) @@ -66,7 +66,7 @@ cmd_exists() { } find_command() { - for name in $@; do + for name in "$@"; do for suff in "3" "-3" "-python3" ""; do cmd=${name}${suff} if cmd_exists $cmd; then diff --git a/locale/az/LC_MESSAGES/fdroidserver.po b/locale/az/LC_MESSAGES/fdroidserver.po index 6bc37559..48050f95 100644 --- a/locale/az/LC_MESSAGES/fdroidserver.po +++ b/locale/az/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.2.1-143-g1a5ee449\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2023-05-26 19:39+0000\n" "Last-Translator: Mehrab Poladov \n" "Language-Team: Azerbaijani \n" @@ -353,6 +353,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1478,6 +1483,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1991,6 +2001,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/ba/LC_MESSAGES/fdroidserver.po b/locale/ba/LC_MESSAGES/fdroidserver.po new file mode 100644 index 00000000..9804a4f7 --- /dev/null +++ b/locale/ba/LC_MESSAGES/fdroidserver.po @@ -0,0 +1,2695 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# Zulfar , 2025. +msgid "" +msgstr "" +"Project-Id-Version: fdroidserver 2.4.0\n" +"Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-06-22 06:50+0000\n" +"Last-Translator: Zulfar \n" +"Language-Team: Bashkir \n" +"Language: ba\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 5.13-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 +msgid "" +"\n" +"{path} encoded for the DEBUG_KEYSTORE secret variable:" +msgstr "" +"\n" +"{path} DEBUG_KEYSTORE йәшерен үҙгәреүсәне өсөн кодланған:" + +#: ../fdroidserver/lint.py +#, python-format +msgid "\"%s/\" has no matching metadata file!" +msgstr "\"%s/\" өсөн ярашлы мета-мәғлүмәт файлы юҡ!" + +#: ../fdroidserver/index.py +msgid "\"isPrimary\" key should not be added to mirrors!" +msgstr "\"isPrimary\" асҡысы көҙгөләргә өҫтәлергә тейеш түгел!" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "\"local_copy_dir\" {path} does not exist!" +msgstr "\"local_copy_dir\" {path} каталогы юҡ!" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "\"{apkfilename}\" is already installed on {dev}." +msgstr "\"{apkfilename}\" {dev} ҡоролмаһында инде ҡуйылған." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" contains recent {name} ({version})" +msgstr "\"{path}\" эсендә {name} ({version}) ҡушымтаһының яңы версияһы бар." + +#: ../fdroidserver/deploy.py +#, python-brace-format +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 "\"{path}\" — яраҡлы файл форматы түгел (ҡулланығыҙ: metadata/*.yml)" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "\"{path}\" is signed by a key that is not allowed:" +msgstr "\"{path}\" рөхсәт ителмәгән асҡыс менән тамғаланған:" + +#: ../fdroidserver/import_subcommand.py +#, python-brace-format +msgid "\"{url}\" is not a valid URL!" +msgstr "\"{url}\" — дөрөҫ URL түгел!" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "%(prog)s: error: %(message)s\n" +msgstr "%(prog)s: хата: %(message)s\n" + +#: ../fdroidserver/publish.py +#, python-format +msgid "%d APKs failed to be signed or verified!" +msgstr "%d APK тамғаланманы йәки тикшерелмәне!" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "%d problems found" +msgstr "%d проблема табылды" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "%r is not callable" +msgstr "%r саҡырылмалы түгел" + +#: ../fdroidserver/signindex.py +#, python-format +msgid "%s did not produce a dict!" +msgstr "%s һүҙлек (dict) ҡайтарманы!" + +#: ../fdroidserver/signindex.py +#, python-format +msgid "%s has bad SHA-256: %s" +msgstr "%s файлының SHA-256 суммаһы дөрөҫ түгел: %s" + +#: ../fdroidserver/lint.py +#, python-format +msgid "%s is not an accepted build field" +msgstr "%s — рөхсәт ителгән йыйыу яланы түгел" + +#: ../fdroidserver/common.py +msgid "'keypass' not found in config.yml!" +msgstr "config.yml файлында 'keypass' табылманы!" + +#: ../fdroidserver/common.py +msgid "'keystore' is NONE and 'smartcardoptions' is blank!" +msgstr "'keystore' күрһәтелмәгән һәм 'smartcardoptions' буш!" + +#: ../fdroidserver/common.py +msgid "'keystore' not found in config.yml!" +msgstr "config.yml файлында 'keystore' табылманы!" + +#: ../fdroidserver/common.py +msgid "'keystorepass' not found in config.yml!" +msgstr "config.yml файлында 'keystorepass' табылманы!" + +#: ../fdroidserver/common.py +msgid "'repo_keyalias' not found in config.yml!" +msgstr "config.yml файлында 'repo_keyalias' табылманы!" + +#: /usr/lib/python3.11/argparse.py +msgid "'required' is an invalid argument for positionals" +msgstr "Позицион аргументтар өсөн 'required' — дөрөҫ булмаған аргумент" + +#: ../fdroidserver/common.py +msgid "'sdk_path' not set in config.yml!" +msgstr "config.yml файлында 'sdk_path' күрһәтелмәгән!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{aapt}' is too old, fdroid requires build-tools-{version} or newer!" +msgstr "'{aapt}' бигерәк иҫке, F-Droid өсөн build-tools-{version} йәки яңыраҡ версияһы кәрәк!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "'{path}' failed to execute!" +msgstr "'{path}' башҡарылманы!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{path}' has invalid format, it should be a dictionary!" +msgstr "'{path}' форматы дөрөҫ түгел, ул һүҙлек булырға тейеш!" + +#: ../fdroidserver/lint.py ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}" +msgstr "'{appid}' өсөн '{value}' — дөрөҫ булмаған {field} ҡиммәте. Regex ҡалыбы: {pattern}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "'{value}' is not a valid {field}, should be {pattern}" +msgstr "'{value}' — яраҡлы {field} түгел, {pattern} булырға тейеш" + +#: ../fdroidserver/checkupdates.py +msgid "--merge-request only runs on a single appid!" +msgstr "--merge-request тик бер appid менән генә эшләй!" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "...checkupdate failed for {appid} : {error}" +msgstr "...{appid} өсөн checkupdate уңышһыҙ үтте: {error}" + +#: /usr/lib/python3.11/argparse.py +msgid ".__call__() not defined" +msgstr ".__call__() билдәләнмәгән" + +#: ../fdroidserver/lint.py +msgid "/issues is missing" +msgstr "/issues юҡ" + +#: ../fdroidserver/mirror.py +msgid "A URL is required as an argument!" +msgstr "Аргумент итеп URL күрһәтеү мотлаҡ!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "APK signatures have different certificates in {path}:" +msgstr "{path} эсендәге APK-имзаларҙың сертификаттары төрлө:" + +#: ../fdroidserver/__main__.py +msgid "Add PGP signatures using GnuPG for packages in repo" +msgstr "Репозиторийҙағы пакеттарға GnuPG ярҙамында PGP-имзалар өҫтәү" + +#: ../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 "Мета-мәғлүмәт файлдары булмаған APK-лар өсөн ҡалыптар өҫтәү" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Adding new repo for only {name}" +msgstr "Тик {name} өсөн генә яңы репозиторий өҫтәү" + +#: ../fdroidserver/init.py +msgid "Alias of the repo signing key in the keystore" +msgstr "Асҡыстар һаҡлағысындағы репо-имзалау асҡысының псевдонимы" + +#: ../fdroidserver/build.py +msgid "AllowedAPKSigningKeys missing but reference binary supplied" +msgstr "AllowedAPKSigningKeys юҡ, ләкин өлгө бинар файл бирелгән" + +#: ../fdroidserver/import_subcommand.py +msgid "Allows a different revision (or git branch) to be specified for the initial import" +msgstr "Башланғыс импорт өсөн икенсе ревизия (йәки git ботағын) күрһәтергә мөмкинлек бирә" + +#: ../fdroidserver/mirror.py +msgid "Also mirror the full archive section" +msgstr "Шулай уҡ архив бүлегенең тулы күсермәһен яһау" + +#: ../fdroidserver/lint.py +msgid "Also warn about formatting issues, like rewritemeta -l" +msgstr "Шулай уҡ rewritemeta -l кеүек форматлау проблемалары тураһында иҫкәртеү" + +#: ../fdroidserver/scanner.py +msgid "Android AAR library" +msgstr "Android AAR китапханаһы" + +#: ../fdroidserver/scanner.py +msgid "Android APK file" +msgstr "Android APK файлы" + +#: ../fdroidserver/scanner.py +msgid "Android DEX code" +msgstr "Android DEX коды" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Android SDK not found at {path}!" +msgstr "Android SDK {path} юлында табылманы!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' does not exist!" +msgstr "'{path}' Android SDK юлы юҡ!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK path '{path}' is not a directory!" +msgstr "'{path}' Android SDK юлы — каталог түгел!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Android SDK tool {cmd} not found!" +msgstr "{cmd} Android SDK ҡоралы табылманы!" + +#: ../fdroidserver/lint.py +msgid "App has Binaries but does not have corresponding AllowedAPKSigningKeys to pin certificate." +msgstr "Ҡушымтала Binaries бар, ләкин сертификатты беркетеү өсөн тейешле AllowedAPKSigningKeys юҡ." + +#: ../fdroidserver/lint.py +msgid "App has NoSourceSince or ArchivePolicy \"0 versions\" or 0 but AutoUpdateMode or UpdateCheckMode are not None" +msgstr "Ҡушымтала NoSourceSince йәки ArchivePolicy \"0 versions\" йәки 0 ҡуйылған, ләкин AutoUpdateMode йәки UpdateCheckMode None түгел" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "App is in '{repo}' but has a link to {url}" +msgstr "Ҡушымта '{repo}' эсендә, ләкин {url} адресына һылтанмаһы бар" + +#: ../fdroidserver/lint.py +msgid "App version has binary but does not have corresponding AllowedAPKSigningKeys to pin certificate." +msgstr "Ҡушымта версияһында бинар файл бар, ләкин сертификатты беркетеү өсөн тейешле AllowedAPKSigningKeys юҡ." + +#: ../fdroidserver/lint.py +msgid "Appending .git is not necessary" +msgstr ".git ҡушып яҙыу мотлаҡ түгел" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Archiving {apkfilename} with invalid signature!" +msgstr "{apkfilename} дөрөҫ булмаған имза менән архивлана!" + +#: ../fdroidserver/lint.py +msgid "AutoUpdateMode with UpdateCheckMode: HTTP must have a pattern." +msgstr "AutoUpdateMode-ла UpdateCheckMode: HTTP өсөн ҡалып булырға тейеш." + +#: ../fdroidserver/install.py +msgid "Automatic no to all prompts." +msgstr "Барлыҡ һорауҙарға автоматик рәүештә \"юҡ\" тигән яуап." + +#: ../fdroidserver/install.py +msgid "Automatic yes to all prompts." +msgstr "Барлыҡ һорауҙарға автоматик рәүештә \"эйе\" тигән яуап." + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Bad entry type \"{mirrortype}\" in mirrors config: {mirror}" +msgstr "Көҙгөләр көйләүҙәрендә дөрөҫ булмаған яҙма төрө \"{mirrortype}\": {mirror}" + +#: ../fdroidserver/mirror.py +msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" +msgstr "Көҙгө яһау өсөн төп URL, һорау юлы аша индекс имзалау асҡысын ҡушырға мөмкин: ?fingerprint=" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in build '{versionName}'" +msgstr "'{versionName}' йыйылмаһында '{branch}' ботағы коммит булараҡ ҡулланылған" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Branch '{branch}' used as commit in srclib '{srclib}'" +msgstr "'{srclib}' сығанаҡ китапханаһында '{branch}' ботағы коммит булараҡ ҡулланылған" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Broken symlink: {path}" +msgstr "Өҙөлгән символик һылтанма: {path}" + +#: ../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 "`fdroid import` менән яһалған йыйылма — әҙер булғас, һүндереү юлын алып ташлағыҙ" + +#: ../fdroidserver/checkupdates.py +msgid "Build metadata git repo has uncommited changes!" +msgstr "Йыйыу мета-мәғлүмәттәренең git репозиторийында һаҡланмаған үҙгәрештәр бар!" + +#: ../fdroidserver/build.py +msgid "Build only the latest version of each package" +msgstr "Һәр пакеттың һуңғы версияһын ғына йыйыу" + +#: ../fdroidserver/init.py +#, python-format +msgid "Built repo based in \"%s\" with this config:" +msgstr "\"%s\" каталогында ошо көйләүҙәр менән репозиторий төҙөлдө:" + +#: ../fdroidserver/checkupdates.py +msgid "Can't auto-update app with no CurrentVersionCode" +msgstr "CurrentVersionCode булмаған ҡушымтаны автоматик яңыртып булмай" + +#: ../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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "{path} уҡылманы: {error}" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Cannot rewrite \"{path}\"" +msgstr "\"{path}\" файлын үҙгәртеп яҙып булмай" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +#, python-format +msgid "Categories '%s' is not valid" +msgstr "'%s' категориялары дөрөҫ түгел" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/lint.py +msgid "Categories are not set" +msgstr "Категориялар күрһәтелмәгән" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Category \"{category}\" defined but not used for any apps!" +msgstr "\"{category}\" категорияһы билдәләнгән, ләкин бер ҡушымтала ла ҡулланылмай!" + +#: ../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 "{appid} өсөн архивлауҙы тикшереү - apk:{integer}, һаҡларға:{keep}, архивта:{arch}" + +#: ../fdroidserver/update.py +msgid "Clean update - don't uses caches, reprocess all APKs" +msgstr "Таҙа яңыртыу — кештарҙы ҡулланмаҫҡа, бөтә APK-ларҙы яңынан эшкәртергә" + +#: ../fdroidserver/common.py +msgid "Color the log output" +msgstr "Лог сығарылышын төҫлө итеү" + +#: ../fdroidserver/import_subcommand.py +msgid "Comma separated list of categories." +msgstr "Өтөр менән айырылған категориялар исемлеге." + +#: ../fdroidserver/__main__.py +#, python-format +msgid "Command '%s' not recognised.\n" +msgstr "'%s' командаһы танылманы.\n" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes" +msgstr "Үҙгәрештәрҙе һаҡлау (commit)" + +#: ../fdroidserver/checkupdates.py +msgid "Commit changes, push, then make a merge request" +msgstr "Үҙгәрештәрҙе һаҡларға (commit), ебәрергә (push), шунан берләштереүгә һорау яһарға" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Conflicting \"{field}\" definitions between .yml and localized files:" +msgstr ".yml һәм локалләштерелгән файлдар араһында \"{field}\" өсөн ҡапма-ҡаршылыҡлы билдәләмәләр:" + +#: ../fdroidserver/__main__.py +msgid "Conflicting arguments: '--verbose' and '--quiet' can not be specified at the same time." +msgstr "Ҡапма-ҡаршылыҡлы аргументтар: '--verbose' һәм '--quiet' бер үк ваҡытта күрһәтелә алмай." + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not find '{command}' on your system" +msgstr "Системала '{command}' табылманы" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/import_subcommand.py +msgid "Could not find latest version code" +msgstr "Һуңғы версияның кодын табып булманы" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vname +#: ../fdroidserver/import_subcommand.py +msgid "Could not find latest version name" +msgstr "Һуңғы версияның исемен табып булманы" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not find {path} to remove it" +msgstr "Юйыу өсөн {path} табылманы" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Could not open APK {path} for analysis: " +msgstr "Анализ өсөн {path} APK файлын асып булманы: " + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Could not parse size \"{size}\", wrong type \"{type}\"" +msgstr "\"{size}\" үлсәмен танып булманы, дөрөҫ булмаған тип \"{type}\"" + +#. Translators: https://developer.android.com/build/configure-app-module#set-application-id +#: ../fdroidserver/import_subcommand.py +msgid "Couldn't find Application ID" +msgstr "Ҡушымтаның идентификаторын (Application ID) табып булманы" + +#: ../fdroidserver/checkupdates.py +msgid "Couldn't find any version information" +msgstr "Бер ниндәй ҙә версия мәғлүмәте табылманы" + +#: ../fdroidserver/checkupdates.py +msgid "Couldn't find package ID" +msgstr "Пакет идентификаторын табып булманы" + +#: ../fdroidserver/update.py +msgid "Cowardily refusing to overwrite existing signing key setup!" +msgstr "Инде булған имзалау асҡысы көйләүҙәрен өҫтөнән яҙҙырыуҙан ҡурҡаҡтарса баш тартам!" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Created new container \"{name}\"" +msgstr "Яңы \"{name}\" контейнеры булдырылды" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Creating \"{path}\" for configuring s3cmd." +msgstr "s3cmd-ты көйләү өсөн \"{path}\" булдырыла." + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Creating empty {config_file}" +msgstr "Буш {config_file} булдырыла" + +#: ../fdroidserver/publish.py +msgid "Creating log directory" +msgstr "Логтар каталогы булдырыла" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Creating new S3 bucket: {url}" +msgstr "Яңы S3 биҙрәһе булдырыла: {url}" + +#: ../fdroidserver/publish.py +msgid "Creating output directory" +msgstr "Сығарыу каталогы булдырыла" + +#: ../fdroidserver/index.py +msgid "Creating signed index with this key (SHA256):" +msgstr "Ошо асҡыс менән тамғаланған индекс булдырыла (SHA256):" + +#: ../fdroidserver/publish.py ../fdroidserver/verify.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 "Ағымдағы CurrentVersionCode {cv} иң иҫке йыйылма яҙмаһынан {versionCode} бәләкәйерәк" + +#: ../fdroidserver/nightly.py +msgid "DEBUG_KEYSTORE is not set or the value is incomplete" +msgstr "DEBUG_KEYSTORE күрһәтелмәгән йәки уның ҡиммәте тулы түгел" + +#: ../fdroidserver/update.py +msgid "Delete APKs and/or OBBs without metadata from the repo" +msgstr "Репозиторийҙан мета-мәғлүмәттәрһеҙ APK-ларҙы һәм/йәки OBB-ларҙы юйыу" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Deleting archive, repo is too big ({size} max {limit})" +msgstr "Архив юйыла, репозиторий бигерәк ҙур ({size} макс. {limit})" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" +msgstr "git-көҙгөнөң тарихы юйыла, репозиторий бигерәк ҙур ({size} макс. {limit})" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Deleting unknown file: {path}" +msgstr "Билдәһеҙ файл юйыла: {path}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Description '%s' is just the app's summary" +msgstr "'%s' тасуирламаһы — ул ҡушымтаның ҡыҫҡаса аңлатмаһы ғына" + +#: ../fdroidserver/lint.py +msgid "Description has a duplicate line" +msgstr "Тасуирламала ҡабатланған юл бар" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Description of length {length} is over the {limit} char limit" +msgstr "{length} оҙонлоғондағы тасуирлама {limit} символ сикләүенән артып китә" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Did you mean config/{name}.yml?" +msgstr "Һеҙ config/{name}.yml-ды күҙ уңында тоттоғоҙмо?" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Did you mean {code}?" +msgstr "Һеҙ {code}-ты күҙ уңында тоттоғоҙмо?" + +#: ../fdroidserver/import_subcommand.py +msgid "Do not add 'disable:' to the generated build entries" +msgstr "Булдырылған йыйылма яҙмаларына 'disable:' өҫтәмәгеҙ" + +#: ../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 "URL-ға \"{path}\"-ты индермәгеҙ!" + +#: ../fdroidserver/init.py +msgid "Do not prompt for Android SDK path, just fail" +msgstr "Android SDK юлын һорамаҫҡа, шунда уҡ уңышһыҙлыҡ менән тамамларға" + +#: ../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 "Сығанаҡ кодтарҙың tarball-ын яһамаҫҡа, йыйылманы һынағанда файҙалы" + +#: ../fdroidserver/build.py +msgid "Don't refresh the repository, useful when testing a build with no internet connection" +msgstr "Репозиторийҙы яңыртмаҫҡа, интернетһыҙ йыйылманы һынағанда файҙалы" + +#: ../fdroidserver/deploy.py ../fdroidserver/nightly.py +msgid "Don't use rsync checksums" +msgstr "rsync контроль суммаларын ҡулланмаҫҡа" + +#: ../fdroidserver/install.py +msgid "Download F-Droid.apk using mirrors that leak less to the network" +msgstr "F-Droid.apk-ны селтәргә аҙыраҡ мәғлүмәт ебәргән көҙгөләр аша йөкмәтергә" + +#: ../fdroidserver/__main__.py +msgid "Download complete mirrors of small repos" +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 "{url} йөкмәтелмәне. {error}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Duplicate Anti-Feature declaration at {path} was ignored!" +msgstr "{path} юлындағы ҡабатланған Anti-Feature декларацияһы иғтибарһыҙ ҡалдырылды!" + +#: ../fdroidserver/index.py +#, python-format +msgid "Duplicate entry \"%s\" in mirrors config!" +msgstr "Көҙгөләр көйләүҙәрендә ҡабатланған \"%s\" яҙмаһы!" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Duplicate link in '{field}': {url}" +msgstr "'{field}' яланында ҡабатланған һылтанма: {url}" + +#: ../fdroidserver/common.py +#, python-format +msgid "ERROR: %(message)s" +msgstr "ХАТА: %(message)s" + +#: ../fdroidserver/__main__.py +msgid "ERROR: The \"server\" subcommand has been removed, use \"deploy\"!" +msgstr "ХАТА: \"server\" аҫкомандаһы алынды, \"deploy\" командаһын ҡулланығыҙ!" + +#: ../fdroidserver/nightly.py +msgid "ERROR: unsupported CI type, patches welcome!" +msgstr "ХАТА: яраҡһыҙ CI төрө, төҙәтмәләр хуплана!" + +#: ../fdroidserver/nightly.py +#, python-format +msgid "ERROR: unsupported git host \"%s\", patches welcome!" +msgstr "ХАТА: яраҡһыҙ git хосты \"%s\", төҙәтмәләр хуплана!" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "ERROR: {key} in {path} is not \"archive\" or \"repo\"!" +msgstr "ХАТА: {path} эсендәге {key} асҡысы \"archive\" йәки \"repo\" түгел!" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "ERROR: {key} not a valid key!" +msgstr "ХАТА: {key} — дөрөҫ асҡыс түгел!" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "ERROR: {key}'s value should be of type {t}!" +msgstr "ХАТА: {key} асҡысының ҡиммәте {t} тибында булырға тейеш!" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "ERROR: {key}:{subkey} in {path} is not in allowed keys: {allowed_keys}!" +msgstr "ХАТА: {path} эсендәге {key}:{subkey} рөхсәт ителгән асҡыстар исемлегендә юҡ: {allowed_keys}!" + +#: ../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 "Кодировка '{enc}' итеп ҡуйылған, F-Droid-та кодировка проблемалары булыуы мөмкин. Иң яҡшы һөҙөмтә өсөн уны 'UTF-8'-гә ҡуйығыҙ." + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"Enter the path to the Android SDK (%s) here:\n" +"> " +msgstr "" +"Android SDK-ның юлын (%s) бында яҙығыҙ:\n" +"> " + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Environment variable {var} from {configname} is not set!" +msgstr "{configname} эсенән {var} мөхит үҙгәреүсәне күрһәтелмәгән!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Environment variable {{env: {var}}} is not set!" +msgstr "{{env: {var}}} мөхит үҙгәреүсәне күрһәтелмәгән!" + +#: ../fdroidserver/deploy.py +msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" +msgstr "'github_releases' урынлаштырыу хатаһы, {} юҡ. (Башта `fdroid update` командаһын эшләтеп алырға кәрәк булыуы мөмкин.)" + +#: ../fdroidserver/import_subcommand.py +msgid "Error while getting repo address" +msgstr "Репозиторий адресын алғанда хата" + +#: ../fdroidserver/scanner.py +msgid "Exit with a non-zero code if problems were found" +msgstr "Проблемалар табылһа, нулдән айырмалы код менән сығырға" + +#: ../fdroidserver/__main__.py +msgid "Extract application metadata from a source repository" +msgstr "Сығанаҡ репозиторийынан ҡушымтаның мета-мәғлүмәттәрен сығарыу" + +#: ../fdroidserver/__main__.py +msgid "Extract signatures from APKs" +msgstr "APK-ларҙан имзаларҙы сығарыу" + +#: ../fdroidserver/install.py +msgid "F-Droid.apk could not be downloaded from any known source!" +msgstr "F-Droid.apk-ны билдәле сығанаҡтарҙың береһенән дә йөкмәтеп булманы!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed copying {path}: {error}" +msgstr "{path} күсерелмәне: {error}" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Failed fetching signatures for '{apkfilename}': {error}" +msgstr "'{apkfilename}' өсөн имзаларҙы алып булманы: {error}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed reading {path}: {error}" +msgstr "{path} уҡылманы: {error}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed resizing {path}: {error}" +msgstr "{path} үлсәме үҙгәртелмәне: {error}" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Failed to create S3 bucket: {url}" +msgstr "S3 контейнерын булдырып булманы: {url}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get APK information, deleting {path}" +msgstr "APK тураһында мәғлүмәт алып булманы, {path} юйыла" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Failed to get APK information, skipping {path}" +msgstr "APK тураһында мәғлүмәт алып булманы, {path} үткәреп ебәрелә" + +#: ../fdroidserver/update.py +msgid "Failed to get APK signing key fingerprint" +msgstr "APK имзалау асҡысының бармаҡ эҙен алып булманы" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Failed to install '{apkfilename}' on {dev}: {error}" +msgstr "'{apkfilename}' {dev} ҡоролмаһына ҡуйылманы: {error}" + +#: ../fdroidserver/common.py +msgid "Failed to sign application" +msgstr "Ҡушымтаны тамғалап булманы" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Fetched buildserverid from VM: {buildserverid}" +msgstr "VM-дан йыйыу-серверының ID-һы алынды: {buildserverid}" + +#: ../fdroidserver/signatures.py +#, python-brace-format +msgid "Fetched signatures for '{apkfilename}' -> '{sigdir}'" +msgstr "'{apkfilename}' өсөн имзалар алынды -> '{sigdir}'" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "File disappeared while processing it: {path}" +msgstr "Файл эшкәртелгән ваҡытта юғалды: {path}" + +#: ../fdroidserver/build.py ../fdroidserver/install.py +#: ../fdroidserver/rewritemeta.py ../fdroidserver/scanner.py +#: ../fdroidserver/update.py +msgid "Finished" +msgstr "Тамамланды" + +#: ../fdroidserver/lint.py +msgid "Forbidden HTML tags" +msgstr "Тыйылған HTML тегтары" + +#: ../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 "{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 "\"{name}\" ҡушымтаһы өсөн мета-мәғлүмәтһеҙ \"{path}\" графикаһы табылды!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Found bad funding file \"{path}\" for \"{name}\":" +msgstr "\"{name}\" өсөн дөрөҫ булмаған \"{path}\" финанслау файлы табылды:" + +#: ../fdroidserver/common.py +msgid "Found invalid appids in arguments" +msgstr "Аргументтарҙа дөрөҫ булмаған appid-ҙар табылды" + +#: ../fdroidserver/common.py +msgid "Found invalid versionCodes for some apps" +msgstr "Ҡайһы бер ҡушымталар өсөн дөрөҫ булмаған versionCode-тар табылды" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Found multiple JAR Signature Block Files in {path}" +msgstr "{path} эсендә бер нисә JAR имза блок файлы табылды" + +#: ../fdroidserver/common.py +msgid "Found multiple Signer Certificates!" +msgstr "Бер нисә имзалаусы сертификаты табылды!" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Found multiple metadata files for {appid}" +msgstr "{appid} өсөн бер нисә мета-мәғлүмәт файлы табылды" + +#: ../fdroidserver/index.py +msgid "Found multiple signing certificates for repository." +msgstr "Репозиторий өсөн бер нисә имзалау сертификаты табылды." + +#: ../fdroidserver/index.py +msgid "Found no signing certificates for repository." +msgstr "Репозиторий өсөн имзалау сертификаттары табылманы." + +#: ../fdroidserver/lint.py +#, python-format +msgid "Found non-file at %s" +msgstr "%s юлында файл булмаған объект табылды" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Found {apkfilename} at {url}" +msgstr "{apkfilename} {url} адресында табылды" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Found {count} problems in {filename}" +msgstr "{filename} эсендә {count} проблема табылды" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Found {count} warnings in {filename}" +msgstr "{filename} эсендә {count} иҫкәрмә табылды" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Generated skeleton metadata for {appid}" +msgstr "{appid} өсөн мета-мәғлүмәт ҡалыбы булдырылды" + +#: ../fdroidserver/common.py +#, python-format +msgid "Git checkout of '%s' failed" +msgstr "'%s' Git checkout-ы уңышһыҙ булды" + +#: ../fdroidserver/common.py +msgid "Git clean failed" +msgstr "Git clean уңышһыҙ булды" + +#: ../fdroidserver/common.py +msgid "Git fetch failed" +msgstr "Git fetch уңышһыҙ булды" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +#, python-format +msgid "Git remote set-head failed: \"%s\"" +msgstr "Git remote set-head уңышһыҙ булды: \"%s\"" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Git reset failed" +msgstr "Git reset уңышһыҙ булды" + +#: ../fdroidserver/common.py +msgid "Git submodule deinit failed" +msgstr "Git submodule deinit уңышһыҙ булды" + +#: ../fdroidserver/common.py +msgid "Git submodule sync failed" +msgstr "Git submodule sync уңышһыҙ булды" + +#: ../fdroidserver/common.py +msgid "Git submodule update failed" +msgstr "Git submodule update уңышһыҙ булды" + +#: ../fdroidserver/common.py +msgid "HTTPS must be used with Subversion URLs!" +msgstr "Subversion URL-дары менән HTTPS ҡулланылырға тейеш!" + +#: ../fdroidserver/deploy.py +msgid "If a git mirror gets to big, allow the archive to be deleted" +msgstr "git көҙгөһө бигерәк ҙурайып китһә, архивты юйырға рөхсәт итеү" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "If this upload fails, try manually uploading to {url}" +msgstr "Был йөкмәү уңышһыҙ булһа, {url} адресына ҡулдан йөкмәп ҡарағыҙ" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Ignoring '{field}' in '{metapath}' metadata because it is deprecated." +msgstr "'{metapath}' мета-мәғлүмәттәрендәге '{field}' иҫкергән булғанға иғтибарһыҙ ҡалдырыла." + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring FUNDING.yml entry longer than 2048: %s" +msgstr "2048-ҙән оҙонораҡ FUNDING.yml яҙмаһы иғтибарһыҙ ҡалдырыла: %s" + +#: ../fdroidserver/update.py +#, python-format +msgid "Ignoring bad element in manifest: %s" +msgstr "Манифестағы дөрөҫ булмаған элемент иғтибарһыҙ ҡалдырыла: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Ignoring deprecated {oldfile}, use {newfile}!" +msgstr "Иҫкергән {oldfile} иғтибарһыҙ ҡалдырыла, {newfile} ҡулланығыҙ!" + +#: ../fdroidserver/index.py +msgid "Ignoring package without metadata: " +msgstr "Мета-мәғлүмәтһеҙ пакет иғтибарһыҙ ҡалдырыла: " + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Ignoring stale cache data for {apkfilename}" +msgstr "{apkfilename} өсөн иҫкергән кеш мәғлүмәттәре иғтибарһыҙ ҡалдырыла" + +#: ../fdroidserver/update.py +msgid "Include APKs that are signed with disabled algorithms like MD5" +msgstr "MD5 кеүек һүндерелгән алгоритмдар менән тамғаланған APK-ларҙы индереү" + +#: ../fdroidserver/mirror.py +msgid "Include the PGP signature .asc files in the mirror" +msgstr "Көҙгөгә PGP-имзалы .asc файлдарын индереү" + +#: ../fdroidserver/mirror.py +msgid "Include the build logs in the mirror" +msgstr "Көҙгөгә йыйыу логтарын индереү" + +#: ../fdroidserver/mirror.py +msgid "Include the source tarballs in the mirror" +msgstr "Көҙгөгә сығанаҡ tarball-дарҙы индереү" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Including metadata from %s@%s" +msgstr "%s@%s версияһынан мета-мәғлүмәттәр индерелә" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Including metadata from {path}" +msgstr "{path} юлынан мета-мәғлүмәттәр индерелә" + +#: ../fdroidserver/common.py +msgid "Initialising submodules" +msgstr "Аҫмодулдәрҙе инициализациялау" + +#: ../fdroidserver/install.py +msgid "Install all signed applications available" +msgstr "Барлыҡ тамғаланған ҡушымталарҙы ҡуйыу" + +#: ../fdroidserver/__main__.py +msgid "Install built packages on devices" +msgstr "Йыйылған пакеттарҙы ҡоролмаларға ҡуйыу" + +#: ../fdroidserver/install.py +#, python-format +msgid "Installing %s..." +msgstr "%s ҡуйыла..." + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Installing '{apkfilename}' on {dev}..." +msgstr "'{apkfilename}' {dev} ҡоролмаһына ҡуйыла..." + +#: ../fdroidserver/__main__.py +msgid "Interact with the repo HTTP server" +msgstr "Репоның HTTP-серверы менән эш итеү" + +#: ../fdroidserver/update.py +msgid "Invalid APK" +msgstr "Дөрөҫ булмаған APK" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid AutoUpdateMode: {mode}" +msgstr "Дөрөҫ булмаған AutoUpdateMode: {mode}" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid UpdateCheckMode: {mode}" +msgstr "Дөрөҫ булмаған UpdateCheckMode: {mode}" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "Invalid VercodeOperation: {field}" +msgstr "Дөрөҫ булмаған VercodeOperation: {field}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Invalid VercodeOperation: {invalid_ops}" +msgstr "Дөрөҫ булмаған VercodeOperation: {invalid_ops}" + +#. Translators: https://developer.android.com/build/configure-app-module#set-application-id +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid application ID {appid}" +msgstr "Дөрөҫ булмаған ҡушымта идентификаторы {appid}" + +#: ../fdroidserver/lint.py +msgid "Invalid bulleted list" +msgstr "Дөрөҫ булмаған маркировкалы исемлек" + +#: ../fdroidserver/common.py +#, python-format +msgid "Invalid name for published file: %s" +msgstr "Баҫтырылған файл өсөн дөрөҫ булмаған исем: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid ndk: entry in build: \"{ndk}\"" +msgstr "Йыйылмала дөрөҫ булмаған ndk: яҙмаһы: \"{ndk}\"" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Invalid redirect to non-HTTPS: {before} -> {after} " +msgstr "HTTPS булмаған адресҡа дөрөҫ булмаған йүнәлтеү: {before} -> {after} " + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid scrlib metadata: '{file}' does not exist" +msgstr "Дөрөҫ булмаған scrlib мета-мәғлүмәте: '{file}' юҡ" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: could not parse '{file}'" +msgstr "Дөрөҫ булмаған srclib мета-мәғлүмәте: '{file}' танылманы" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Invalid srclib metadata: unknown key '{key}' in '{file}'" +msgstr "Дөрөҫ булмаған srclib мета-мәғлүмәте: '{file}' эсендә билдәһеҙ '{key}' асҡысы" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature failed to verify: {path}" +msgstr "JAR имзаһы тикшерелмәне: {path}" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "JAR signature verified: {path}" +msgstr "JAR имзаһы тикшерелде: {path}" + +#: ../fdroidserver/scanner.py +msgid "Java JAR file" +msgstr "Java JAR файлы" + +#: ../fdroidserver/mirror.py ../fdroidserver/publish.py +#: ../fdroidserver/update.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 "Компиляцияланған Java класы" + +#: ../fdroidserver/signindex.py +msgid "Java jarsigner not found! Install in standard location or set java_paths!" +msgstr "Java jarsigner табылманы! Стандарт урынға ҡуйығыҙ йәки java_paths-ты күрһәтегеҙ!" + +#: ../fdroidserver/lint.py +msgid "Javascript in HTML src attributes" +msgstr "HTML-дың src атрибуттарында Javascript" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "Keeping failed build \"{apkfilename}\"" +msgstr "Уңышһыҙ йыйылған \"{apkfilename}\" һаҡлана" + +#: ../fdroidserver/init.py +msgid "Keystore for signing key:\t" +msgstr "Имзалау асҡысы өсөн асҡыстар һаҡлағысы:\t" + +#: ../fdroidserver/lint.py +msgid "Known debug key is used in AllowedAPKSigningKeys: " +msgstr "AllowedAPKSigningKeys-та билдәле төҙәтеү асҡысы ҡулланыла: " + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Last used commit '{commit}' looks like a tag, but UpdateCheckMode is '{ucm}'" +msgstr "Һуңғы ҡулланылған '{commit}' коммиты тегҡа оҡшаған, ләкин UpdateCheckMode '{ucm}' итеп ҡуйылған" + +#: ../fdroidserver/lint.py +msgid "Liberapay donation methods belong in the Liberapay: field" +msgstr "Liberapay иғәнә ысулдары Liberapay: яланында булырға тейеш" + +#: ../fdroidserver/rewritemeta.py +msgid "List files that would be reformatted (dry run)" +msgstr "Яңынан форматланасаҡ файлдарҙың исемлеге (ҡоро эшләтеп ҡарау)" + +#: ../fdroidserver/lint.py +msgid "Locale included in f-droid.org URL" +msgstr "f-droid.org URL-ында локаль бар" + +#: ../fdroidserver/build.py +msgid "Make the build stop on exceptions" +msgstr "Хаталар булғанда йыйыуҙы туҡтатыу" + +#: ../fdroidserver/index.py +msgid "Malformed repository mirrors." +msgstr "Репозиторий көҙгөләре дөрөҫ форматланмаған." + +#: ../fdroidserver/deploy.py +msgid "Malformed serverwebroot line:" +msgstr "serverwebroot юлы дөрөҫ форматланмаған:" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Max recursion depth in ZIP file reached: %s" +msgstr "ZIP файлында максималь рекурсия тәрәнлегенә етелде: %s" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Mirror config for {url} contains \"isPrimary\" key!" +msgstr "{url} өсөн көҙгө көйләүҙәрендә \"isPrimary\" асҡысы бар!" + +#: ../fdroidserver/mirror.py +msgid "Mirror the full repo and archive, all file types." +msgstr "Репо менән архивтың тулы көҙгөһөн яһау, бөтә файл төрҙәре." + +#: ../fdroidserver/gpgsign.py +msgid "Missing output directory" +msgstr "Сығарыу каталогы юҡ" + +#: ../fdroidserver/metadata.py +msgid "Moving Anti-Features declarations to localized files:" +msgstr "Anti-Features декларацияларын локалләштерелгән файлдарға күсереү:" + +#: ../fdroidserver/index.py +msgid "Neither \"repo_pubkey\" nor \"keystorepass\" set in config.yml" +msgstr "config.yml-да \"repo_pubkey\" ҙә, \"keystorepass\" та күрһәтелмәгән" + +#: ../fdroidserver/verify.py +#, python-format +msgid "No APK for package: %s" +msgstr "%s пакеты өсөн APK юҡ" + +#: ../fdroidserver/common.py +msgid "No Android SDK found!" +msgstr "Android SDK табылманы!" + +#: ../fdroidserver/install.py +msgid "No attached devices found" +msgstr "Тоташтырылған ҡоролмалар табылманы" + +#: ../fdroidserver/install.py +msgid "No devices found for `adb install`! Please plug one in." +msgstr "`adb install` өсөн ҡоролмалар табылманы! Зинһар, берәйһен тоташтырығыҙ." + +#: ../fdroidserver/index.py +msgid "No fingerprint in URL." +msgstr "URL-да бармаҡ эҙе юҡ." + +#: ../fdroidserver/common.py +msgid "No git submodules available" +msgstr "git аҫмодулдәре юҡ" + +#: ../fdroidserver/import_subcommand.py +msgid "No gradle project could be found. Specify --subdir?" +msgstr "gradle проекты табылманы. --subdir күрһәтеп ҡарайһығыҙмы?" + +#: ../fdroidserver/import_subcommand.py +msgid "No information found." +msgstr "Мәғлүмәт табылманы." + +#: ../fdroidserver/checkupdates.py +msgid "No matching tags found" +msgstr "Ярашлы тегтар табылманы" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "No minimum SDK version found in {0}, using default (3)." +msgstr "{0} эсендә SDK-ның минималь версияһы табылманы, стандарт (3) ҡулланыла." + +#: ../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 "Ҡушымтаның Android өсөн булыуын күрһәтеү кәрәкмәй" + +#: ../fdroidserver/deploy.py +msgid "No option set! Edit your config.yml to set at least one of these:" +msgstr "Бер параметр ҙа күрһәтелмәгән! config.yml файлына үҙгәреш индереп, ошоларҙың кәмендә береһен күрһәтегеҙ:" + +#: ../fdroidserver/common.py +msgid "No packages specified" +msgstr "Пакеттар күрһәтелмәгән" + +#: ../fdroidserver/install.py +#, python-format +msgid "No signed APK available for %s" +msgstr "%s өсөн тамғаланған APK юҡ" + +#: ../fdroidserver/install.py +msgid "No signed output directory - nothing to do" +msgstr "Тамғаланған сығарыу каталогы юҡ — эшләр нәмә юҡ" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No signing certificates found in {path}" +msgstr "{path} эсендә имзалау сертификаттары табылманы" + +#: ../fdroidserver/common.py +#, python-format +msgid "No such package: %s" +msgstr "Бындай пакет юҡ: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "No such versionCode {versionCode} for app {appid}" +msgstr "{appid} ҡушымтаһы өсөн бындай {versionCode} versionCode-ы юҡ" + +#: ../fdroidserver/checkupdates.py +msgid "No tags found" +msgstr "Тегтар табылманы" + +#: ../fdroidserver/publish.py ../fdroidserver/verify.py +msgid "No unsigned directory - nothing to do" +msgstr "Тамғаланмаған каталог юҡ — эшләр нәмә юҡ" + +#: ../fdroidserver/__main__.py +msgid "No version information could be found." +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 "{appid} өсөн эшләр нәмә юҡ." + +#: ../fdroidserver/init.py +msgid "Now set these in config.yml:" +msgstr "Хәҙер ошоларҙы config.yml-да күрһәтегеҙ:" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "OBB file has newer versionCode({integer}) than any APK:" +msgstr "OBB файлының versionCode-ы ({integer}) теләһә ҡайһы APK-ныҡынан яңыраҡ:" + +#: ../fdroidserver/update.py +msgid "OBB filename must start with \"main.\" or \"patch.\":" +msgstr "OBB файлының исеме \"main.\" йәки \"patch.\" менән башланырға тейеш:" + +#: ../fdroidserver/update.py +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 "Офлайн машина, `fdroid deploy` эшләтелгәнгә тиклем git көҙгөһөн булдырыу үткәреп ебәрелә" + +#: ../fdroidserver/deploy.py +msgid "One of the 'github_releases' config items is missing the 'packageNames' value. skipping ..." +msgstr "'github_releases' көйләүҙәренең береһендә 'packageNames' ҡиммәте юҡ. үткәреп ебәрелә ..." + +#: ../fdroidserver/deploy.py +msgid "One of the 'github_releases' config items is missing the 'projectUrl' value. skipping ..." +msgstr "'github_releases' көйләүҙәренең береһендә 'projectUrl' ҡиммәте юҡ. үткәреп ебәрелә ..." + +#: ../fdroidserver/deploy.py +msgid "One of the 'github_releases' config items is missing the 'token' value. skipping ..." +msgstr "'github_releases' көйләүҙәренең береһендә 'token' ҡиммәте юҡ. үткәреп ебәрелә ..." + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Only PNG and JPEG are supported for graphics, found: {path}" +msgstr "Графика өсөн тик PNG һәм JPEG ғына ярай, табылды: {path}" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/common.py +msgid "Only accepts a single key \"env\"" +msgstr "Тик бер генә \"env\" асҡысын ҡабул итә" + +#: ../fdroidserver/checkupdates.py +msgid "Only process apps with auto-updates" +msgstr "Тик автоматик яңыртылыусы ҡушымталарҙы ғына эшкәртеү" + +#: ../fdroidserver/lint.py +msgid "OpenCollective donation methods belong in the OpenCollective: field" +msgstr "OpenCollective иғәнә ысулдары OpenCollective: яланында булырға тейеш" + +#: ../fdroidserver/verify.py +msgid "Output JSON report to file named after APK." +msgstr "JSON отчетын APK исеме менән аталған файлға сығарыу." + +#: ../fdroidserver/scanner.py +msgid "Output JSON to stdout." +msgstr "JSON-ды стандарт сығарыу ағымына (stdout) сығарыу." + +#: ../fdroidserver/checkupdates.py ../fdroidserver/gpgsign.py +#: ../fdroidserver/publish.py ../fdroidserver/signindex.py +#: ../fdroidserver/update.py +msgid "Outputting JSON" +msgstr "JSON сығарыла" + +#: ../fdroidserver/import_subcommand.py +msgid "Overall license of the project." +msgstr "Проекттың дөйөм лицензияһы." + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "Overriding blank versionName in {apkfilename} from metadata: {version}" +msgstr "{apkfilename} эсендәге буш versionName мета-мәғлүмәттән алынған {version} менән алмаштырыла" + +#: ../fdroidserver/import_subcommand.py +#, python-brace-format +msgid "Package \"{appid}\" already exists" +msgstr "\"{appid}\" пакеты инде бар" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Parsing manifest at '{path}'" +msgstr "'{path}' юлындағы манифест таныла" + +#: ../fdroidserver/common.py +msgid "Password required with username" +msgstr "Ҡулланыусы исеме менән бергә пароль кәрәк" + +#: ../fdroidserver/import_subcommand.py +msgid "Path to main Android project subdirectory, if not in root." +msgstr "Төп Android проектының аҫкаталогына юл, әгәр ул тамыр каталогында булмаһа." + +#: ../fdroidserver/init.py +msgid "Path to the Android SDK (sometimes set in ANDROID_HOME)" +msgstr "Android SDK-ға юл (ҡайһы саҡ ANDROID_HOME-да күрһәтелә)" + +#: ../fdroidserver/btlog.py +msgid "Path to the git repo to use as the log" +msgstr "Лог итеп ҡулланыу өсөн git репозиторийына юл" + +#: ../fdroidserver/init.py +msgid "Path to the keystore for the repo signing key" +msgstr "Репо имзалау асҡысы өсөн асҡыстар һаҡлағысына юл" + +#: ../fdroidserver/nightly.py +msgid "Print the secret variable to the terminal for easy copy/paste" +msgstr "Йәшерен үҙгәреүсәнде күсереп-ҡуйыу еңел булһын өсөн терминалға сығарыу" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Privacy mode was enabled based on your locale ({country_code})." +msgstr "Һеҙҙең локаль ({country_code}) нигеҙендә хосусилыҡ режимы ҡабыҙылды." + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Problem with ZIP file: %s, error %s" +msgstr "ZIP файлы менән проблема: %s, хата %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Problem with xml at '{path}'" +msgstr "'{path}' юлындағы xml менән проблема" + +#: ../fdroidserver/checkupdates.py +msgid "Process auto-updates" +msgstr "Автоматик яңыртыуҙарҙы эшкәртеү" + +#: ../fdroidserver/publish.py ../fdroidserver/update.py +#, python-brace-format +msgid "Processing {apkfilename}" +msgstr "{apkfilename} эшкәртелә" + +#: ../fdroidserver/checkupdates.py ../fdroidserver/scanner.py +#, python-brace-format +msgid "Processing {appid}" +msgstr "{appid} эшкәртелә" + +#: ../fdroidserver/update.py +msgid "Produce human-readable XML/JSON for index files" +msgstr "Индекс файлдары өсөн кеше уҡый алырлыҡ XML/JSON булдырыу" + +#: ../fdroidserver/import_subcommand.py +msgid "Project URL to import from." +msgstr "Импортлау өсөн проекттың URL-ы." + +#: ../fdroidserver/lint.py +msgid "Punctuation should be avoided" +msgstr "Тыныш билдәләренән ҡасырға кәрәк" + +#: ../fdroidserver/btlog.py +msgid "Push the log to this git remote repository" +msgstr "Логты ошо алыҫтағы git репозиторийына ебәреү" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Pushing binary transparency log to {url}" +msgstr "Бинар асыҡлыҡ логы {url} адресына ебәрелә" + +#: ../fdroidserver/deploy.py +msgid "Pushing to remote server failed!" +msgstr "Алыҫтағы серверға ебәреү уңышһыҙ булды!" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Pushing to {url}" +msgstr "{url} адресына ебәрелә" + +#: ../fdroidserver/__main__.py +msgid "Quickly start a new repository" +msgstr "Яңы репозиторийҙы тиҙ генә башлау" + +#: ../fdroidserver/__main__.py +msgid "Read all the metadata files and exit" +msgstr "Барлыҡ мета-мәғлүмәт файлдарын уҡыу һәм сығыу" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading '{config_file}'" +msgstr "'{config_file}' уҡыла" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed, APK invalid: '{apkfilename}'" +msgstr "packageName/versionCode/versionName уҡылманы, APK дөрөҫ түгел: '{apkfilename}'" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Reading packageName/versionCode/versionName failed,APK invalid: '{apkfilename}'" +msgstr "packageName/versionCode/versionName уҡылманы, APK дөрөҫ түгел: '{apkfilename}'" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Reading {apkfilename} from cache" +msgstr "{apkfilename} кештан уҡыла" + +#: ../fdroidserver/build.py +msgid "Refresh and cache scanner rules and signatures from the network" +msgstr "Сканлаусы ҡағиҙәләрен һәм имзаларын селтәрҙән яңыртыу һәм кешлау" + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." +msgstr "'{path}' тамғалауҙан баш тартам, файл {dir1} һәм {dir2} каталогтарында ла бар." + +#: ../fdroidserver/verify.py +msgid "Remove source tarball and any APKs if successfully verified." +msgstr "Уңышлы тикшерелһә, сығанаҡ tarball-ды һәм теләһә ниндәй APK-ларҙы юйыу." + +#: ../fdroidserver/common.py +msgid "Removing specified files" +msgstr "Күрһәтелгән файлдар юйыла" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Removing {path}\"" +msgstr "\"{path} юйыла" + +#: ../fdroidserver/update.py +msgid "Rename APK files that do not match package.name_123.apk" +msgstr "package.name_123.apk ҡалыбына тап килмәгән APK файлдарының исемен үҙгәртеү" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Resigning {apkfilename} with provided debug.keystore" +msgstr "{apkfilename} бирелгән debug.keystore менән яңынан тамғалана" + +#: ../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 "Сығарылышты иҫкәрмәләр һәм хаталар менән сикләү" + +#: ../fdroidserver/net.py +#, python-format +msgid "Retrying failed download: %s" +msgstr "Уңышһыҙ йөкмәү ҡабатлана: %s" + +#: ../fdroidserver/__main__.py +msgid "Rewrite all the metadata files" +msgstr "Барлыҡ мета-мәғлүмәт файлдарын үҙгәртеп яҙыу" + +#: ../fdroidserver/rewritemeta.py +#, python-brace-format +msgid "Rewriting '{appid}'" +msgstr "'{appid}' үҙгәртеп яҙыла" + +#: ../fdroidserver/checkupdates.py +msgid "Run on git repo that has uncommitted changes" +msgstr "Һаҡланмаған үҙгәрештәре булған git репозиторийында эшләтеү" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "Run over {cibase} to find -debug.apk. and skip repo_basedir {repo_basedir}" +msgstr "{cibase} буйлап -debug.apk. табыу өсөн эшләтеү. һәм repo_basedir {repo_basedir} үткәреп ебәреү" + +#: ../fdroidserver/lint.py +msgid "Run rewritemeta to fix formatting" +msgstr "Форматлауҙы төҙәтеү өсөн rewritemeta-ны эшләтегеҙ" + +#: ../fdroidserver/deploy.py +msgid "Running first pass with MD5 checking disabled" +msgstr "MD5 тикшереүе һүндерелгән килеш беренсе үтеү башҡарыла" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "Running wget in {path}" +msgstr "wget {path} каталогында эшләтелә" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "SHA-256 of {url} does not match entry!" +msgstr "{url} адресының SHA-256 суммаһы яҙмаға тап килмәй!" + +#: ../fdroidserver/build.py +msgid "Scan the resulting APK(s) for known non-free classes." +msgstr "Алынған APK(-лар)ҙы билдәле ирекле булмаған кластарға сканлау." + +#: ../fdroidserver/__main__.py +msgid "Scan the source code of a package" +msgstr "Пакеттың сығанаҡ кодын сканлау" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {apk}" +msgstr "Сканлаусы {apk} эсендә {count} проблема тапты" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:" +msgstr "Сканлаусы {appid} эсендә {count} проблема тапты:" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Scanner found {count} problems in {appid}:{versionCode}:" +msgstr "Сканлаусы {appid}:{versionCode} эсендә {count} проблема тапты:" + +#: ../fdroidserver/build.py +msgid "Scanner found {} problem" +msgid_plural "Scanner found {} problems" +msgstr[0] "Сканлаусы {} проблема тапты" +msgstr[1] "Сканлаусы {} проблема тапты" + +#: ../fdroidserver/scanner.py +msgid "Scanning APK for extra signing blocks." +msgstr "APK-ны өҫтәмә имзалау блоктарына сканлау." + +#: ../fdroidserver/scanner.py +msgid "Scanning APK with dexdump for known non-free classes." +msgstr "APK-ны dexdump менән билдәле ирекле булмаған кластарға сканлау." + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Set NDK {release} ({version}) up" +msgstr "NDK {release} ({version}) көйләнде" + +#: ../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 "Асыҡ файлдар сикләүен {integer} итеп ҡуйыу" + +#: ../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 "Был йыйыу өсөн {0} секундлыҡ тайм-аут ҡуйыла" + +#: ../fdroidserver/__main__.py +msgid "Sign and place packages in the repo" +msgstr "Пакеттарҙы тамғалау һәм репозиторийға урынлаштырыу" + +#: ../fdroidserver/__main__.py +msgid "Sign indexes created using update --nosign" +msgstr "update --nosign ярҙамында булдырылған индекстарҙы тамғалау" + +#: ../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 "Дөрөҫ булмаған имзалы '{apkfilename}' үткәреп ебәрелә!" + +#: ../fdroidserver/deploy.py ../fdroidserver/index.py +#, python-format +msgid "Skipping GitLab Pages mirror because the repo is too large (>%.2fGB)!" +msgstr "GitLab Pages көҙгөһө үткәреп ебәрелә, сөнки репозиторий бигерәк ҙур (>%.2fGB)!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping index generation for {appid}" +msgstr "{appid} өсөн индекс булдырыу үткәреп ебәрелә" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Skipping {apkfilename} with invalid signature!" +msgstr "Дөрөҫ булмаған имзалы {apkfilename} үткәреп ебәрелә!" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "Skipping {appid}: disabled" +msgstr "{appid} үткәреп ебәрелә: һүндерелгән" + +#: ../fdroidserver/deploy.py +msgid "Specify a local folder to sync the repo to" +msgstr "Репоны синхронлаштырыу өсөн локаль каталогты күрһәтегеҙ" + +#: ../fdroidserver/deploy.py +msgid "Specify an identity file to provide to SSH for rsyncing" +msgstr "rsync өсөн SSH-ға биреләсәк идентификация файлын күрһәтегеҙ" + +#: ../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 "Stripping mystery signature from {apkfilename}" +msgstr "Серле имза {apkfilename} файлынан алына" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Summary '%s' is just the app's name" +msgstr "'%s' ҡыҫҡаса аңлатмаһы — ул ҡушымтаның исеме генә" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Summary of length {length} is over the {limit} char limit" +msgstr "{length} оҙонлоғондағы ҡыҫҡаса аңлатма {limit} символ сикләүенән артып китә" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "System clock is older than date in {path}!" +msgstr "Система сәғәте {path} эсендәге датанан иҫкерәк!" + +#: ../fdroidserver/checkupdates.py +msgid "Tags update mode only works for git, hg, bzr and git-svn repositories currently" +msgstr "Тегтарҙы яңыртыу режимы әлеге ваҡытта тик git, hg, bzr һәм git-svn репозиторийҙары өсөн генә эшләй" + +#: ../fdroidserver/checkupdates.py +msgid "Tags update mode used in git-svn, but the repo was not set up with tags" +msgstr "Тегтарҙы яңыртыу режимы git-svn-да ҡулланылған, ләкин репо тегтар менән көйләнмәгән" + +#: ../fdroidserver/build.py +msgid "Test mode - put output in the tmp directory only, and always build, even if the output already exists." +msgstr "Һынау режимы — сығарылышты тик tmp каталогына ғына урынлаштырыу һәм сығарылыш булһа ла, һәр ваҡыт йыйыу." + +#: ../fdroidserver/index.py +msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" +msgstr "\"qrcode\" Python пакеты ҡуйылмаған (мәҫ. apt-get install python3-qrcode)!" + +#. 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 "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)" + +#: ../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/index.py +msgid "The repository's fingerprint does not match." +msgstr "Репозиторийҙың бармаҡ эҙе тап килмәй." + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "The root dir for local_copy_dir \"{path}\" does not exist!" +msgstr "local_copy_dir \"{path}\" өсөн тамыр каталогы юҡ!" + +#: ../fdroidserver/publish.py +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/mirror.py +msgid "This command should never be used to mirror f-droid.org! A full copy requires more than 600GB." +msgstr "Был команда f-droid.org-тың көҙгөһөн яһау өсөн бер ҡасан да ҡулланылырға тейеш түгел! Тулы күсермә өсөн 600GB-тан ашыу урын кәрәк." + +#: ../fdroidserver/common.py +msgid "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/fdroid." +msgstr "Был — F-Droid менән ҡулланыу өсөн ҡушымталар репозиторийы. Был репозиторийҙағы ҡушымталар йә оригиналь эшләүселәр тарафынан йыйылған рәсми бинарҙар, йә f-droid.org администраторы тарафынан https://gitlab.com/fdroid адресындағы ҡоралдар ярҙамында сығанаҡ кодтан йыйылған бинарҙар." + +#: ../fdroidserver/import_subcommand.py +#, python-format +msgid "This repo already has local metadata: %s" +msgstr "Был репоның инде локаль мета-мәғлүмәттәре бар: %s" + +#: ../fdroidserver/init.py +#, python-format +msgid "" +"To complete the setup, add your APKs to \"%s\"\n" +"then run \"fdroid update -c; fdroid update\". You might also want to edit\n" +"\"config.yml\" to set the URL, repo name, and more. You should also set up\n" +"a signing key (a temporary one might have been automatically generated).\n" +"\n" +"For more info: https://f-droid.org/docs/Setup_an_F-Droid_App_Repo\n" +"and https://f-droid.org/docs/Signing_Process" +msgstr "" +"Көйләүҙе тамамлау өсөн, APK-ларығыҙҙы \"%s\" каталогына өҫтәгеҙ,\n" +"шунан \"fdroid update -c; fdroid update\" командаһын эшләтегеҙ. Шулай уҡ URL-ды, репо исемен\n" +"һәм башҡаларҙы көйләү өсөн \"config.yml\" файлына үҙгәреш индерергә теләрһегеҙ. \n" +"Шулай уҡ имзалау асҡысын көйләргә тейешһегеҙ (ваҡытлыса асҡыс автоматик рәүештә булдырылған булырға мөмкин).\n" +"\n" +"Күберәк мәғлүмәт өсөн: https://f-droid.org/docs/Setup_an_F-Droid_App_Repo\n" +"һәм https://f-droid.org/docs/Signing_Process" + +#: ../fdroidserver/deploy.py +msgid "To use awsbucket, awssecretkey and awsaccesskeyid must also be set in config.yml!" +msgstr "awsbucket-ты ҡулланыу өсөн config.yml-да awssecretkey һәм awsaccesskeyid та күрһәтелергә тейеш!" + +#: ../fdroidserver/deploy.py +msgid "To use rclone, rclone_config and awsbucket must be set in config.yml!" +msgstr "rclone-ды ҡулланыу өсөн config.yml-да rclone_config һәм awsbucket күрһәтелергә тейеш!" + +#: ../fdroidserver/lint.py +msgid "URL must start with https:// or http://" +msgstr "URL https:// йәки http:// менән башланырға тейеш" + +#: ../fdroidserver/lint.py +msgid "URL shorteners should not be used" +msgstr "URL ҡыҫҡартҡыстары ҡулланылырға тейеш түгел" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "URL {url} in Description: {error}" +msgstr "Тасуирламалағы {url} URL-ы: {error}" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use FSF or OSI approved tags from https://spdx.org/license-list" +msgstr "Көтөлмәгән \"{}\" лицензия тегы! Тик https://spdx.org/license-list адресынан FSF йәки OSI тарафынан раҫланған тегтарҙы ҡулланығыҙ" + +#: ../fdroidserver/lint.py +msgid "Unexpected license tag \"{}\"! Only use license tags configured in your config file" +msgstr "Көтөлмәгән \"{}\" лицензия тегы! Тик конфигурация файлында көйләнгән лицензия тегтарын ҡулланығыҙ" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Unknown entry {key} in {configname}" +msgstr "{configname} эсендә билдәһеҙ {key} яҙмаһы" + +#: ../fdroidserver/__main__.py +msgid "Unknown exception found!" +msgstr "Билдәһеҙ хата табылды!" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "Unknown file '{filename}' in build '{versionName}'" +msgstr "'{versionName}' йыйылмаһында билдәһеҙ '{filename}' файлы" + +#: ../fdroidserver/metadata.py +#, python-format +msgid "Unknown metadata format: %s" +msgstr "Билдәһеҙ мета-мәғлүмәт форматы: %s" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unknown metadata format: {path} (use: *.yml)" +msgstr "Билдәһеҙ мета-мәғлүмәт форматы: {path} (ҡулланығыҙ: *.yml)" + +#: ../fdroidserver/common.py +msgid "Unknown version of aapt, might cause problems: " +msgstr "aapt-тың билдәһеҙ версияһы, проблемалар тыуҙырыуы мөмкин: " + +#: ../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 "'{path}' эсендә танылмаған '{fieldname}' ҡушымта яланы" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Unrecognised build flag '{build_flag}' in '{path}'" +msgstr "'{path}' эсендә танылмаған '{build_flag}' йыйыу флагы" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported file type \"{extension}\" for repo graphic" +msgstr "Репо графикаһы өсөн яраҡһыҙ \"{extension}\" файл төрө" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "Unsupported graphics file found: {path}" +msgstr "Яраҡһыҙ графика файлы табылды: {path}" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused extlib at %s" +msgstr "%s юлында ҡулланылмаған extlib" + +#: ../fdroidserver/lint.py +#, python-format +msgid "Unused file at %s" +msgstr "%s юлында ҡулланылмаған файл" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scandelete path: %s" +msgstr "Ҡулланылмаған scandelete юлы: %s" + +#: ../fdroidserver/scanner.py +#, python-format +msgid "Unused scanignore path: %s" +msgstr "Ҡулланылмаған scanignore юлы: %s" + +#: ../fdroidserver/__main__.py +msgid "Update repo information for new packages" +msgstr "Яңы пакеттар өсөн репо мәғлүмәтен яңыртыу" + +#: ../fdroidserver/__main__.py +msgid "Update the binary transparency log for a URL" +msgstr "URL өсөн бинар асыҡлыҡ логын яңыртыу" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "UpdateCheckData has invalid URL: {url}" +msgstr "UpdateCheckData-ла дөрөҫ булмаған URL: {url}" + +#. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must match the version code as integer (\\d or [0-9]): {codeex}" +msgstr "UpdateCheckData версия кодына бөтөн һан булараҡ тап килергә тейеш (\\d йәки [0-9]): {codeex}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "UpdateCheckData must use HTTPS URL: {url}" +msgstr "UpdateCheckData HTTPS URL-ын ҡулланырға тейеш: {url}" + +#: ../fdroidserver/lint.py +#, python-brace-format +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 ҡуйылған, ләкин checkupdates әле эшләтелмәгән кеүек." + +#. Translators: https://developer.android.com/build/configure-app-module#set-application-id +#: ../fdroidserver/lint.py +msgid "UpdateCheckName is set to the known application ID, it can be removed" +msgstr "UpdateCheckName билдәле ҡушымта идентификаторына ҡуйылған, уны алып ташларға мөмкин" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Uploading {apkfilename} to androidobservatory.org" +msgstr "{apkfilename} androidobservatory.org-ҡа йөкләнә" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Uploading {apkfilename} to virustotal" +msgstr "{apkfilename} virustotal-ға йөкләнә" + +#: ../fdroidserver/lint.py +msgid "Use /HEAD instead of /master or /main to point at a file in the default branch" +msgstr "Стандарт ботаҡтағы файлға күрһәтеү өсөн /master йәки /main урынына /HEAD ҡулланығыҙ" + +#: ../fdroidserver/update.py +msgid "Use `fdroid update -c` to create it." +msgstr "Уны булдырыу өсөн `fdroid update -c` ҡулланығыҙ." + +#: ../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 "Яңы өҫтәлгән APK-лар өсөн ағымдағы ваҡыт урынына APK-нан датаны ҡулланыу" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Using \"{path}\" for configuring s3cmd." +msgstr "s3cmd-ты көйләү өсөн \"{path}\" ҡулланыла." + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Using \"{path}\" for syncing with remote storage." +msgstr "Алыҫтағы һаҡлағыс менән синхронлаштырыу өсөн \"{path}\" ҡулланыла." + +#: ../fdroidserver/common.py +msgid "Using APK Signature v2" +msgstr "APK имзаһының v2 версияһы ҡулланыла" + +#: ../fdroidserver/common.py +msgid "Using APK Signature v3" +msgstr "APK имзаһының v3 версияһы ҡулланыла" + +#: ../fdroidserver/common.py +msgid "Using JAR Signature" +msgstr "JAR имзаһы ҡулланыла" + +#: ../fdroidserver/common.py +msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" +msgstr "Java-ның jarsigner-ы ҡулланыла, APK-ларҙы тикшереү өсөн тәҡдим ителмәй! apksigner ҡулланығыҙ" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "Using blank dictionary instead of contents of {path}!" +msgstr "{path} эстәлеге урынына буш һүҙлек ҡулланыла!" + +#: ../fdroidserver/init.py +#, python-brace-format +msgid "Using existing keystore \"{path}\"" +msgstr "Инде булған \"{path}\" асҡыстар һаҡлағысы ҡулланыла" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Using rclone to sync with: {url}" +msgstr "Синхронлаштырыу өсөн rclone ҡулланыла: {url}" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "Using s3cmd to sync with: {url}" +msgstr "Синхронлаштырыу өсөн s3cmd ҡулланыла: {url}" + +#: ../fdroidserver/__main__.py +msgid "Valid commands are:" +msgstr "Яраҡлы командалар:" + +#: ../fdroidserver/verify.py +msgid "Verify against locally cached copy rather than redownloading." +msgstr "Яңынан йөкмәү урынына локаль кешланған күсермәгә ҡаршы тикшереү." + +#: ../fdroidserver/__main__.py +msgid "Verify the integrity of downloaded packages" +msgstr "Йөкләнгән пакеттарҙың бөтөнлөгөн тикшереү" + +#: ../fdroidserver/index.py +msgid "Verifying index signature:" +msgstr "Индекс имзаһы тикшерелә:" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "Verifying package {path} with apksigner." +msgstr "{path} пакеты apksigner менән тикшерелә." + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." +msgstr "VirusTotal API асҡысы 32MB-тан ҙурыраҡ файлдарҙы йөкләй алмай, {path} файлын йөкләү өсөн {url} ҡулланығыҙ." + +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + +#: ../fdroidserver/__main__.py +msgid "Warn about possible metadata errors" +msgstr "Мөмкин булған мета-мәғлүмәт хаталары тураһында иҫкәртеү" + +#: ../fdroidserver/scanner.py +msgid "WebAssembly binary file" +msgstr "WebAssembly бинар файлы" + +#: ../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 "Бөтә репозиторийҙы линтлағанда yamllint стандарт буйынса һүндерелгән. Был опция yamllint-ты мәжбүри рәүештә эшләтә." + +#: ../fdroidserver/publish.py +msgid "When signing or verifying fails, exit with an error code." +msgstr "Тамғалау йәки тикшереү уңышһыҙ булһа, хата коды менән сығыу." + +#: ../fdroidserver/install.py +msgid "Would you like to download and install F-Droid.apk via adb? (YES/no)" +msgstr "F-Droid.apk-ны adb аша йөкләп ҡуйырға теләйһегеҙме? (ЭЙЕ/юҡ)" + +#: ../fdroidserver/install.py +msgid "Would you like to download the app(s) from f-droid.org? (YES/no)" +msgstr "Ҡушымта(лар)ҙы f-droid.org-тан йөкләргә теләйһегеҙме? (ЭЙЕ/юҡ)" + +#: ../fdroidserver/init.py +msgid "X.509 'Distinguished Name' used when generating keys" +msgstr "Асҡыстарҙы булдырғанда ҡулланылған X.509 'Айырым исем' (Distinguished Name)" + +#: ../fdroidserver/common.py +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 "ZIP файл архивы" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "adb reports {serial} is \"{status}\"!" +msgstr "adb хәбәр итә: {serial} — \"{status}\"!" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "adding IdentityFile to {path}" +msgstr "IdentityFile {path} юлына өҫтәлә" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "adding to {name}: {path}" +msgstr "{name}-ға өҫтәлә: {path}" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "ambiguous option: %(option)s could match %(matches)s" +msgstr "ике мәғәнәле опция: %(option)s %(matches)s-ҡа тап килеүе мөмкин" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "apksigner in build-tools;{version} passes APKs with invalid v3 signatures, ignoring." +msgstr "build-tools;{version} эсендәге apksigner дөрөҫ булмаған v3 имзалы APK-ларҙы үткәрә, иғтибарһыҙ ҡалдырыла." + +#: ../fdroidserver/common.py +msgid "apksigner not found! Cannot sign or verify modern APKs" +msgstr "apksigner табылманы! Заманса APK-ларҙы тамғалап йәки тикшереп булмай" + +#: ../fdroidserver/common.py +msgid "apksigner not found, it's required for signing!" +msgstr "apksigner табылманы, ул тамғалау өсөн кәрәк!" + +#. Translators: https://developer.android.com/build/configure-app-module#set-application-id +#: ../fdroidserver/checkupdates.py ../fdroidserver/lint.py +#: ../fdroidserver/rewritemeta.py +msgid "application ID of file to operate on" +msgstr "эшкәртеләсәк файлдың ҡушымта идентификаторы" + +#. Translators: https://developer.android.com/build/configure-app-module#set-application-id +#: ../fdroidserver/build.py ../fdroidserver/install.py +#: ../fdroidserver/publish.py ../fdroidserver/scanner.py +#: ../fdroidserver/verify.py +msgid "application ID with optional versionCode in the form APPID[:VERCODE]" +msgstr "ҡушымта идентификаторы, APPID[:VERCODE] рәүешендә versionCode өҫтәмә булыуы мөмкин" + +#: ../fdroidserver/common.py +msgid "archive_url needs to end with /archive" +msgstr "archive_url /archive менән тамамланырға тейеш" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "argument \"-\" with mode %r" +msgstr "%r режимлы \"-\" аргументы" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "argument %(argument_name)s: %(message)s" +msgstr "%(argument_name)s аргументы: %(message)s" + +#: ../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 "scrlib спецификацияһын танып булмай (юл түгел): '{}'" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "can't open '%(filename)s': %(error)s" +msgstr "'%(filename)s' асылманы: %(error)s" + +#: ../fdroidserver/scanner.py +msgid "can't open non-https url: '{};" +msgstr "https булмаған url-ды асып булмай: '{};" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "cannot find required srclibs: \"{path}\"" +msgstr "кәрәкле srclib-тар табылманы: \"{path}\"" + +#: /usr/lib/python3.11/argparse.py +msgid "cannot have multiple subparser arguments" +msgstr "бер нисә аҫпарсер аргументы була алмай" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "cannot merge actions - two groups are named %r" +msgstr "ғәмәлдәрҙе берләштереп булмай — ике төркөм %r тип аталған" + +#: ../fdroidserver/nightly.py +msgid "cannot publish update, did you set the deploy key?" +msgstr "яңыртыуҙы баҫтырып булмай, урынлаштырыу асҡысын күрһәттегеҙме?" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "cloning {url}" +msgstr "{url} клонлана" + +#: ../fdroidserver/__main__.py +msgid "commands from plugin modules:" +msgstr "плагин модулдәренән командалар:" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "conflicting option string: %s" +msgid_plural "conflicting option strings: %s" +msgstr[0] "ҡапма-ҡаршылыҡлы опция юлы: %s" +msgstr[1] "ҡапма-ҡаршылыҡлы опция юлдары: %s" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "conflicting subparser alias: %s" +msgstr "ҡапма-ҡаршылыҡлы аҫпарсер псевдонимы: %s" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "conflicting subparser: %s" +msgstr "ҡапма-ҡаршылыҡлы аҫпарсер: %s" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "could not parse '{path}'" +msgstr "'{path}' танылманы" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no name specified): '{}'" +msgstr "srclib спецификацияһын танып булманы (исем күрһәтелмәгән): '{}'" + +#: ../fdroidserver/common.py +msgid "could not parse srclib spec (no ref specified): '{}'" +msgstr "srclib спецификацияһын танып булманы (ref күрһәтелмәгән): '{}'" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "created {path}" +msgstr "{path} булдырылды" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "current version is newer: old vercode={old}, new vercode={new}" +msgstr "ағымдағы версия яңыраҡ: иҫке vercode={old}, яңы vercode={new}" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "deleting: repo/{apkfilename}" +msgstr "юйыла: repo/{apkfilename}" + +#: ../fdroidserver/scanner.py +msgid "dependency file without lock" +msgstr "йоҙаҡһыҙ бәйлелек файлы" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "deployed process log {path} to {dest}" +msgstr "эшкәртеү логы {path} {dest} адресына урынлаштырылды" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "dest= is required for options like %r" +msgstr "%r кеүек опциялар өсөн dest= кәрәк" + +#: ../fdroidserver/scanner.py +msgid "downloading '{}'" +msgstr "'{}' йөкләнә" + +#: ../fdroidserver/scanner.py +msgid "downloading scanner signatures from '{}' failed" +msgstr "сканлаусы имзаларын '{}' адресынан йөкләү уңышһыҙ булды" + +#: ../fdroidserver/scanner.py +msgid "executable binary, possibly code" +msgstr "башҡарылыусы бинар, код булыуы мөмкин" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "expected %s argument" +msgid_plural "expected %s arguments" +msgstr[0] "%s аргумент көтөлә" +msgstr[1] "%s аргумент көтөлә" + +#: /usr/lib/python3.11/argparse.py +msgid "expected at least one argument" +msgstr "кәмендә бер аргумент көтөлә" + +#: /usr/lib/python3.11/argparse.py +msgid "expected at most one argument" +msgstr "күп тигәндә бер аргумент көтөлә" + +#: /usr/lib/python3.11/argparse.py +msgid "expected one argument" +msgstr "бер аргумент көтөлә" + +#: ../fdroidserver/__main__.py +msgid "fdroid [] [-h|--help|--version|]" +msgstr "fdroid [<команда>] [-h|--help|--version|<аргументтар>]" + +#: ../fdroidserver/scanner.py +msgid "fetch the latest version of signatures from the web" +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 "git svn clone уңышһыҙ булды" + +#: ../fdroidserver/scanner.py +msgid "gzip file archive" +msgstr "gzip файл архивы" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "ignored explicit argument %r" +msgstr "асыҡтан-асыҡ %r аргументы иғтибарһыҙ ҡалдырылды" + +#: ../fdroidserver/index.py +msgid "index-v1 must have a signature, use `fdroid signindex` to create it!" +msgstr "index-v1 имзалы булырға тейеш, уны булдырыу өсөн `fdroid signindex` ҡулланығыҙ!" + +#: ../fdroidserver/index.py +msgid "index-v2 must have a signature, use `fdroid signindex` to create it!" +msgstr "index-v2 имзалы булырға тейеш, уны булдырыу өсөн `fdroid signindex` ҡулланығыҙ!" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "invalid %(type)s value: %(value)r" +msgstr "дөрөҫ булмаған %(type)s ҡиммәте: %(value)r" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "invalid choice: %(value)r (choose from %(choices)s)" +msgstr "дөрөҫ булмаған һайлау: %(value)r (%(choices)s араһынан һайлағыҙ)" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "invalid conflict_resolution value: %r" +msgstr "дөрөҫ булмаған conflict_resolution ҡиммәте: %r" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "invalid option string %(option)r: must start with a character %(prefix_chars)r" +msgstr "дөрөҫ булмаған %(option)r опция юлы: %(prefix_chars)r символы менән башланырға тейеш" + +#: ../fdroidserver/common.py +msgid "ipfs_cid not found, skipping CIDv1 generation" +msgstr "ipfs_cid табылманы, CIDv1 булдырыу үткәреп ебәрелә" + +#: ../fdroidserver/checkupdates.py +#, python-brace-format +msgid "latest build recipe is newer: old vercode={old}, new vercode={new}" +msgstr "һуңғы йыйыу рецебы яңыраҡ: иҫке vercode={old}, яңы vercode={new}" + +#: ../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/deploy.py +msgid "local_copy_dir must be an absolute path!" +msgstr "local_copy_dir абсолют юл булырға тейеш!" + +#: ../fdroidserver/deploy.py +msgid "local_copy_dir must be directory, not a file!" +msgstr "local_copy_dir каталог булырға тейеш, файл түгел!" + +#: ../fdroidserver/index.py +#, python-format +msgid "mirror '%s' does not end with 'fdroid'!" +msgstr "'%s' көҙгөһө 'fdroid' менән тамамланмай!" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "mirrors set twice, in config.yml and {path}!" +msgstr "көҙгөләр ике тапҡыр күрһәтелгән, config.yml-да һәм {path}-та!" + +#: /usr/lib/python3.11/argparse.py +msgid "mutually exclusive arguments must be optional" +msgstr "бер-береһен инҡар итеүсе аргументтар өҫтәмә булырға тейеш" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "next {name} cache update due in {time}" +msgstr "киләһе {name} кешын яңыртыу {time} аша" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "no \"icon\" in {appid}" +msgstr "{appid}-та \"icon\" юҡ" + +#: ../fdroidserver/signatures.py +msgid "no APK supplied" +msgstr "APK бирелмәгән" + +#: ../fdroidserver/checkupdates.py +msgid "no version information found" +msgstr "версия тураһында мәғлүмәт табылманы" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "not allowed with argument %s" +msgstr "%s аргументы менән рөхсәт ителмәй" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "one of the arguments %s is required" +msgstr "%s аргументтарының береһе кәрәк" + +#: ../fdroidserver/common.py ../fdroidserver/index.py +msgid "only accepts strings, lists, and tuples" +msgstr "тик юлдарҙы, исемлектәрҙе һәм кортеждарҙы ғына ҡабул итә" + +#: /usr/lib/python3.11/argparse.py +msgid "options" +msgstr "опциялар" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "overwriting existing {path}" +msgstr "инде булған {path} өҫтөнән яҙыла" + +#: /usr/lib/python3.11/argparse.py +msgid "positional arguments" +msgstr "позицион аргументтар" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "process log deploy {path} to {dest} failed!" +msgstr "эшкәртеү логын {path} {dest} адресына урынлаштырыу уңышһыҙ булды!" + +#: ../fdroidserver/build.py +msgid "reference binary missing signature" +msgstr "өлгө бинарҙың имзаһы юҡ" + +#: ../fdroidserver/signatures.py +#, python-brace-format +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 \"repo/icons/%s\" does not exist, generating placeholder." +msgstr "\"repo/icons/%s\" repo_icon-ы юҡ, ҡалып булдырыла." + +#: ../fdroidserver/common.py +msgid "repo_url needs to end with /repo" +msgstr "repo_url /repo менән тамамланырға тейеш" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "rsync is missing or broken: {error}" +msgstr "rsync юҡ йәки боҙолған: {error}" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "s3cmd sync indexes {path} to {url} and delete" +msgstr "s3cmd индекстарҙы {path}-тан {url}-ға синхронлаштыра һәм юя" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "s3cmd syncs indexes from {path} to {url} and deletes removed" +msgstr "s3cmd индекстарҙы {path}-тан {url}-ға синхронлаштыра һәм юйылғандарҙы юя" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "scanner cache is malformed! You can clear it with: '{clear}'" +msgstr "сканлаусы кешы боҙолған! Уны былай таҙартырға мөмкин: '{clear}'" + +#: ../fdroidserver/deploy.py +msgid "serverwebroot: path does not end with \"fdroid\", perhaps you meant one of these:" +msgstr "serverwebroot: юл \"fdroid\" менән тамамланмай, бәлки һеҙ быларҙың береһен күҙ уңында тоттоғоҙ:" + +#: ../fdroidserver/scanner.py +msgid "shared library" +msgstr "уртаҡ китапхана" + +#: /usr/lib/python3.11/argparse.py +msgid "show this help message and exit" +msgstr "был ярҙам хәбәрен күрһәтеү һәм сығыу" + +#: ../fdroidserver/signatures.py +msgid "signed APK, either a file-path or HTTPS URL." +msgstr "тамғаланған APK, файл юлы йәки HTTPS URL-ы." + +#: ../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 "сығанаҡ tarball үткәреп ебәрелә: {path}" + +#: ../fdroidserver/lint.py +msgid "srclibs missing name and/or @" +msgstr "srclibs-та исем һәм/йәки @ юҡ" + +#: ../fdroidserver/scanner.py +msgid "static library" +msgstr "статик китапхана" + +#: ../fdroidserver/build.py +#, python-brace-format +msgid "supplied reference binary has allowed signer {signer}" +msgstr "бирелгән өлгө бинарҙың рөхсәт ителгән имзалаусыһы {signer} бар" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "the following arguments are required: %s" +msgstr "түбәндәге аргументтар мотлаҡ: %s" + +#: ../fdroidserver/install.py +msgid "true" +msgstr "дөрөҫ" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "unexpected option string: %s" +msgstr "көтөлмәгән опция юлы: %s" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "unknown parser %(parser_name)r (choices: %(choices)s)" +msgstr "билдәһеҙ парсер %(parser_name)r (һайлау варианттары: %(choices)s)" + +#: /usr/lib/python3.11/argparse.py +#, python-format +msgid "unrecognized arguments: %s" +msgstr "танылмаған аргументтар: %s" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "unsafe permissions on '{config_file}' (should be 0600)!" +msgstr "'{config_file}' өсөн хәүефле рөхсәттәр (0600 булырға тейеш)!" + +#: ../fdroidserver/__main__.py /usr/lib/python3.11/argparse.py +msgid "usage: " +msgstr "ҡулланыу: " + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "using Apache libcloud to sync with {url}" +msgstr "{url} менән синхронлаштырыу өсөн Apache libcloud ҡулланыла" + +#: ../fdroidserver/deploy.py +msgid "virustotal.com is rate limiting, waiting to retry..." +msgstr "virustotal.com сикләү ҡуйҙы, ҡабатлап ҡарау өсөн көтөлә..." + +#: ../fdroidserver/install.py +msgid "yes" +msgstr "эйе" + +#: ../fdroidserver/publish.py +#, python-brace-format +msgid "{0} app, {1} key aliases" +msgid_plural "{0} apps, {1} key aliases" +msgstr[0] "{0} ҡушымта, {1} асҡыс псевдонимы" +msgstr[1] "{0} ҡушымта, {1} асҡыс псевдонимы" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename} ({appid}) has no metadata!" +msgstr "{apkfilename} ({appid}) өсөн мета-мәғлүмәт юҡ!" + +#. Translators: https://developer.android.com/build/configure-app-module#set-application-id +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{apkfilename}'s AndroidManifest.xml has a bad date: " +msgstr "{apkfilename}-ның AndroidManifest.xml-ында дөрөҫ булмаған дата: " + +#. Translators: https://developer.android.com/build/configure-app-module#set-application-id +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} does not have a name! Using application ID instead." +msgstr "{appid} өсөн исем юҡ! Уның урынына ҡушымта идентификаторы ҡулланыла." + +#. Translators: https://developer.android.com/build/configure-app-module#set-application-id +#: ../fdroidserver/update.py +#, python-brace-format +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!" +msgstr "{path} эсендәге {appid} — дөрөҫ Java пакет исеме түгел!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{appid} has both APKs and files: {files}" +msgstr "{appid}-та APK-лар ҙа, файлдар ҙа бар: {files}" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{appid} is missing {name}" +msgstr "{appid}-та {name} юҡ" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: Unknown extlib {path} in build '{versionName}'" +msgstr "{appid}: '{versionName}' йыйылмаһында билдәһеҙ extlib {path}" + +#: ../fdroidserver/scanner.py +#, python-brace-format +msgid "{appid}: no builds specified, running on current source state" +msgstr "{appid}: йыйылмалар күрһәтелмәгән, ағымдағы сығанаҡ хәлендә эшләтелә" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{appid}: {field} must be a '{type}', but it is a '{fieldtype}!'" +msgstr "{appid}: {field} '{type}' булырға тейеш, ләкин ул '{fieldtype}'!" + +#: ../fdroidserver/lint.py +#, python-brace-format +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 "{build_flag} бөтөн һан булырға тейеш, табылды: {value}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{build_flag} must be list or string, found: {value}" +msgstr "{build_flag} исемлек йәки юл булырға тейеш, табылды: {value}" + +#: ../fdroidserver/metadata.py +#, python-brace-format +msgid "{file} is blank or corrupt!" +msgstr "{file} буш йәки боҙолған!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{name} \"{section}/icons/{path}\" does not exist! Check \"config.yml\"." +msgstr "{name} \"{section}/icons/{path}\" юҡ! \"config.yml\"-ды тикшерегеҙ." + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path1} is a duplicate of {path2}, remove one!" +msgstr "{path1} — {path2}-нең күсермәһе, береһен юйығыҙ!" + +#: ../fdroidserver/import_subcommand.py +#, python-brace-format +msgid "{path} already exists, ignoring import results!" +msgstr "{path} инде бар, импорт һөҙөмтәләре иғтибарһыҙ ҡалдырыла!" + +#: ../fdroidserver/nightly.py +#, python-brace-format +msgid "{path} does not exist! Create it by running:" +msgstr "{path} юҡ! Уны булдырыу өсөн эшләтегеҙ:" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" +msgstr "{path} файлының имзаһы дөрөҫ түгел \"{pattern}\", Janus эксплойты булыуы мөмкин!" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "{path} has been flagged by virustotal {count} times:" +msgstr "{path} virustotal тарафынан {count} тапҡыр билдәләнгән:" + +#: ../fdroidserver/install.py +#, python-brace-format +msgid "{path} has the wrong fingerprint ({fingerprint})!" +msgstr "{path} файлының бармаҡ эҙе дөрөҫ түгел ({fingerprint})!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{path} is not \"key: value\" dict, but a {datatype}!" +msgstr "{path} — \"key: value\" һүҙлеге түгел, ә {datatype}!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{path} is not a standard config file!" +msgstr "{path} — стандарт конфигурация файлы түгел!" + +#: ../fdroidserver/index.py +#, python-brace-format +msgid "{path} is not list, but a {datatype}!" +msgstr "{path} — исемлек түгел, ә {datatype}!" + +#: ../fdroidserver/common.py +#, python-brace-format +msgid "{path} is not {expected_type}, but a {datatype}!" +msgstr "{path} — {expected_type} түгел, ә {datatype}!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path} is zero size!" +msgstr "{path} үлсәме нуль!" + +#: ../fdroidserver/deploy.py +#, python-brace-format +msgid "{path} more than 200MB, manually upload: {url}" +msgstr "{path} 200MB-тан ҙурыраҡ, ҡулдан йөкләү: {url}" + +#: ../fdroidserver/lint.py +#, python-brace-format +msgid "{path}: \"{code}\" is not a valid ISO_3166-1 alpha-2 country code!" +msgstr "{path}: \"{code}\" — дөрөҫ ISO_3166-1 alpha-2 ил коды түгел!" + +#: ../fdroidserver/update.py +#, python-brace-format +msgid "{path}: {error}" +msgstr "{path}: {error}" + +#: ../fdroidserver/mirror.py +#, python-brace-format +msgid "{url} does not end with \"fdroid\", check the URL path!" +msgstr "{url} \"fdroid\" менән тамамланмай, URL юлын тикшерегеҙ!" + +#: ../fdroidserver/import_subcommand.py +#, python-brace-format +msgid "{url} does not start with \"http\"!" +msgstr "{url} \"http\" менән башланмай!" + +#: ../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] "{} йыйыу уңышлы булды" diff --git a/locale/be/LC_MESSAGES/fdroidserver.po b/locale/be/LC_MESSAGES/fdroidserver.po index bab918a4..9526f6ea 100644 --- a/locale/be/LC_MESSAGES/fdroidserver.po +++ b/locale/be/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.2.1-143-g1a5ee449\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-01-21 00:08+0000\n" "Last-Translator: flac \n" "Language-Team: Belarusian \n" @@ -358,6 +358,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1483,6 +1488,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Перайменуйце файлы APK, якія не адпавядаюць package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1996,6 +2006,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Папярэджваць аб магчымых памылках метададзеных" diff --git a/locale/bg/LC_MESSAGES/fdroidserver.po b/locale/bg/LC_MESSAGES/fdroidserver.po index bc6bff77..bbcbc06a 100644 --- a/locale/bg/LC_MESSAGES/fdroidserver.po +++ b/locale/bg/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.1b0\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-07-19 10:21+0000\n" "Last-Translator: 109247019824 \n" "Language-Team: Bulgarian \n" @@ -354,6 +354,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1479,6 +1484,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1992,6 +2002,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/bn/LC_MESSAGES/fdroidserver.po b/locale/bn/LC_MESSAGES/fdroidserver.po index fa057130..44e14abf 100644 --- a/locale/bn/LC_MESSAGES/fdroidserver.po +++ b/locale/bn/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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2021-02-12 09:48+0000\n" "Last-Translator: Oymate \n" "Language-Team: Bengali \n" @@ -353,6 +353,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1478,6 +1483,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1991,6 +2001,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/bo/LC_MESSAGES/fdroidserver.po b/locale/bo/LC_MESSAGES/fdroidserver.po index 3f892a0e..cbd1c63c 100644 --- a/locale/bo/LC_MESSAGES/fdroidserver.po +++ b/locale/bo/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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-04-10 13:33+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Tibetan \n" @@ -358,6 +358,11 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "ཚགས་རྒྱབ་པའི་སྐབས་སུ་ནོར་སྐྱོན་ {} ཤོར་བས་བཟོ་སྐྲུན་བྱེད་ཐུབ་མེད།" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "ཀློག་མི་ཐུབ།{path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1499,6 +1504,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "package.name_123.apk དང་མི་འདྲ་བའི་APK ཡིག་ཆ་དེ་ཚོར་མིང་སྐྱར་ཏུ་བཏགས།" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, fuzzy, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2015,6 +2025,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "ཡིག་ཚགས་ཀྱི་རྒྱབ་ལྗོངས་ལོ་རྒྱུས་སྐྱོན་སྲིད་པ་རྣམས་པ་ཉེན་བརྡ་གཏོང་།" diff --git a/locale/ca/LC_MESSAGES/fdroidserver.po b/locale/ca/LC_MESSAGES/fdroidserver.po index d7bdddfb..48cea1fc 100644 --- a/locale/ca/LC_MESSAGES/fdroidserver.po +++ b/locale/ca/LC_MESSAGES/fdroidserver.po @@ -6,21 +6,21 @@ # Adrià Martín , 2024. # unmes , 2024. # Joan Pujolar , 2024. -# Ecron , 2024. +# Ecron , 2024, 2025. msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.1-273-g54e84d87\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-01-30 12:31+0000\n" -"Last-Translator: pitroig \n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-05-16 16:36+0000\n" +"Last-Translator: Ecron \n" "Language-Team: Catalan \n" "Language: ca\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 5.10-dev\n" +"X-Generator: Weblate 5.12-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -46,7 +46,7 @@ msgstr "\"%s/\" no té cap fitxer de metadades coincidents!" #: ../fdroidserver/index.py msgid "\"isPrimary\" key should not be added to mirrors!" -msgstr "" +msgstr "La clau «isPrimary» no s'hauria d'afegir a les rèpliques!" #: ../fdroidserver/index.py #, python-brace-format @@ -307,7 +307,7 @@ msgstr "Sí automàtic a totes les demandes." #: ../fdroidserver/index.py #, python-brace-format msgid "Bad entry type \"{mirrortype}\" in mirrors config: {mirror}" -msgstr "Tipus d'entrada incorrecta \"{mirrortype}\" a la configuració de miralls: {mirror}" +msgstr "Tipus d'entrada incorrecta «{mirrortype}» a la configuració de les rèpliques: {mirror}" #: ../fdroidserver/mirror.py msgid "Base URL to mirror, can include the index signing key using the query string: ?fingerprint=" @@ -363,6 +363,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "No es pot construir a causa d'un error {} en escanejar" msgstr[1] "No es pot construir a causa d'errors {} en escanejar" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "No s'ha pogut llegir {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -485,9 +490,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "S'està creant \"{path}\" per configurar s3cmd." #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "S'està llegint '{config_file}'" +msgstr "S'està creant un «{config_file}» buit" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -535,7 +540,7 @@ msgstr "S'està suprimint l'arxiu, el dipòsit és massa gran ({size} màxim {li #: ../fdroidserver/deploy.py #, python-brace-format msgid "Deleting git-mirror history, repo is too big ({size} max {limit})" -msgstr "S'està suprimint l'historial del mirall de git, el dipòsit és massa gran ({size} màxim {limit})" +msgstr "S'està suprimint l'historial git-mirror, el dipòsit és massa gran ({size}, màxim {limit})" #: ../fdroidserver/update.py #, python-brace-format @@ -601,7 +606,7 @@ msgstr "No usis les sumes de verificació \"rsync\"" #: ../fdroidserver/install.py msgid "Download F-Droid.apk using mirrors that leak less to the network" -msgstr "Baixeu l'F-Droid.apk amb els miralls que filtren menys dades a la xarxa" +msgstr "Baixeu l'F-Droid.apk amb les rèpliques que filtren menys dades a la xarxa" #: ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" @@ -657,12 +662,12 @@ msgstr "ERROR: {key} a {path} no és \"arxiu\" o \"dipòsit\"!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key} not a valid key!" -msgstr "" +msgstr "ERROR: {key} no és una clau vàlida!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key}'s value should be of type {t}!" -msgstr "" +msgstr "ERROR: el valor de {key} hauria de ser del tipus {t}!" #: ../fdroidserver/lint.py #, python-brace-format @@ -689,9 +694,9 @@ msgid "Environment variable {var} from {configname} is not set!" msgstr "La variable d'entorn {var} de {configname} no està establerta!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment variable {{env: {var}}} is not set!" -msgstr "La variable d'entorn {var} de {configname} no està establerta!" +msgstr "La variable d'entorn {{env: {var}}} no està establerta!" #: ../fdroidserver/deploy.py msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" @@ -933,9 +938,9 @@ msgid "Ignoring bad element in manifest: %s" msgstr "S'ignorarà l'element incorrecte al manifest: %s" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Ignoring deprecated {oldfile}, use {newfile}!" -msgstr "{oldfile} és obsolet, utilitzeu {newfile}" +msgstr "S'ignorarà el {oldfile} obsolet, utilitzeu {newfile}!" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -956,11 +961,11 @@ msgstr "Inclou els fitxers .asc de signatura PGP a la rèplica" #: ../fdroidserver/mirror.py msgid "Include the build logs in the mirror" -msgstr "Inclou els registres de construcció al mirall" +msgstr "Inclou els registres de construcció en la rèplica" #: ../fdroidserver/mirror.py msgid "Include the source tarballs in the mirror" -msgstr "Inclou els arxius tar d'origen al mirall" +msgstr "Inclou els fitxers tarball del codi font en la rèplica" #: ../fdroidserver/metadata.py #, python-format @@ -1143,7 +1148,7 @@ msgstr "S'ha arribat a la profunditat màxima de recursivitat en el fitxer ZIP: #: ../fdroidserver/index.py #, python-brace-format msgid "Mirror config for {url} contains \"isPrimary\" key!" -msgstr "" +msgstr "La configuració de la rèplica per a {url} conté la clau «isPrimary»!" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." @@ -1287,7 +1292,7 @@ msgstr "El nom del paquet de l'OBB no coincideix amb un APK compatible:" #: ../fdroidserver/deploy.py msgid "Offline machine, skipping git mirror generation until `fdroid deploy`" -msgstr "Màquina fora de línia, s'ometrà la generació del mirall git fins al `fdroid deploy`" +msgstr "Màquina fora de línia, s'ometrà la generació de la rèplica git fins al `fdroid deploy`" #: ../fdroidserver/deploy.py msgid "One of the 'github_releases' config items is missing the 'packageNames' value. skipping ..." @@ -1310,7 +1315,7 @@ msgstr "Només s'admeten PNG i JPEG per als gràfics, s'ha trobat: {path}" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Only accepts a single key \"env\"" -msgstr "" +msgstr "Només accepta una clau única «env»" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" @@ -1471,7 +1476,7 @@ msgstr "Actualitza i cau les regles de l'escàner i les signatures de la xarxa" #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "No se signarà «{path}», el fitxer existeix a les dues carpetes {dir1} i {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1490,6 +1495,11 @@ msgstr "S'està suprimint {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Canvia el nom dels fitxers APK que no coincideixin amb package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1699,7 +1709,7 @@ msgstr "Mode de prova: posa la sortida només al directori tmp, i sempre constru #: ../fdroidserver/index.py msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" -msgstr "" +msgstr "No s'ha instal·lat el paquet de Python «qrcode» (p. ex. apt-get install python3-qrcode)!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -2010,6 +2020,10 @@ msgstr "S'està verificant el paquet {path} l'apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "La clau de l'API VirusTotal no pot pujar fitxers més grans de 32 MB, utilitzeu {url} per pujar {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avisa de possibles errors a les metadades" @@ -2322,12 +2336,12 @@ msgstr "local_copy_dir ha de ser directori, no un fitxer!" #: ../fdroidserver/index.py #, python-format msgid "mirror '%s' does not end with 'fdroid'!" -msgstr "el mirall '%s' no acaba amb 'fdroid'!" +msgstr "La rèplica «%s» no acaba amb «fdroid»!" #: ../fdroidserver/index.py #, python-brace-format msgid "mirrors set twice, in config.yml and {path}!" -msgstr "miralls establerts dues vegades, a config.yml i {path}!" +msgstr "rèpliques establertes dues vegades, a config.yml i {path}!" #: /usr/lib/python3.11/argparse.py msgid "mutually exclusive arguments must be optional" @@ -2597,7 +2611,7 @@ msgstr "{name} \"{section}/icons/{path}\" no existeix! Comproveu \"config.yml\". #: ../fdroidserver/update.py #, python-brace-format msgid "{path1} is a duplicate of {path2}, remove one!" -msgstr "" +msgstr "{path1} és un duplicat de {path2}, elimineu-ne un!" #: ../fdroidserver/import_subcommand.py #, python-brace-format diff --git a/locale/cs/LC_MESSAGES/fdroidserver.po b/locale/cs/LC_MESSAGES/fdroidserver.po index 2c95ed17..351d8885 100644 --- a/locale/cs/LC_MESSAGES/fdroidserver.po +++ b/locale/cs/LC_MESSAGES/fdroidserver.po @@ -13,8 +13,8 @@ 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: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-20 16:21+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-03-26 10:00+0000\n" "Last-Translator: Fjuro \n" "Language-Team: Czech \n" "Language: cs\n" @@ -366,6 +366,11 @@ msgstr[0] "Nelze sestavit kvůli {} chybě při skenování" msgstr[1] "Nelze sestavit kvůli {} chybám při skenování" msgstr[2] "Nelze sestavit kvůli {} chybám při skenování" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Chyba při čtení {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1474,7 +1479,7 @@ msgstr "Obnovit a uložit pravidla a podpisy skeneru ze sítě do mezipaměti" #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Odmítám podespat „{path}“, soubor existuje ve složce {dir1} i {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1493,6 +1498,11 @@ msgstr "Odebírání {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Přejmenovat soubory APK, které se neshodují s package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2014,6 +2024,10 @@ msgstr "Ověřování balíčku {path} pomocí apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "Klíč API VirusTotal neumožňuje nahrávání souborů větších než 32 MB, k nahrání {path} použijte {url}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Varovat ohledně možných chyb metadat" diff --git a/locale/cy/LC_MESSAGES/fdroidserver.po b/locale/cy/LC_MESSAGES/fdroidserver.po index 37648a7b..8451062c 100644 --- a/locale/cy/LC_MESSAGES/fdroidserver.po +++ b/locale/cy/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.0a5-27-gf24eae0f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2021-01-16 21:23+0000\n" "Last-Translator: Aled Powell \n" "Language-Team: Welsh \n" @@ -357,6 +357,11 @@ msgstr[3] "" msgstr[4] "" msgstr[5] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1482,6 +1487,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Ailenwi ffeiliau APK na sy'n dilyn y ffurf package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2006,6 +2016,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Rhybuddio am wallau metaddata posib" diff --git a/locale/de/LC_MESSAGES/fdroidserver.po b/locale/de/LC_MESSAGES/fdroidserver.po index 98b0aed3..5dde0e8f 100644 --- a/locale/de/LC_MESSAGES/fdroidserver.po +++ b/locale/de/LC_MESSAGES/fdroidserver.po @@ -13,21 +13,21 @@ # TobiGr , 2021. # FW , 2021. # fossdd , 2021. -# Ceeee , 2021. +# Ceeee , 2021, 2025. # C. Rüdinger , 2021, 2022. # VfBFan , 2021, 2023, 2024, 2025. # Roman Leo , 2021. # Follpvosten , 2021. # ssantos , 2022, 2023, 2024. -# "C. Rüdinger" , 2023. +# "C. Rüdinger" , 2023, 2025. # VfBFan , 2024. # Maxi , 2024. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-21 08:45+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-04-29 10:16+0000\n" "Last-Translator: VfBFan \n" "Language-Team: German \n" "Language: de\n" @@ -35,7 +35,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 5.11-dev\n" +"X-Generator: Weblate 5.12-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -378,6 +378,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Lesen von {path} fehlgeschlagen: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -519,7 +524,7 @@ msgstr "Erstelle Ausgabeverzeichnis" #: ../fdroidserver/index.py msgid "Creating signed index with this key (SHA256):" -msgstr "Signierter Index mit diesem Schlüssel (SHA256) wird erstellt:" +msgstr "Signierter Index wird mit diesem Schlüssel (SHA256) erstellt:" #: ../fdroidserver/publish.py ../fdroidserver/verify.py msgid "Creating temporary directory" @@ -532,7 +537,7 @@ msgstr "Unsignierter Index zur Vorbereitung der Signierung wird erstellt" #: ../fdroidserver/lint.py #, python-brace-format msgid "CurrentVersionCode {cv} is less than oldest build entry {versionCode}" -msgstr "CurrentVersionCode {cv} ist kleiner als der älteste Build-Eintrag {versionCode}" +msgstr "CurrentVersionCode {cv} ist niedriger als ältester Build-Eintrag {versionCode}" #: ../fdroidserver/nightly.py msgid "DEBUG_KEYSTORE is not set or the value is incomplete" @@ -866,7 +871,7 @@ msgstr "Ungültige Datei bei %s gefunden" #: ../fdroidserver/deploy.py #, python-brace-format msgid "Found {apkfilename} at {url}" -msgstr "{apkfilename} unter {url} gefunden" +msgstr "{apkfilename} gefunden auf {url}" #: ../fdroidserver/scanner.py #, python-brace-format @@ -930,7 +935,7 @@ msgstr "Wenn ein Git-Mirror zu groß wird, erlaube dem Archiv gelöscht zu werde #: ../fdroidserver/deploy.py #, python-brace-format msgid "If this upload fails, try manually uploading to {url}" -msgstr "Wenn das Hochladen fehlschlägt, versuchen Sie es händisch auf {url} hochzuladen" +msgstr "Wenn das Hochladen fehlschlägt, versuchen Sie ihn manuell auf {url} hochzuladen" #: ../fdroidserver/metadata.py #, python-brace-format @@ -1337,7 +1342,7 @@ msgstr "OpenCollective-Spendenmethoden gehören in das OpenCollective: Feld" #: ../fdroidserver/verify.py msgid "Output JSON report to file named after APK." -msgstr "JSON-Bericht in eine nach der APK benannte Datei ausgeben." +msgstr "In Datei ausgegebener JSON-Bericht wird nach APK benannt." #: ../fdroidserver/scanner.py msgid "Output JSON to stdout." @@ -1486,7 +1491,7 @@ msgstr "Aktualisieren und Zwischenspeichern von Scannerregeln und Signaturen aus #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Eintragen von '{path}' abgelehnt, Datei ist sowohl in Ordner {dir1} als auch {dir2} vorhanden." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1505,6 +1510,11 @@ msgstr "Entferne {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "APK-Dateien umbenennen, die nicht dem Muster „package.name_123.apk“ entsprechen" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1557,7 +1567,7 @@ msgstr "Ausführen von wget in {path}" #: ../fdroidserver/index.py #, python-brace-format msgid "SHA-256 of {url} does not match entry!" -msgstr "SHA-256 von {url} stimmt nicht mit Eintrag überein!" +msgstr "SHA-256 der {url} stimmt nicht mit Eintrag überein!" #: ../fdroidserver/build.py msgid "Scan the resulting APK(s) for known non-free classes." @@ -1607,7 +1617,7 @@ msgstr "Einstellen der Uhr auf diese Zeit mit:" #: ../fdroidserver/nightly.py msgid "Set maximum releases in repo before older ones are archived" -msgstr "Setze maximale Veröffentlichungen im Repo bevor ältere archiviert werden" +msgstr "Setze maximale Veröffentlichungen im Repo, bevor ältere archiviert werden" #: ../fdroidserver/build.py #, python-brace-format @@ -1757,7 +1767,7 @@ msgstr "Dieser Befehl sollte niemals verwendet werden, um f-droid.org zu spiegel #: ../fdroidserver/common.py msgid "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/fdroid." -msgstr "Dies ist eine Paketquelle für Anwendungen, die für die Benutzung zusammen mit F-Droid gedacht ist. Die darin enthaltenen Anwendungen sind entweder offizielle von den Entwicklern erstellte Binärdateien oder werden von f-droid.org mithilfe des Werkzeugs auf https://gitlab.com/fdroid aus dem Quellcode erstellt." +msgstr "Dies ist eine Paketquelle für Anwendungen, die für die Benutzung zusammen mit F-Droid gedacht ist. Die darin enthaltenen Anwendungen sind entweder offizielle von den Entwicklern erstellte Binärdateien oder werden von f-droid.org mithilfe der Werkzeuge auf https://gitlab.com/fdroid aus dem Quellcode erstellt." #: ../fdroidserver/import_subcommand.py #, python-format @@ -1973,7 +1983,7 @@ msgstr "Verwende APK-Signatur v3" #: ../fdroidserver/common.py msgid "Using JAR Signature" -msgstr "Verwende JAR Signatur" +msgstr "Verwende JAR-Signatur" #: ../fdroidserver/common.py msgid "Using Java's jarsigner, not recommended for verifying APKs! Use apksigner" @@ -2025,6 +2035,10 @@ msgstr "Überprüfen des Pakets {path} mit apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "VirusTotal-API-Schlüssel kann nicht Dateien größer 32MB hochladen, verwende {url} um {path} hochzuladen." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Vor möglichen Metadaten-Fehlern warnen" @@ -2154,7 +2168,7 @@ msgstr "Mehrere Subparser-Argumente sind unzulässig" #: /usr/lib/python3.11/argparse.py #, python-format msgid "cannot merge actions - two groups are named %r" -msgstr "kann keine Aktionen zusammenführen - zwei Gruppen heißen %r" +msgstr "kann keine Aktionen zusammenführen – zwei Gruppen heißen %r" #: ../fdroidserver/nightly.py msgid "cannot publish update, did you set the deploy key?" @@ -2528,8 +2542,8 @@ msgstr "ja" #, python-brace-format msgid "{0} app, {1} key aliases" msgid_plural "{0} apps, {1} key aliases" -msgstr[0] "{0} app, {1} Schlüsselaliase" -msgstr[1] "{0} apps, {1} Schlüsselaliase" +msgstr[0] "{0} App, {1} Schlüssel-Aliase" +msgstr[1] "{0} Apps, {1} Schlüssel-Aliase" #: ../fdroidserver/update.py #, python-brace-format @@ -2557,7 +2571,7 @@ msgstr "{appid} von {path} ist keine gültige Android-Anwendungs-ID!" #: ../fdroidserver/metadata.py ../fdroidserver/update.py #, python-brace-format msgid "{appid} from {path} is not a valid Java Package Name!" -msgstr "{appid} von {path} ist kein gültiger Java-Paketname!" +msgstr "{appid} aus {path} ist kein gültiger Java-Paketname!" #: ../fdroidserver/update.py #, python-brace-format @@ -2577,7 +2591,7 @@ msgstr "{appid}: unbekannte Extlib {path} im Build '{versionName}'" #: ../fdroidserver/scanner.py #, python-brace-format msgid "{appid}: no builds specified, running on current source state" -msgstr "{appid}: keine builds angegeben, läuft auf dem aktuellen source-Stand" +msgstr "{appid}: Kein Build angegeben; verwende aktuellen Quellen-Stand" #: ../fdroidserver/lint.py #, python-brace-format @@ -2627,7 +2641,7 @@ msgstr "{path} existiert nicht! Erstellen Sie es durch Ausführen von:" #: ../fdroidserver/update.py #, python-brace-format msgid "{path} has bad file signature \"{pattern}\", possible Janus exploit!" -msgstr "{path} hat die schlechte Dateisignatur \"{pattern}\", möglicher Janus-Exploit!" +msgstr "{path} hat falsche Dateisignatur \"{pattern}\", möglicher Janus-Exploit!" #: ../fdroidserver/deploy.py #, python-brace-format diff --git a/locale/el/LC_MESSAGES/fdroidserver.po b/locale/el/LC_MESSAGES/fdroidserver.po index 13380be3..5bd92c4a 100644 --- a/locale/el/LC_MESSAGES/fdroidserver.po +++ b/locale/el/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.0a0-62-gc63c4b3d\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-05-10 13:24+0000\n" "Last-Translator: ΣΤΑΥΡΟΣ ΔΑΛΙΑΚΟΠΟΥΛΟΣ \n" "Language-Team: Greek \n" @@ -360,6 +360,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1485,6 +1490,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Μετονομασία αρχείων APK που δεν αντιστοιχούν με «όνομα.πακέτου_123.apk»" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1998,6 +2008,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Προειδοποίηση για πιθανά σφάλματα μετα-δεδομένων" diff --git a/locale/es/LC_MESSAGES/fdroidserver.po b/locale/es/LC_MESSAGES/fdroidserver.po index f01ed699..64a43a1c 100644 --- a/locale/es/LC_MESSAGES/fdroidserver.po +++ b/locale/es/LC_MESSAGES/fdroidserver.po @@ -14,20 +14,21 @@ # Jaime Marquínez Ferrándiz , 2022. # gallegonovato , 2022, 2023, 2024. # Nicolás Pérez , 2025. +# Swyter , 2025. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-16 22:47+0000\n" -"Last-Translator: Nicolás Pérez \n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-06-24 11:02+0000\n" +"Last-Translator: Swyter \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 5.11-dev\n" +"X-Generator: Weblate 5.13-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -370,6 +371,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Fallo al leer {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -492,9 +498,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Creando \"{path}\" para configurar s3cmd." #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "Leyendo '{config_file}'" +msgstr "Creando el archivo vacío {config_file}" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -1497,6 +1503,11 @@ msgstr "Eliminando {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Cambiar el nombre de archivos APK que no coinciden con el formato package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1811,7 +1822,7 @@ msgstr "Entrada desconocida {key} en {configname}" #: ../fdroidserver/__main__.py msgid "Unknown exception found!" -msgstr "¡Se encontró una excepción desconocida!" +msgstr "Se ha producido una excepción desconocida" #: ../fdroidserver/lint.py #, python-brace-format @@ -1993,7 +2004,7 @@ msgstr "Usando s3cmd para sincronizar con: {url}" #: ../fdroidserver/__main__.py msgid "Valid commands are:" -msgstr "Los comandos válidos son:" +msgstr "Las órdenes válidas son:" #: ../fdroidserver/verify.py msgid "Verify against locally cached copy rather than redownloading." @@ -2017,6 +2028,10 @@ msgstr "Verificando el paquete {path} con apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "La clave de API de VirusTotal no puede subir archivos mayores de 32MB. Use {url} para subir {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Alertar sobre posibles errores de metadatos" diff --git a/locale/es_AR/LC_MESSAGES/fdroidserver.po b/locale/es_AR/LC_MESSAGES/fdroidserver.po index f6e544a1..a15ddd81 100644 --- a/locale/es_AR/LC_MESSAGES/fdroidserver.po +++ b/locale/es_AR/LC_MESSAGES/fdroidserver.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2021-04-10 21:26+0000\n" "Last-Translator: Germe the fur star \n" "Language-Team: Spanish (Argentina) \n" @@ -361,6 +361,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "No se pudo empaquetar debido al {} error mientras se escaneaba" msgstr[1] "No se pudo empaquetar debido a los {} errores mientras se escaneaba" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "No se puede reescribir \"{path}\"" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1495,6 +1500,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Renombrar archivos APK que no corresponden a package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2008,6 +2018,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Advertir sobre posibles errores en los metadatos" diff --git a/locale/es_MX/LC_MESSAGES/fdroidserver.po b/locale/es_MX/LC_MESSAGES/fdroidserver.po index 344bf130..aaddd007 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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2020-04-29 12:49+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Spanish (Mexico) \n" @@ -354,6 +354,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1483,6 +1488,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1996,6 +2006,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/eu/LC_MESSAGES/fdroidserver.po b/locale/eu/LC_MESSAGES/fdroidserver.po index 8d6c69b4..4cb555c2 100644 --- a/locale/eu/LC_MESSAGES/fdroidserver.po +++ b/locale/eu/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.0a0-62-gc63c4b3d\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -352,6 +352,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1477,6 +1482,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1990,6 +2000,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/fa/LC_MESSAGES/fdroidserver.po b/locale/fa/LC_MESSAGES/fdroidserver.po index d8aad95a..ff34a457 100644 --- a/locale/fa/LC_MESSAGES/fdroidserver.po +++ b/locale/fa/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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-11-26 15:16+0000\n" "Last-Translator: Danial Behzadi \n" "Language-Team: Persian \n" @@ -356,6 +356,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "{path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1481,6 +1486,11 @@ msgstr "برداشتن {path}" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1994,6 +2004,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/fdroidserver.pot b/locale/fdroidserver.pot index 0f9e9b28..486f290d 100644 --- a/locale/fdroidserver.pot +++ b/locale/fdroidserver.pot @@ -5,9 +5,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: fdroidserver 2.4.0\n" +"Project-Id-Version: fdroidserver 2.4.2-3-gdcb804f7\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -354,6 +354,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1479,6 +1484,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1992,6 +2002,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/fi/LC_MESSAGES/fdroidserver.po b/locale/fi/LC_MESSAGES/fdroidserver.po index 065b07d8..31803e83 100644 --- a/locale/fi/LC_MESSAGES/fdroidserver.po +++ b/locale/fi/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.0a0-62-gc63c4b3d\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2025-01-31 14:19+0000\n" "Last-Translator: Ricky Tigg \n" "Language-Team: Finnish \n" @@ -355,6 +355,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1480,6 +1485,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1993,6 +2003,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/fr/LC_MESSAGES/fdroidserver.po b/locale/fr/LC_MESSAGES/fdroidserver.po index aff0f707..d65abe95 100644 --- a/locale/fr/LC_MESSAGES/fdroidserver.po +++ b/locale/fr/LC_MESSAGES/fdroidserver.po @@ -42,20 +42,21 @@ # Lzebulon , 2024. # Armand Camponovo , 2024. # Lula Bye , 2025. +# Laurent FAVOLE , 2025. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-02 16:42+0000\n" -"Last-Translator: Lula Bye \n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-04-11 17:20+0000\n" +"Last-Translator: Laurent FAVOLE \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 5.10.3-dev\n" +"X-Generator: Weblate 5.11-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -81,7 +82,7 @@ msgstr "\"%s/\" n'a pas de fichier de métadonnées correspondant !" #: ../fdroidserver/index.py msgid "\"isPrimary\" key should not be added to mirrors!" -msgstr "" +msgstr "La clé \"isPrimary\" ne devrait pas être ajoutée aux miroirs !" #: ../fdroidserver/index.py #, python-brace-format @@ -398,6 +399,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Erreur de lecture {path} : {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -520,9 +526,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Création de « {path} » pour configurer s3cmd." #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "Lecture de '{config_file}'" +msgstr "Création d'un fichier {config_file} vide" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -692,12 +698,12 @@ msgstr "ERREUR : {key} dans {path} n'est pas \"archive\" ou \"repo\"." #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key} not a valid key!" -msgstr "" +msgstr "ERREUR : {key} n'est pas une clé valide !" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key}'s value should be of type {t}!" -msgstr "" +msgstr "ERREUR : la valeur de {key} devrait être du type {t} !" #: ../fdroidserver/lint.py #, python-brace-format @@ -724,9 +730,9 @@ msgid "Environment variable {var} from {configname} is not set!" msgstr "La variable d'environnent {var} de {configname} n'est pas configurée !" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment variable {{env: {var}}} is not set!" -msgstr "La variable d'environnent {var} de {configname} n'est pas configurée !" +msgstr "La variable d'environnement {{env: {var}}} n'est pas configurée !" #: ../fdroidserver/deploy.py msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" @@ -970,7 +976,7 @@ msgstr "Un mauvais élément du manifest est ignoré : %s" #: ../fdroidserver/common.py #, fuzzy, python-brace-format msgid "Ignoring deprecated {oldfile}, use {newfile}!" -msgstr "{oldfile} est obsolète, utilisez {newfile}" +msgstr "{oldfile} est obsolète et ignoré, {newfile} est utilisé !" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -1178,7 +1184,7 @@ msgstr "Profondeur maximale de récursivité dans le fichier ZIP atteinte : %s" #: ../fdroidserver/index.py #, python-brace-format msgid "Mirror config for {url} contains \"isPrimary\" key!" -msgstr "" +msgstr "La configuration du miroir pour {url} contient la clé \"isPrimary\" !" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." @@ -1345,7 +1351,7 @@ msgstr "Seuls les formats PNG et JPEG sont pris en charge pour les graphiques, t #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Only accepts a single key \"env\"" -msgstr "" +msgstr "N'accepte qu'une seule clé \"env\"" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" @@ -1506,7 +1512,7 @@ msgstr "Actualisation et mise en cache des règles et signature à partir du ré #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Signature de '{path}' refusée, le fichier existe à la fois dans les dossiers {dir1} et {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1525,6 +1531,11 @@ msgstr "Suppression de {path}\"" 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/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1734,7 +1745,7 @@ msgstr "Mode test — mettre la sortie dans le dossier tmp uniquement et toujour #: ../fdroidserver/index.py msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" -msgstr "" +msgstr "Le paquet Python \"qrcode\" n'est pas installé (p. ex. apt-get install python3-qrcode) !" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -1960,9 +1971,8 @@ msgid "Uploading {apkfilename} to virustotal" msgstr "Téléversement de {apkfilename} vers virustotal" #: ../fdroidserver/lint.py -#, fuzzy msgid "Use /HEAD instead of /master or /main to point at a file in the default branch" -msgstr "Utiliser /HEAD plutôt que /master pour pointer un fichier dans la branche par défaut" +msgstr "Utiliser /HEAD plutôt que /master pour pointer vers un fichier dans la branche par défaut" #: ../fdroidserver/update.py msgid "Use `fdroid update -c` to create it." @@ -1982,9 +1992,9 @@ msgid "Using \"{path}\" for configuring s3cmd." msgstr "Utiliser \"{path}\" pour configurer s3cmd." #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Using \"{path}\" for syncing with remote storage." -msgstr "Utiliser \"{path}\" pour configurer un stockage distant." +msgstr "Utiliser \"{path}\" pour synchroniser avec un stockage distant." #: ../fdroidserver/common.py msgid "Using APK Signature v2" @@ -2039,21 +2049,24 @@ msgid "Verifying index signature:" msgstr "Vérification de la signature d'index :" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Verifying package {path} with apksigner." -msgstr "Vérifier le paquet {path} avec apksigner." +msgstr "Vérification du paquet {path} avec apksigner." #: ../fdroidserver/deploy.py #, python-brace-format msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "L’API de VirusTotal ne permet pas d’envoyer des fichiers plus grands que 32Mo, utilisez {url} pour envoyer {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avertir de possibles erreurs dans les métadonnées" #: ../fdroidserver/scanner.py -#, fuzzy msgid "WebAssembly binary file" msgstr "Fichier binaire WebAssembly" @@ -2090,7 +2103,7 @@ msgid "ZIP file archive" msgstr "Archive ZIP" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "adb reports {serial} is \"{status}\"!" msgstr "adb reporte que {serial} est \"{status}\" !" @@ -2110,9 +2123,9 @@ msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "option ambiguë : %(option)s peut correspondre à %(matches)s" #: ../fdroidserver/common.py -#, python-brace-format +#, fuzzy, python-brace-format msgid "apksigner in build-tools;{version} passes APKs with invalid v3 signatures, ignoring." -msgstr "" +msgstr "apksigner dans build-tools;{version} accepte les APKs avec des signatures v3 invalides, ignoré" #: ../fdroidserver/common.py msgid "apksigner not found! Cannot sign or verify modern APKs" @@ -2216,9 +2229,8 @@ msgid "could not parse '{path}'" msgstr "impossible de lire '{path}'" #: ../fdroidserver/common.py -#, fuzzy msgid "could not parse srclib spec (no name specified): '{}'" -msgstr "impossible d'analyser la spécification srclib (pas de référence spécifiée) : '{}'" +msgstr "impossible d'analyser la spécification srclib (pas de nom spécifié) : '{}'" #: ../fdroidserver/common.py msgid "could not parse srclib spec (no ref specified): '{}'" @@ -2365,7 +2377,7 @@ msgid "mirror '%s' does not end with 'fdroid'!" msgstr "le miroir «%s» ne se termine pas par «fdroid» !" #: ../fdroidserver/index.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "mirrors set twice, in config.yml and {path}!" msgstr "miroir configuré deux fois, dans config.yml et {path} !" @@ -2452,9 +2464,9 @@ msgid "s3cmd sync indexes {path} to {url} and delete" msgstr "s3cmd synchroniser les index de {path} vers {url} et les supprimer" #: ../fdroidserver/deploy.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "s3cmd syncs indexes from {path} to {url} and deletes removed" -msgstr "s3cmd synchroniser les index de {path} vers {url} et les supprimer" +msgstr "s3cmd synchronise les index de {path} vers {url} et supprime ceux enlevés" #: ../fdroidserver/scanner.py #, python-brace-format @@ -2462,9 +2474,8 @@ msgid "scanner cache is malformed! You can clear it with: '{clear}'" msgstr "l'analyse du cache est mal formée ! Vous pouvez le nettoyer avec : '{clear}'" #: ../fdroidserver/deploy.py -#, fuzzy msgid "serverwebroot: path does not end with \"fdroid\", perhaps you meant one of these:" -msgstr "serverwebroot: le chemin ne se terminer pas avec \"fdroid\", peut être voulez-vous dire :" +msgstr "serverwebroot : le chemin ne se termine pas par \"fdroid\", peut-être voulez-vous dire :" #: ../fdroidserver/scanner.py msgid "shared library" @@ -2510,7 +2521,6 @@ msgid "the following arguments are required: %s" msgstr "les arguments suivants sont requis %s" #: ../fdroidserver/install.py -#, fuzzy msgid "true" msgstr "vrai" @@ -2548,7 +2558,6 @@ msgid "virustotal.com is rate limiting, waiting to retry..." msgstr "virustotal.com limite le nombre de requêtes, en attente avant de réessayer..." #: ../fdroidserver/install.py -#, fuzzy msgid "yes" msgstr "oui" @@ -2640,7 +2649,7 @@ msgstr "{name} \"{section}/icons/{path}\" n'existe pas ! Vérifiez \"config.yml\ #: ../fdroidserver/update.py #, python-brace-format msgid "{path1} is a duplicate of {path2}, remove one!" -msgstr "" +msgstr "{path1} est un doublon de {path2}, supprimez-en un !" #: ../fdroidserver/import_subcommand.py #, python-brace-format @@ -2663,7 +2672,7 @@ msgid "{path} has been flagged by virustotal {count} times:" msgstr "{path} a été signalé par virustotal {count} fois :" #: ../fdroidserver/install.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "{path} has the wrong fingerprint ({fingerprint})!" msgstr "{path} a la mauvaise empreinte ({fingerprint}) !" diff --git a/locale/fy/LC_MESSAGES/fdroidserver.po b/locale/fy/LC_MESSAGES/fdroidserver.po index 677eea67..1f751485 100644 --- a/locale/fy/LC_MESSAGES/fdroidserver.po +++ b/locale/fy/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.0\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2021-07-01 15:29+0000\n" "Last-Translator: Vancha March \n" "Language-Team: Frisian \n" @@ -353,6 +353,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1478,6 +1483,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1991,6 +2001,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/ga/LC_MESSAGES/fdroidserver.po b/locale/ga/LC_MESSAGES/fdroidserver.po index 6e899484..b9916f78 100644 --- a/locale/ga/LC_MESSAGES/fdroidserver.po +++ b/locale/ga/LC_MESSAGES/fdroidserver.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.3a1-162-gfbb3cc59\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-23 10:56+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-03-27 19:35+0000\n" "Last-Translator: Aindriú Mac Giolla Eoin \n" "Language-Team: Irish \n" "Language: ga\n" @@ -360,6 +360,11 @@ msgstr[2] "Ní féidir tógáil de bharr {} earráidí agus an scanadh" msgstr[3] "Ní féidir tógáil de bharr {} earráidí agus an scanadh" msgstr[4] "Ní féidir tógáil de bharr {} earráidí agus an scanadh" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Theip ar léamh {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1468,7 +1473,7 @@ msgstr "Athnuaigh agus cuir rialacha agus sínithe scanóirí taisce ón líonra #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Ag diúltú '{path}' a shíniú, tá an comhad san fhillteán {dir1} agus {dir2} araon." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1487,6 +1492,11 @@ msgstr "Ag baint {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Athainmnigh comhaid APK nach bhfuil comhoiriúnach package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2010,6 +2020,10 @@ msgstr "Pacáiste {path} á fhíorú le apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "Ní féidir le heochair API VirusTotal comhaid níos mó ná 32MB a uaslódáil, úsáid {url} chun {path} a uaslódáil." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Tabhair rabhadh faoi earráidí meiteashonraí a d'fhéadfadh a bheith ann" diff --git a/locale/hi/LC_MESSAGES/fdroidserver.po b/locale/hi/LC_MESSAGES/fdroidserver.po index 11e53f7d..58779021 100644 --- a/locale/hi/LC_MESSAGES/fdroidserver.po +++ b/locale/hi/LC_MESSAGES/fdroidserver.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.0a5-27-gf24eae0f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2023-02-22 11:24+0000\n" "Last-Translator: Saurmandal \n" "Language-Team: Hindi \n" @@ -354,6 +354,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1479,6 +1484,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1992,6 +2002,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/hu/LC_MESSAGES/fdroidserver.po b/locale/hu/LC_MESSAGES/fdroidserver.po index a9d51973..6e232ead 100644 --- a/locale/hu/LC_MESSAGES/fdroidserver.po +++ b/locale/hu/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-04-10 13:33+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Hungarian \n" @@ -359,6 +359,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Nem lehet összeállítani, mert {} hiba történt az átvizsgáláskor" msgstr[1] "Nem lehet összeállítani, mert {} hiba történt az átvizsgáláskor" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "A(z) {path} olvasása sikertelen: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1494,6 +1499,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Azon APK fájlok átnevezése, melyek nem illeszkednek a csomag.név_123.apk mintára" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2011,6 +2021,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Figyelmeztetés a lehetséges metaadat-hibákról" diff --git a/locale/it/LC_MESSAGES/fdroidserver.po b/locale/it/LC_MESSAGES/fdroidserver.po index a20dfa82..5117e2d4 100644 --- a/locale/it/LC_MESSAGES/fdroidserver.po +++ b/locale/it/LC_MESSAGES/fdroidserver.po @@ -22,7 +22,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2025-03-20 16:21+0000\n" "Last-Translator: Champ0999 \n" "Language-Team: Italian \n" @@ -375,6 +375,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Impossibile leggere {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1504,6 +1509,11 @@ msgstr "Rimozione di {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Rinomina i file APK che non corrispondono a package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2028,6 +2038,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "La chiave API di VirusTotal non può caricare file più grandi di 32MB, usa {url} per caricare {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avvisa riguardo possibili errori nei metadati" diff --git a/locale/ja/LC_MESSAGES/fdroidserver.po b/locale/ja/LC_MESSAGES/fdroidserver.po index 1d8629c1..50dd832d 100644 --- a/locale/ja/LC_MESSAGES/fdroidserver.po +++ b/locale/ja/LC_MESSAGES/fdroidserver.po @@ -8,8 +8,8 @@ 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: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-02-08 06:22+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-04-30 04:07+0000\n" "Last-Translator: Liner Seven \n" "Language-Team: Japanese \n" "Language: ja\n" @@ -17,7 +17,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 5.10-dev\n" +"X-Generator: Weblate 5.12-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -43,7 +43,7 @@ msgstr "「\"%s/」に合致するメタデータのファイルはありませ #: ../fdroidserver/index.py msgid "\"isPrimary\" key should not be added to mirrors!" -msgstr "" +msgstr "\"isPrimary\" キーはミラーに追加すべきではありません!" #: ../fdroidserver/index.py #, python-brace-format @@ -359,6 +359,11 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "スキャン時に{}個のエラーが発生したためビルドできません" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "{path}を読み込めませんでした:{error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -481,9 +486,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "s3cmdの設定用に「{path}」を作成します。" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "「{config_file}」を読み込みます" +msgstr "素の {config_file} を作成" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -653,12 +658,12 @@ msgstr "エラー:{path}の{key}は「archive」でも「repo」でもあり #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key} not a valid key!" -msgstr "" +msgstr "エラー:{key} が無効な値です!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key}'s value should be of type {t}!" -msgstr "" +msgstr "エラー:{key} の値は {t} 型でなければいけません!" #: ../fdroidserver/lint.py #, python-brace-format @@ -685,9 +690,9 @@ msgid "Environment variable {var} from {configname} is not set!" msgstr "{configname}の環境変数 {var} が設定されていません!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment variable {{env: {var}}} is not set!" -msgstr "{configname}の環境変数 {var} が設定されていません!" +msgstr "環境変数{{env: {var}}}が未設定です!" #: ../fdroidserver/deploy.py msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" @@ -929,9 +934,9 @@ msgid "Ignoring bad element in manifest: %s" msgstr "manifestの正しくない要素を無視します:%s" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Ignoring deprecated {oldfile}, use {newfile}!" -msgstr "{oldfile}は非推奨です。{newfile}を使用してください" +msgstr "{oldfile}は非推奨です。{newfile}を使用してください!" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -1139,7 +1144,7 @@ msgstr "ZIPファイルの最大の再帰階層に到達しました:%s" #: ../fdroidserver/index.py #, python-brace-format msgid "Mirror config for {url} contains \"isPrimary\" key!" -msgstr "" +msgstr "{url} のミラー設定に \"isPrimary\" キーが含まれています!" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." @@ -1306,7 +1311,7 @@ msgstr "画像にはPNGとJPEGのみをサポートします。これが見つ #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Only accepts a single key \"env\"" -msgstr "" +msgstr "単一キー \"env\" のみを受け付けます" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" @@ -1467,7 +1472,7 @@ msgstr "スキャナーのルールと署名をネットワークから取得し #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "{dir1} と {dir2} のどちらにもファイルが存在するため、'{path}'への署名は拒否されました。" #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1486,6 +1491,11 @@ msgstr "{path} を削除" msgid "Rename APK files that do not match package.name_123.apk" msgstr "package.name_123.apkに合致しないAPKファイルの名前を変更" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1694,7 +1704,7 @@ msgstr "テストモード - 既に出力が存在する場合でも、一時デ #: ../fdroidserver/index.py msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" -msgstr "" +msgstr "\"qrcode\"のPythonパッケージが未導入です( 例えば apt-get install python3-qrcode します)!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -2005,6 +2015,10 @@ msgstr "apksignerを使用してパッケージ{path}を検証しています。 msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "VirusTotalのAPI鍵は32メガバイトより大きいファイルをアップロードできません。{url}から{path}をアップロードしてください。" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "潜在的なメタデータのエラーに関して警告" @@ -2589,7 +2603,7 @@ msgstr "{name}「{section}/icons/{path}」がありません!「config.yml」 #: ../fdroidserver/update.py #, python-brace-format msgid "{path1} is a duplicate of {path2}, remove one!" -msgstr "" +msgstr "{path1} は {path2} と重複しています、片方を除外してください!" #: ../fdroidserver/import_subcommand.py #, python-brace-format diff --git a/locale/kab/LC_MESSAGES/fdroidserver.po b/locale/kab/LC_MESSAGES/fdroidserver.po index 9cc66432..121b58f0 100644 --- a/locale/kab/LC_MESSAGES/fdroidserver.po +++ b/locale/kab/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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2021-01-15 13:25+0000\n" "Last-Translator: R_SACI \n" "Language-Team: Kabyle \n" @@ -355,6 +355,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1482,6 +1487,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1995,6 +2005,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/ko/LC_MESSAGES/fdroidserver.po b/locale/ko/LC_MESSAGES/fdroidserver.po index 66244698..cb546be1 100644 --- a/locale/ko/LC_MESSAGES/fdroidserver.po +++ b/locale/ko/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-09-06 14:57+0000\n" "Last-Translator: Cxnfl1ct \n" "Language-Team: Korean \n" @@ -358,6 +358,11 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1485,6 +1490,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "package.name_123.apk와 일치하지 않는 APK 파일의 이름을 바꿉니다" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1997,6 +2007,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "가능한 메타데이터 오류에 대해 경고합니다" diff --git a/locale/ml/LC_MESSAGES/fdroidserver.po b/locale/ml/LC_MESSAGES/fdroidserver.po index 39b7a730..1a4cc764 100644 --- a/locale/ml/LC_MESSAGES/fdroidserver.po +++ b/locale/ml/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2023-06-23 14:52+0000\n" "Last-Translator: abe1242 \n" "Language-Team: Malayalam \n" @@ -358,6 +358,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1483,6 +1488,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1999,6 +2009,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/nb_NO/LC_MESSAGES/fdroidserver.po b/locale/nb_NO/LC_MESSAGES/fdroidserver.po index 26cf9e7f..8ba73029 100644 --- a/locale/nb_NO/LC_MESSAGES/fdroidserver.po +++ b/locale/nb_NO/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2022-09-06 14:30+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Norwegian Bokmål \n" @@ -366,6 +366,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Klarte ikke å lese {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, fuzzy, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1537,6 +1542,11 @@ msgstr "Fjerner {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Gi nytt navn til APK-filer som ikke samsvarer med package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2070,6 +2080,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "VirusTotal API-nøkkel kan ikke laste opp filer større enn 32 MB, bruk {url} for å laste opp {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Advar om mulige metadata-feil" diff --git a/locale/nl/LC_MESSAGES/fdroidserver.po b/locale/nl/LC_MESSAGES/fdroidserver.po index aa9106fb..f5dbfba0 100644 --- a/locale/nl/LC_MESSAGES/fdroidserver.po +++ b/locale/nl/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-01-03 09:07+0000\n" "Last-Translator: Issa1553 \n" "Language-Team: Dutch \n" @@ -361,6 +361,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1486,6 +1491,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Hernoem APK-bestanden die niet overeenkomen met pakket.naam_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1999,6 +2009,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Waarschuwen voor mogelijke metadata fouten" diff --git a/locale/nn/LC_MESSAGES/fdroidserver.po b/locale/nn/LC_MESSAGES/fdroidserver.po index 180c114d..5db8fd94 100644 --- a/locale/nn/LC_MESSAGES/fdroidserver.po +++ b/locale/nn/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.3.0-3-g4ba7b5c9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-11-26 10:54+0000\n" "Last-Translator: Bård Sigurd Møller \n" "Language-Team: Norwegian Nynorsk \n" @@ -353,6 +353,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1478,6 +1483,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1991,6 +2001,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/pa/LC_MESSAGES/fdroidserver.po b/locale/pa/LC_MESSAGES/fdroidserver.po index b08867aa..8c64a1c2 100644 --- a/locale/pa/LC_MESSAGES/fdroidserver.po +++ b/locale/pa/LC_MESSAGES/fdroidserver.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.3.3\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -352,6 +352,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1477,6 +1482,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1990,6 +2000,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/pick-complete-translations.py b/locale/pick-complete-translations.py index 8c4d377b..be11426c 100755 --- a/locale/pick-complete-translations.py +++ b/locale/pick-complete-translations.py @@ -2,13 +2,13 @@ # # add completed translations from weblate to MANIFEST.in -import git import json import os import re -import requests import subprocess +import git +import requests projectbasedir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) localedir = os.path.join(projectbasedir, 'locale') diff --git a/locale/pl/LC_MESSAGES/fdroidserver.po b/locale/pl/LC_MESSAGES/fdroidserver.po index 4726753c..03bbc39f 100644 --- a/locale/pl/LC_MESSAGES/fdroidserver.po +++ b/locale/pl/LC_MESSAGES/fdroidserver.po @@ -10,8 +10,8 @@ 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: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-13 20:43+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-06-24 12:05+0000\n" "Last-Translator: WaldiS \n" "Language-Team: Polish \n" "Language: pl\n" @@ -19,7 +19,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 5.11-dev\n" +"X-Generator: Weblate 5.13-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -45,7 +45,7 @@ msgstr "\"%s/\" nie ma pasującego pliku metadanych!" #: ../fdroidserver/index.py msgid "\"isPrimary\" key should not be added to mirrors!" -msgstr "" +msgstr "Klucz „isPrimary” nie powinien być dodawany do mirrorów!" #: ../fdroidserver/index.py #, python-brace-format @@ -363,6 +363,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Błąd odczytu {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -485,9 +490,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Tworzenie \"{path}\" do konfiguracji s3cmd." #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "Czytaj '{config_file}'" +msgstr "Tworzenie pustego pliku {config_file}" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -657,12 +662,12 @@ msgstr "BŁĄD: {key} w {path} nie jest \"archive\" lub \"repo\"!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key} not a valid key!" -msgstr "" +msgstr "BŁĄD: {key} nie jest prawidłowym kluczem!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key}'s value should be of type {t}!" -msgstr "" +msgstr "BŁĄD: wartość klucza {key} powinna być typu {t}!" #: ../fdroidserver/lint.py #, python-brace-format @@ -689,9 +694,9 @@ msgid "Environment variable {var} from {configname} is not set!" msgstr "Zmienna środowiskowa {var} z {configname} nie jest ustawiona!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment variable {{env: {var}}} is not set!" -msgstr "Zmienna środowiskowa {var} z {configname} nie jest ustawiona!" +msgstr "Zmienna środowiskowa{{env: {var}}} nie została ustawiona!" #: ../fdroidserver/deploy.py msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" @@ -933,9 +938,9 @@ msgid "Ignoring bad element in manifest: %s" msgstr "Ignorowanie błędnego elementu w manifeście: %s" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Ignoring deprecated {oldfile}, use {newfile}!" -msgstr "{oldfile} jest przestarzałe, użyj {newfile}" +msgstr "{oldfile} jest przestarzałe, użyj {newfile}!" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -1143,7 +1148,7 @@ msgstr "Osiągnięto maksymalną głębokość rekurencji w pliku ZIP: %s" #: ../fdroidserver/index.py #, python-brace-format msgid "Mirror config for {url} contains \"isPrimary\" key!" -msgstr "" +msgstr "Konfiguracja Mirror dla {url} zawiera klucz \"isPrimary\"!" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." @@ -1310,7 +1315,7 @@ msgstr "Tylko PNG i JPEG są obsługiwane dla grafiki, znaleziono: {path}" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Only accepts a single key \"env\"" -msgstr "" +msgstr "Akceptowany jest tylko jeden klucz \"env\"" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" @@ -1471,7 +1476,7 @@ msgstr "Odświeżanie i buforowanie reguł skanera i sygnatur z sieci" #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Odmowa podpisania pliku {path}, ponieważ istnieje on zarówno w folderze {dir1}, jak i {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1490,6 +1495,11 @@ msgstr "Usuwanie „{path}”" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Zmień nazwy plików APK, które nie pasują do pliku package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1700,7 +1710,7 @@ msgstr "Tryb testowy - umieszczaj dane wyjściowe tylko w katalogu tmp i zawsze #: ../fdroidserver/index.py msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" -msgstr "" +msgstr "Pakiet Pythona „qrcode” nie jest zainstalowany (np. apt-get install python3-qrcode)!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -2011,6 +2021,10 @@ msgstr "Weryfikacja pakietu {path} za pomocą apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "Klucz VirusTotal API nie może przesyłać plików większych niż 32 MB, użyj {url}, aby przesłać {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Ostrzegaj o możliwych błędach metadanych" @@ -2601,7 +2615,7 @@ msgstr "{name} \"{section}/icons/{path}\" nie istnieje! Sprawdź \"config.yml\". #: ../fdroidserver/update.py #, python-brace-format msgid "{path1} is a duplicate of {path2}, remove one!" -msgstr "" +msgstr "{path1} to duplikat {path2}, usuń jeden z nich!" #: ../fdroidserver/import_subcommand.py #, python-brace-format diff --git a/locale/pt/LC_MESSAGES/fdroidserver.po b/locale/pt/LC_MESSAGES/fdroidserver.po index feb11e64..84ee4ed9 100644 --- a/locale/pt/LC_MESSAGES/fdroidserver.po +++ b/locale/pt/LC_MESSAGES/fdroidserver.po @@ -9,8 +9,8 @@ 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: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-02 21:32+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-04-06 16:45+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -18,7 +18,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 5.10.3-dev\n" +"X-Generator: Weblate 5.11-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -44,7 +44,7 @@ msgstr "\"%s/\" não tem ficheiro de metadados correspondente!" #: ../fdroidserver/index.py msgid "\"isPrimary\" key should not be added to mirrors!" -msgstr "" +msgstr "A chave \"isPrimary\" não deve ser adicionada em espelhos!" #: ../fdroidserver/index.py #, python-brace-format @@ -361,6 +361,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Falha de leitura {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -483,9 +488,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Criando \"{path}\" para configurar s3cmd." #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "A ler '{config_file}'" +msgstr "A criar '{config_file}' vazio" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -655,12 +660,12 @@ msgstr "ERRO: {key} em {path} não é \"arquivo\" ou \"repositório\"!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key} not a valid key!" -msgstr "" +msgstr "ERRO: {key} não é uma chave válida!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key}'s value should be of type {t}!" -msgstr "" +msgstr "ERRO: o valor de {key} deve ser do tipo {t}!" #: ../fdroidserver/lint.py #, python-brace-format @@ -687,9 +692,9 @@ msgid "Environment variable {var} from {configname} is not set!" msgstr "A variável de ambiente {var} de {configname} não está definida!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment variable {{env: {var}}} is not set!" -msgstr "A variável de ambiente {var} de {configname} não está definida!" +msgstr "A variável de ambiente {{env: {var} não está definida!" #: ../fdroidserver/deploy.py msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" @@ -931,9 +936,9 @@ msgid "Ignoring bad element in manifest: %s" msgstr "A ignorar o elemento mau no manifesto: %s" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Ignoring deprecated {oldfile}, use {newfile}!" -msgstr "{oldfile} está obsoleto, use {newfile}" +msgstr "A ignorar {oldfile} obsoleto, use {newfile}!" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -1141,7 +1146,7 @@ msgstr "Profundidade máxima de recursão no ficheiro ZIP atingida: %s" #: ../fdroidserver/index.py #, python-brace-format msgid "Mirror config for {url} contains \"isPrimary\" key!" -msgstr "" +msgstr "A configuração de espelho de {url} contém a chave \"isPrimary\"!" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." @@ -1308,7 +1313,7 @@ msgstr "Somente PNG e JPEG são suportados para gráficos, encontrado: {path}" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Only accepts a single key \"env\"" -msgstr "" +msgstr "Aceita apenas uma única chave \"env\"" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" @@ -1469,7 +1474,7 @@ msgstr "Atualizar e armazenar as regras e assinaturas do scanner da rede no cach #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Recuso assinar '{path}', o ficheiro existe nas pastas {dir1} e {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1488,6 +1493,11 @@ msgstr "A remover {path}\"" 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/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1697,7 +1707,7 @@ msgstr "Modo de teste - ponha a saída apenas no diretório tmp e sempre compile #: ../fdroidserver/index.py msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" -msgstr "" +msgstr "O pacote Python \"qrcode\" não está instalado (por exemplo, apt-get install python3-qrcode)!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -2008,6 +2018,10 @@ msgstr "A verificar o pacote {path} com apksigner." 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}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avisar sobre possíveis erros de metadados" @@ -2595,7 +2609,7 @@ msgstr "{name} \"{section}/icons/{path}\" não existe! Corrija-o no \"config.yml #: ../fdroidserver/update.py #, python-brace-format msgid "{path1} is a duplicate of {path2}, remove one!" -msgstr "" +msgstr "{path1} é uma duplicata de {path2}, remova uma!" #: ../fdroidserver/import_subcommand.py #, python-brace-format diff --git a/locale/pt_BR/LC_MESSAGES/fdroidserver.po b/locale/pt_BR/LC_MESSAGES/fdroidserver.po index 4ae99353..ea2ad833 100644 --- a/locale/pt_BR/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_BR/LC_MESSAGES/fdroidserver.po @@ -19,9 +19,9 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-21 18:43+0000\n" -"Last-Translator: LucasMZ \n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-03-26 10:00+0000\n" +"Last-Translator: Igor Rückert \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -371,6 +371,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Falha ao ler {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1479,7 +1484,7 @@ msgstr "Atualizar e armazenar em cache regras e assinaturas do scanner da rede" #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Recusando assinar '{path}', o arquivo existe nas pastas {dir1} e {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1498,6 +1503,11 @@ msgstr "Removendo {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Renomeia arquivos APK que não correspondem a pacote.nome_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2018,6 +2028,10 @@ msgstr "Verificando o pacote {path} com apksigner." 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}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avisa sobre possíveis erros de metadados" diff --git a/locale/pt_PT/LC_MESSAGES/fdroidserver.po b/locale/pt_PT/LC_MESSAGES/fdroidserver.po index a3538f79..e9f15dfa 100644 --- a/locale/pt_PT/LC_MESSAGES/fdroidserver.po +++ b/locale/pt_PT/LC_MESSAGES/fdroidserver.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-02 21:32+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-05-30 07:19+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese (Portugal) \n" "Language: pt_PT\n" @@ -20,7 +20,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 5.10.3-dev\n" +"X-Generator: Weblate 5.12-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -46,7 +46,7 @@ msgstr "\"%s/\" não tem ficheiro de metadados correspondente!" #: ../fdroidserver/index.py msgid "\"isPrimary\" key should not be added to mirrors!" -msgstr "" +msgstr "A chave \"isPrimary\" não deve ser adicionada em espelhos!" #: ../fdroidserver/index.py #, python-brace-format @@ -363,6 +363,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Falha de leitura {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -485,9 +490,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Criando \"{path}\" para configurar s3cmd." #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "A ler '{config_file}'" +msgstr "A criar '{config_file}' vazio" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -657,12 +662,12 @@ msgstr "ERRO: {key} em {path} não é \"arquivo\" ou \"repositório\"!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key} not a valid key!" -msgstr "" +msgstr "ERRO: {key} não é uma chave válida!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key}'s value should be of type {t}!" -msgstr "" +msgstr "ERRO: o valor de {key} deve ser do tipo {t}!" #: ../fdroidserver/lint.py #, python-brace-format @@ -689,9 +694,9 @@ msgid "Environment variable {var} from {configname} is not set!" msgstr "A variável de ambiente {var} de {configname} não está definida!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment variable {{env: {var}}} is not set!" -msgstr "A variável de ambiente {var} de {configname} não está definida!" +msgstr "A variável de ambiente {{env: {var} não está definida!" #: ../fdroidserver/deploy.py msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" @@ -933,9 +938,9 @@ msgid "Ignoring bad element in manifest: %s" msgstr "A ignorar o elemento mau no manifesto: %s" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Ignoring deprecated {oldfile}, use {newfile}!" -msgstr "{oldfile} está obsoleto, use {newfile}" +msgstr "A ignorar {oldfile} obsoleto, use {newfile}!" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -1143,7 +1148,7 @@ msgstr "Profundidade máxima de recursão no ficheiro ZIP atingida: %s" #: ../fdroidserver/index.py #, python-brace-format msgid "Mirror config for {url} contains \"isPrimary\" key!" -msgstr "" +msgstr "A configuração de espelho de {url} contém a chave \"isPrimary\"!" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." @@ -1310,7 +1315,7 @@ msgstr "Somente PNG e JPEG são suportados para gráficos, encontrado: {path}" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Only accepts a single key \"env\"" -msgstr "" +msgstr "Aceita apenas uma única chave \"env\"" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" @@ -1471,7 +1476,7 @@ msgstr "Atualizar e armazenar as regras e assinaturas do scanner da rede no cach #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Recuso assinar '{path}', o ficheiro existe nas pastas {dir1} e {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1490,6 +1495,11 @@ msgstr "A remover {path}\"" 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/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1699,7 +1709,7 @@ msgstr "Modo de teste - ponha a saída apenas no diretório tmp e sempre compile #: ../fdroidserver/index.py msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" -msgstr "" +msgstr "O pacote de Python \"qrcode\" não está instalado (por exemplo, apt-get install python3-qrcode)!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -2010,6 +2020,10 @@ msgstr "A verificar o pacote {path} com apksigner." 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}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avisar sobre possíveis erros de metadados" @@ -2597,7 +2611,7 @@ msgstr "{name} \"{section}/icons/{path}\" não existe! Corrija-o no \"config.yml #: ../fdroidserver/update.py #, python-brace-format msgid "{path1} is a duplicate of {path2}, remove one!" -msgstr "" +msgstr "{path1} é uma duplicata de {path2}, remova uma!" #: ../fdroidserver/import_subcommand.py #, python-brace-format diff --git a/locale/ro/LC_MESSAGES/fdroidserver.po b/locale/ro/LC_MESSAGES/fdroidserver.po index 4293395d..0599ee8c 100644 --- a/locale/ro/LC_MESSAGES/fdroidserver.po +++ b/locale/ro/LC_MESSAGES/fdroidserver.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.0a5-27-gf24eae0f\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-12-02 17:00+0000\n" "Last-Translator: Licaon Kter \n" "Language-Team: Romanian \n" @@ -362,6 +362,11 @@ msgstr[0] "Nu se poate construi din cauza unei erori {} în timpul scanării" msgstr[1] "Nu se poate construi din cauza erorilor {} în timpul scanării" msgstr[2] "Nu se poate construi din cauza erorilor {} în timpul scanării" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "A eșuat citirea {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1489,6 +1494,11 @@ msgstr "Eliminarea lui {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Redenumiți fișierele APK care nu se potrivesc cu package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2011,6 +2021,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "VirusTotal API key nu poate încărca fișiere mai mari de 32MB, utilizați {url} pentru a încărca {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Avertizează cu privire la posibile erori de metadate" diff --git a/locale/ru/LC_MESSAGES/fdroidserver.po b/locale/ru/LC_MESSAGES/fdroidserver.po index 023ed632..bd4aa6f5 100644 --- a/locale/ru/LC_MESSAGES/fdroidserver.po +++ b/locale/ru/LC_MESSAGES/fdroidserver.po @@ -16,20 +16,21 @@ # gfbdrgng , 2024. # neverender , 2024. # Dmitry , 2024. +# Artyom Rybakov , 2025. 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: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-01-25 15:42+0000\n" -"Last-Translator: Golubev Alexander \n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-06-24 10:15+0000\n" +"Last-Translator: Artyom Rybakov \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 5.10-dev\n" +"X-Generator: Weblate 5.13-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -55,7 +56,7 @@ msgstr "У \"%s/\" нет соответствующего файла метад #: ../fdroidserver/index.py msgid "\"isPrimary\" key should not be added to mirrors!" -msgstr "" +msgstr "Ключ \"IsPrimary\" не следует добавлять в зеркала!" #: ../fdroidserver/index.py #, python-brace-format @@ -373,6 +374,11 @@ msgstr[0] "Запустить сборку невозможно из-за {} о msgstr[1] "Запустить сборку невозможно из-за {} ошибок во время сканирования данных" msgstr[2] "Запустить сборку невозможно из-за {} ошибок во время сканирования данных" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Не удалось распознать {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -495,9 +501,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "Создание \"{path}\" для конфигурации s3cmd." #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "Чтение '{config_file}'" +msgstr "Создание пустого '{config_file}'" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -667,12 +673,12 @@ msgstr "ОШИБКА: {key} в {path} должен быть или \"archive\", #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key} not a valid key!" -msgstr "" +msgstr "ОШИБКА: {key} недействительный ключ!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key}'s value should be of type {t}!" -msgstr "" +msgstr "ОШИБКА: значение {key} должно быть типа {t}!" #: ../fdroidserver/lint.py #, python-brace-format @@ -699,9 +705,9 @@ msgid "Environment variable {var} from {configname} is not set!" msgstr "Переменная среды {var} из {configname} не установлена!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment variable {{env: {var}}} is not set!" -msgstr "Переменная среды {var} из {configname} не установлена!" +msgstr "Переменная среды {{env: {var}}} не установлена!" #: ../fdroidserver/deploy.py msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" @@ -943,9 +949,9 @@ msgid "Ignoring bad element in manifest: %s" msgstr "Проигнорировано: плохой элемент в манифесте: %s" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Ignoring deprecated {oldfile}, use {newfile}!" -msgstr "{oldfile} признан устаревшим; используйте {newfile}" +msgstr "Устаревший {oldfile} игнорируется, используйте {newfile}!" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -1153,7 +1159,7 @@ msgstr "Достигнута максимальная глубина рекур #: ../fdroidserver/index.py #, python-brace-format msgid "Mirror config for {url} contains \"isPrimary\" key!" -msgstr "" +msgstr "Конфигурация зеркала для {url} содержит ключ \"IsPrimary\"!" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." @@ -1320,7 +1326,7 @@ msgstr "Допускаются изображения только в форма #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Only accepts a single key \"env\"" -msgstr "" +msgstr "Принимает только один ключ \"env\"" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" @@ -1481,7 +1487,7 @@ msgstr "Обновление и кэширование правил и сигн #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Отказываюсь подписывать '{path}', файл существует как в папке {dir1}, так и в папке {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1500,6 +1506,11 @@ msgstr "Удаление {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Переименовать все APK файлы, не соответствующие шаблону \"название.пакета_123.apk\"" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1710,7 +1721,7 @@ msgstr "Тестовый режим. Все собранное попадает #: ../fdroidserver/index.py msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" -msgstr "" +msgstr "Пакет Python \"qrcode\" не установлен (например, apt-get install python3-qrcode)!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -2021,6 +2032,10 @@ msgstr "Проверка пакета {path} с помощью apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "Через API VirusTotal нельзя загрузить файлы больше 32MB, загрузите {path} на {url} самостоятельно." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Предупреждать о возможных ошибках в метаданных" @@ -2611,7 +2626,7 @@ msgstr "{name}: \"{section}/icons/{path}\" не существует! Попра #: ../fdroidserver/update.py #, python-brace-format msgid "{path1} is a duplicate of {path2}, remove one!" -msgstr "" +msgstr "{path1} дублирует {path2}, удалите один!" #: ../fdroidserver/import_subcommand.py #, python-brace-format diff --git a/locale/sk/LC_MESSAGES/fdroidserver.po b/locale/sk/LC_MESSAGES/fdroidserver.po index a4dd859f..f3f21800 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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -353,6 +353,11 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1478,6 +1483,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1992,6 +2002,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/sq/LC_MESSAGES/fdroidserver.po b/locale/sq/LC_MESSAGES/fdroidserver.po index 25881e20..efa0401b 100644 --- a/locale/sq/LC_MESSAGES/fdroidserver.po +++ b/locale/sq/LC_MESSAGES/fdroidserver.po @@ -6,8 +6,8 @@ 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: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-21 08:45+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-03-26 21:33+0000\n" "Last-Translator: Besnik Bleta \n" "Language-Team: Albanian \n" "Language: sq\n" @@ -358,6 +358,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "S’u arrit të lexohej {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1466,7 +1471,7 @@ msgstr "Rifresko dhe ruaj në fshehtinë rregulla skaneri nga rrjeti" #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "S’po pranohet të nënshkruhet '{path}', kartela ekziston te të dyja dosjet, {dir1} dhe {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1485,6 +1490,11 @@ msgstr "Po hiqet {path}\"" 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/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2006,6 +2016,10 @@ msgstr "Po verifikohet paketë {path} me apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "Kyçi API VirusTotal s’mund të ngarkojë kartela më të mëdha se 2MB, përdorni {url} që të ngarkoni {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Sinjalizo rreth gabimesh të mundshëm tejtëdhënash" diff --git a/locale/sr/LC_MESSAGES/fdroidserver.po b/locale/sr/LC_MESSAGES/fdroidserver.po index b07f0c4e..5413ac1d 100644 --- a/locale/sr/LC_MESSAGES/fdroidserver.po +++ b/locale/sr/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.1b0\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-12-30 22:00+0000\n" "Last-Translator: Reno Tx \n" "Language-Team: Serbian \n" @@ -361,6 +361,11 @@ msgstr[0] "Не може се изградити због {} грешке при msgstr[1] "Не може се изградити због {} грешке приликом скенирања" msgstr[2] "Не може се изградити због {} грешака приликом скенирања" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Није успело читање {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1488,6 +1493,11 @@ msgstr "Уклањање {path}" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Преименујте APK фајлове који не одговарају package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2009,6 +2019,10 @@ msgstr "Провера пакета {path} са apksigner." msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "VirusTotal API кључ не може отпремити датотеке веће од 32MB, користи {url} за отпремање {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Упозорење о могућим грешкама у метаподацима" diff --git a/locale/sv/LC_MESSAGES/fdroidserver.po b/locale/sv/LC_MESSAGES/fdroidserver.po index ce93975f..a0928312 100644 --- a/locale/sv/LC_MESSAGES/fdroidserver.po +++ b/locale/sv/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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2025-03-17 21:44+0000\n" "Last-Translator: Kristoffer Grundström \n" "Language-Team: Swedish \n" @@ -362,6 +362,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "{path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1487,6 +1492,11 @@ msgstr "Tar bort {path}''" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Byt namn på APK-filer som inte matchar paket.namn_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2000,6 +2010,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Visa varningar vid möjliga metadatafel" diff --git a/locale/sw/LC_MESSAGES/fdroidserver.po b/locale/sw/LC_MESSAGES/fdroidserver.po index 21e2b3a3..3ddf8eb8 100644 --- a/locale/sw/LC_MESSAGES/fdroidserver.po +++ b/locale/sw/LC_MESSAGES/fdroidserver.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.3a1\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-09-08 11:09+0000\n" "Last-Translator: abelbiwott-dev \n" "Language-Team: Swahili \n" @@ -359,6 +359,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "Haiwezi kujenga kutokana na kosa la {} wakati wa uchanganuzi" msgstr[1] "Haiwezi kujenga kutokana na makosa ya {} wakati wa uchanganuzi" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Imeshindwa kusoma {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1486,6 +1491,11 @@ msgstr "Kuondoa {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Badilisha jina la faili za APK ambazo hazilingani na package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2007,6 +2017,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "Ufunguo wa API ya VirusTotal haiwezi kupakia faili zaidi ya 32MB, tumia {url} kupakia {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Onya kuhusu hitilafu ya metadata yanayoweza kutokea" diff --git a/locale/ta/LC_MESSAGES/fdroidserver.po b/locale/ta/LC_MESSAGES/fdroidserver.po index 00d2540d..0661e420 100644 --- a/locale/ta/LC_MESSAGES/fdroidserver.po +++ b/locale/ta/LC_MESSAGES/fdroidserver.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 2.1-273-g54e84d87\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2025-01-20 14:04+0000\n" "Last-Translator: Hans-Christoph Steiner \n" "Language-Team: Tamil \n" @@ -360,6 +360,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "ச்கேன் செய்யும் போது {} பிழை காரணமாக உருவாக்க முடியாது" msgstr[1] "ச்கேன் செய்யும் போது {} பிழைகள் காரணமாக உருவாக்க முடியாது" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "தோல்வியுற்ற வாசிப்பு {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1487,6 +1492,11 @@ msgstr "{path} \"ஐ நீக்குதல்" msgid "Rename APK files that do not match package.name_123.apk" msgstr "தொகுப்புடன் பொருந்தாத APK கோப்புகளை மறுபெயரிடுங்கள். NAME_123.APK" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2007,6 +2017,10 @@ msgstr "Apksigner உடன் தொகுப்பு {path} ஐ சரிப msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "வைரச்டோட்டல் பநிஇ விசையை 32MB ஐ விட பெரிய கோப்புகளை பதிவேற்ற முடியாது, {path} பதிவேற்ற {url} ஐப் பயன்படுத்தவும்." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "சாத்தியமான மேனிலை தரவு பிழைகள் குறித்து எச்சரிக்கவும்" diff --git a/locale/tr/LC_MESSAGES/fdroidserver.po b/locale/tr/LC_MESSAGES/fdroidserver.po index f3cdbc11..b3bbe3d5 100644 --- a/locale/tr/LC_MESSAGES/fdroidserver.po +++ b/locale/tr/LC_MESSAGES/fdroidserver.po @@ -4,20 +4,23 @@ # Orhan , 2021. # Oğuz Ersen , 2022, 2023, 2024. # Bai , 2023. +# "M. Fatih Uluçam" , 2025. +# Nuri KÜÇÜKLER , 2025. +# Bora Atıcı , 2025. msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2024-09-10 23:49+0000\n" -"Last-Translator: Oğuz Ersen \n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-05-26 22:01+0000\n" +"Last-Translator: Bora Atıcı \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 5.8-dev\n" +"X-Generator: Weblate 5.12-dev\n" #: ../fdroidserver/nightly.py msgid "" @@ -43,7 +46,7 @@ msgstr "\"%s/\" eşleşen üst veri dosyasına sahip değil!" #: ../fdroidserver/index.py msgid "\"isPrimary\" key should not be added to mirrors!" -msgstr "" +msgstr "\"isPrimary\" anahtarı yansılara eklenmemelidir!" #: ../fdroidserver/index.py #, python-brace-format @@ -170,7 +173,7 @@ msgstr "'{value}' geçerli bir {field} değil, {pattern} olmalı" #: ../fdroidserver/checkupdates.py msgid "--merge-request only runs on a single appid!" -msgstr "" +msgstr "--merge-request yalnızca tek bir uygulama kimliğinde çalışır!" #: ../fdroidserver/checkupdates.py #, python-brace-format @@ -295,11 +298,11 @@ msgstr "UpdateCheckMode ile AutoUpdateMode: HTTP bir desene sahip olmalıdır." #: ../fdroidserver/install.py msgid "Automatic no to all prompts." -msgstr "" +msgstr "Bütün sorulara otomatik olarak hayır." #: ../fdroidserver/install.py msgid "Automatic yes to all prompts." -msgstr "" +msgstr "Bütün sorulara otomatik olarak evet." #: ../fdroidserver/index.py #, python-brace-format @@ -360,6 +363,11 @@ 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/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "{path} okunamadı: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -396,7 +404,7 @@ msgstr "Temiz güncelleme - önbellekleri kullanmaz, tüm APKları yeniden işle #: ../fdroidserver/common.py msgid "Color the log output" -msgstr "" +msgstr "Günlük çıktısını renklendir" #: ../fdroidserver/import_subcommand.py msgid "Comma separated list of categories." @@ -413,7 +421,7 @@ msgstr "Değişiklikleri işle" #: ../fdroidserver/checkupdates.py msgid "Commit changes, push, then make a merge request" -msgstr "" +msgstr "Değişiklikleri uygula, yükle ve bir birleştirme isteği yap" #: ../fdroidserver/metadata.py #, python-brace-format @@ -482,9 +490,9 @@ msgid "Creating \"{path}\" for configuring s3cmd." msgstr "s3cmd yapılandırması için \"{path}\" oluşturuluyor." #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Creating empty {config_file}" -msgstr "'{config_file}' okunuyor" +msgstr "Boş {config_file} oluşturuluyor" #: ../fdroidserver/publish.py msgid "Creating log directory" @@ -598,7 +606,7 @@ msgstr "Rsync sağlama toplamlarını kullanma" #: ../fdroidserver/install.py msgid "Download F-Droid.apk using mirrors that leak less to the network" -msgstr "" +msgstr "F-Droid.apk'yı ağa az bilgi sızdıracak şekilde indir" #: ../fdroidserver/__main__.py msgid "Download complete mirrors of small repos" @@ -654,12 +662,12 @@ msgstr "HATA: {path} içindeki {key} \"archive\" veya \"repo\" değil!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key} not a valid key!" -msgstr "" +msgstr "HATA: {key} geçerli bir anahtar değil!" #: ../fdroidserver/lint.py #, python-brace-format msgid "ERROR: {key}'s value should be of type {t}!" -msgstr "" +msgstr "Hata: {key} anahtarının değeri {t} tipinde olmalı!" #: ../fdroidserver/lint.py #, python-brace-format @@ -686,9 +694,9 @@ msgid "Environment variable {var} from {configname} is not set!" msgstr "{configname} içinden {var} ortam değişkeni ayarlı değil!" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment variable {{env: {var}}} is not set!" -msgstr "{configname} içinden {var} ortam değişkeni ayarlı değil!" +msgstr "Ortam değişkeni {{env: {var}}} ayarlanmadı!" #: ../fdroidserver/deploy.py msgid "Error deploying 'github_releases', {} not present. (You might need to run `fdroid update` first.)" @@ -712,7 +720,7 @@ msgstr "APK'lardan imzaları ayıkla" #: ../fdroidserver/install.py msgid "F-Droid.apk could not be downloaded from any known source!" -msgstr "" +msgstr "F-Droid.apk bilinen kaynakların hiç birinden indirilemedi!" #: ../fdroidserver/update.py #, python-brace-format @@ -930,9 +938,9 @@ msgid "Ignoring bad element in manifest: %s" msgstr "Manifestteki hatalı öğe yok sayılıyor: %s" #: ../fdroidserver/common.py -#, fuzzy, python-brace-format +#, python-brace-format msgid "Ignoring deprecated {oldfile}, use {newfile}!" -msgstr "{oldfile} kullanımdan kaldırıldı, {newfile} kullanın" +msgstr "{oldfile} kullanımdan kaldırıldı, {newfile} kullanın!" #: ../fdroidserver/index.py msgid "Ignoring package without metadata: " @@ -1140,7 +1148,7 @@ msgstr "ZIP dosyasında azami özyineleme derinliğine ulaşıldı: %s" #: ../fdroidserver/index.py #, python-brace-format msgid "Mirror config for {url} contains \"isPrimary\" key!" -msgstr "" +msgstr "{url} için yansı yapılandırması \"isPrimary\" anahtarını içeriyor!" #: ../fdroidserver/mirror.py msgid "Mirror the full repo and archive, all file types." @@ -1173,7 +1181,7 @@ msgstr "Bağlı aygıt bulunamadı" #: ../fdroidserver/install.py msgid "No devices found for `adb install`! Please plug one in." -msgstr "" +msgstr "`adb install` için aygıt bulunamadı! Lütfen bir tane takın." #: ../fdroidserver/index.py msgid "No fingerprint in URL." @@ -1307,7 +1315,7 @@ msgstr "Grafikler için yalnızca PNG ve JPEG desteklenir, bulunan: {path}" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/common.py msgid "Only accepts a single key \"env\"" -msgstr "" +msgstr "Sadece bir tane anahtar \"env\" kabul edilir" #: ../fdroidserver/checkupdates.py msgid "Only process apps with auto-updates" @@ -1377,7 +1385,7 @@ msgstr "Kolay kopyala yapıştır için gizli değişkeni terminale yaz" #: ../fdroidserver/install.py #, python-brace-format msgid "Privacy mode was enabled based on your locale ({country_code})." -msgstr "" +msgstr "Yerel ayarınız ({country_code}) baz alınarak gizlilik kipi etkinleştirildi." #: ../fdroidserver/scanner.py #, python-format @@ -1468,11 +1476,11 @@ msgstr "Tarayıcı kurallarını ve imzalarını ağdan yenile ve önbelleğe al #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "'{path}' imzalanması reddedildi, dosya hem {dir1} hem de {dir2} dizininde yer alıyor." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." -msgstr "" +msgstr "Başarıyla doğrulanmışsa, kaynak sıkıştırılmış dosyayı ve var olan bütün APK'ları kaldır." #: ../fdroidserver/common.py msgid "Removing specified files" @@ -1487,6 +1495,11 @@ msgstr "\"{path}\" kaldırılıyor" msgid "Rename APK files that do not match package.name_123.apk" msgstr "paket.adı_123.apk örüntüsüyle eşleşmeyen tüm APK dosyalarını yeniden adlandır" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1503,7 +1516,7 @@ msgstr "Çıkışı uyarılara ve hatalara kısıtla" #: ../fdroidserver/net.py #, python-format msgid "Retrying failed download: %s" -msgstr "" +msgstr "Başarısız indirme tekrar deneniyor: %s" #: ../fdroidserver/__main__.py msgid "Rewrite all the metadata files" @@ -1572,7 +1585,7 @@ msgstr[1] "Tarayıcı {} sorun buldu" #: ../fdroidserver/scanner.py msgid "Scanning APK for extra signing blocks." -msgstr "" +msgstr "APK'daki ekstra imzalama blokları taranıyor." #: ../fdroidserver/scanner.py msgid "Scanning APK with dexdump for known non-free classes." @@ -1696,7 +1709,7 @@ msgstr "Sınama kipi - çıkışı sadece tmp dizinine koy, ve her zaman inşa e #: ../fdroidserver/index.py msgid "The \"qrcode\" Python package is not installed (e.g. apt-get install python3-qrcode)!" -msgstr "" +msgstr "\"qrcode\" Python paketi kurulu değil (yüklemek için: apt-get install python3-qrcode)!" #. Translators: https://developer.android.com/guide/topics/manifest/manifest-element.html#vcode #: ../fdroidserver/update.py @@ -2000,20 +2013,24 @@ msgstr "İndeks imzası doğrulanıyor:" #: ../fdroidserver/install.py #, python-brace-format msgid "Verifying package {path} with apksigner." -msgstr "" +msgstr "{path} paketi apksigner ile doğrulanıyor." #: ../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." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Olası üst veri hataları hakkında uyar" #: ../fdroidserver/scanner.py msgid "WebAssembly binary file" -msgstr "" +msgstr "WebAssembly ikilik dosyası" #: ../fdroidserver/update.py msgid "When configured for signed indexes, create only unsigned indexes at this stage" @@ -2029,11 +2046,11 @@ msgstr "İmzalama veya doğrulama başarısız olduğunda, bir hata koduyla çı #: ../fdroidserver/install.py msgid "Would you like to download and install F-Droid.apk via adb? (YES/no)" -msgstr "" +msgstr "F-Droid.apk'nın adb aracılığıyla indirilmesini ve yüklenmesini ister misiniz? (EVET/hayır)" #: ../fdroidserver/install.py msgid "Would you like to download the app(s) from f-droid.org? (YES/no)" -msgstr "" +msgstr "Uygulamaları f-droid.org adresinden indirmek ister misiniz? (EVET/hayır)" #: ../fdroidserver/init.py msgid "X.509 'Distinguished Name' used when generating keys" @@ -2050,7 +2067,7 @@ msgstr "ZIP dosya arşivi" #: ../fdroidserver/install.py #, python-brace-format msgid "adb reports {serial} is \"{status}\"!" -msgstr "" +msgstr "adb {serial} için {status} durumunu veriyor!" #: ../fdroidserver/nightly.py #, python-brace-format @@ -2467,7 +2484,7 @@ msgstr "şu argümanlar gerekli: %s" #: ../fdroidserver/install.py msgid "true" -msgstr "" +msgstr "doğru" #: /usr/lib/python3.11/argparse.py #, python-format @@ -2504,7 +2521,7 @@ msgstr "virustotal.com hızı sınırlıyor, yeniden deneme bekleniyor..." #: ../fdroidserver/install.py msgid "yes" -msgstr "" +msgstr "evet" #: ../fdroidserver/publish.py #, python-brace-format @@ -2594,7 +2611,7 @@ msgstr "{name} \"{section}/icons/{path}\" yok! config.yml içinde düzeltin." #: ../fdroidserver/update.py #, python-brace-format msgid "{path1} is a duplicate of {path2}, remove one!" -msgstr "" +msgstr "{path1}, {path2} 'in bir kopyasıdır, birini kaldırın!" #: ../fdroidserver/import_subcommand.py #, python-brace-format @@ -2619,7 +2636,7 @@ msgstr "{path} virustotal tarafından {count} defa işaretlendi:" #: ../fdroidserver/install.py #, python-brace-format msgid "{path} has the wrong fingerprint ({fingerprint})!" -msgstr "" +msgstr "{path} yanlış {fingerprint} parmak izine sahip!" #: ../fdroidserver/common.py #, python-brace-format diff --git a/locale/tzm/LC_MESSAGES/fdroidserver.po b/locale/tzm/LC_MESSAGES/fdroidserver.po index 705a018c..fcfc7527 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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2020-10-29 08:32+0000\n" "Last-Translator: Hakim Oubouali \n" "Language-Team: Central Atlas Tamazight \n" @@ -353,6 +353,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1478,6 +1483,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1991,6 +2001,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/ug/LC_MESSAGES/fdroidserver.po b/locale/ug/LC_MESSAGES/fdroidserver.po index e4565e46..82346c03 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: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2018-06-08 03:44+0000\n" "Last-Translator: ۋولقان \n" "Language-Team: Uyghur \n" @@ -354,6 +354,11 @@ msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "" msgstr[1] "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1480,6 +1485,11 @@ msgstr "" msgid "Rename APK files that do not match package.name_123.apk" msgstr "" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -1993,6 +2003,10 @@ msgstr "" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "" diff --git a/locale/uk/LC_MESSAGES/fdroidserver.po b/locale/uk/LC_MESSAGES/fdroidserver.po index 9a4a57f9..822f3358 100644 --- a/locale/uk/LC_MESSAGES/fdroidserver.po +++ b/locale/uk/LC_MESSAGES/fdroidserver.po @@ -17,8 +17,8 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-24 14:02+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-03-27 19:35+0000\n" "Last-Translator: Ihor Hordiichuk \n" "Language-Team: Ukrainian \n" "Language: uk\n" @@ -370,6 +370,11 @@ msgstr[0] "Неможливо створити через {} помилку пі msgstr[1] "Неможливо створити через {} помилки під час сканування" msgstr[2] "Неможливо створити через {} помилок під час сканування" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "Не вдалося розпізнати {path}: {error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1478,7 +1483,7 @@ msgstr "Оновлення та кешування правил і сигнат #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "Відмова підписати '{path}', файл існує в теках {dir1} і {dir2}." #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1497,6 +1502,11 @@ msgstr "Вилучення {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "Перейменування файлів APK, які не відповідають package.name_123.apk" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2018,6 +2028,10 @@ msgstr "Перевірка пакета {path} за допомогою apksigner msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "Ключ API VirusTotal не може завантажити файли, розмір яких понад 32 МБ, використовуйте {url} для завантаження {path}." +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "Попереджати про можливі помилки метаданих" diff --git a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po index 918404df..6bb2b142 100644 --- a/locale/zh_Hans/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hans/LC_MESSAGES/fdroidserver.po @@ -39,8 +39,8 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" -"PO-Revision-Date: 2025-03-21 03:03+0000\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" +"PO-Revision-Date: 2025-03-26 10:00+0000\n" "Last-Translator: 大王叫我来巡山 \n" "Language-Team: Chinese (Simplified Han script) \n" "Language: zh_Hans\n" @@ -390,6 +390,11 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "因扫描时的{}错误而无法构建" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "读取 {path} 失败:{error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1498,7 +1503,7 @@ msgstr "刷新和缓存来自网络的扫描程序规则和签名" #: ../fdroidserver/publish.py #, python-brace-format msgid "Refusing to sign '{path}', file exists in both {dir1} and {dir2} folder." -msgstr "" +msgstr "拒绝签署 '{path}',文件同时存在于文件夹 {dir1} 和 {dir2}。" #: ../fdroidserver/verify.py msgid "Remove source tarball and any APKs if successfully verified." @@ -1517,6 +1522,11 @@ msgstr "删除 {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "重命名文件名不符合 package.name_123.apk 的 APK 文件" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2036,6 +2046,10 @@ msgstr "使用 apksigner 验证包 {path}。" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "VirusTotal 的 API 密钥无法用于上传大于 32MB 的文件,请使用 {url} 上传 {path}。" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "警告元数据中可能存在的错误" diff --git a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po index 4516afc7..e2358e7e 100644 --- a/locale/zh_Hant/LC_MESSAGES/fdroidserver.po +++ b/locale/zh_Hant/LC_MESSAGES/fdroidserver.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: fdroidserver 0.9\n" "Report-Msgid-Bugs-To: https://gitlab.com/fdroid/fdroidserver/issues\n" -"POT-Creation-Date: 2025-03-25 11:36+0100\n" +"POT-Creation-Date: 2025-06-25 09:52+0200\n" "PO-Revision-Date: 2024-11-26 15:16+0000\n" "Last-Translator: Peter Dave Hello \n" "Language-Team: Chinese (Traditional Han script) \n" @@ -362,6 +362,11 @@ msgid "Can't build due to {} error while scanning" msgid_plural "Can't build due to {} errors while scanning" msgstr[0] "掃描時由於 {} 出錯,無法進行編譯" +#: ../fdroidserver/common.py +#, fuzzy, python-brace-format +msgid "Cannot read {path}: {error}" +msgstr "讀取 {path} 失敗:錯誤訊息{error}" + #: ../fdroidserver/rewritemeta.py #, python-brace-format msgid "Cannot rewrite \"{path}\"" @@ -1509,6 +1514,11 @@ msgstr "正在移除 {path}\"" msgid "Rename APK files that do not match package.name_123.apk" msgstr "為不符合 package.name_123.apk 格式的 APK 檔案更名" +#: ../fdroidserver/common.py +#, python-brace-format +msgid "RepoType {type} is deprecated, please switch to git." +msgstr "" + #: ../fdroidserver/nightly.py #, python-brace-format msgid "Resigning {apkfilename} with provided debug.keystore" @@ -2045,6 +2055,10 @@ msgstr "正在使用 apksigner 驗證套件 {path}。" msgid "VirusTotal API key cannot upload files larger than 32MB, use {url} to upload {path}." msgstr "VirusTotal API key 無法上傳大於 32MB 的檔案, 選擇使用 {url} 來上傳檔案 {path} 。" +#: ../fdroidserver/nightly.py +msgid "WARNING: only public git repos are supported!" +msgstr "" + #: ../fdroidserver/__main__.py msgid "Warn about possible metadata errors" msgstr "關於中介資料可能錯誤的警告" diff --git a/makebuildserver b/makebuildserver index a4a27060..34962ca7 100755 --- a/makebuildserver +++ b/makebuildserver @@ -48,17 +48,17 @@ logging.basicConfig(format=logformat, level=loglevel) tail = None BASEBOX_DEFAULT = 'debian/bookworm64' -BASEBOX_VERSION_DEFAULT = "12.20241217.1" +BASEBOX_VERSION_DEFAULT = "12.20250126.1" BASEBOX_CHECKSUMS = { - "12.20241217.1": { + "12.20250126.1": { "libvirt": { - "box.img": "7cda96dd706fe5c4eba8210abc944b047842ee6655167933cb7d5ea99cb962bb", + "box.img": "64eb111ab8b0785253c7542caaa7f560d4532b8133266ec94804882d209017d3", "Vagrantfile": "f9c6fcbb47a4d0d33eb066859c8e87efd642287a638bd7da69a9e7a6f25fec47", "metadata.json": "20dc0268a79410dbf01c7e544ba5138f6f695a298b53c56c87a25f68c5031173", }, "virtualbox": { - "box.ovf": "abc34993d37a85a9f89506621bdb3e2cb11eda7c7f6b2d19de9e866264031532", - "box.vmdk": "62a2991aa9543b64cc273c545dc2403adf844644253c9fe162632030c4dd21c4", + "box.ovf": "d8493bdfc4c42b5f66b815efe2a90d20b639eb2ce12cc8c7c51a3039674d146a", + "box.vmdk": "6927001058f57b325544c399297c41ec9c6fbfc21cb764b58f2ff0495864a4fa", "Vagrantfile": "0bbc2ae97668d8da27ab97b766752dcd0bf9e41900e21057de15a58ee7fae47d", "metadata.json": "ffdaa989f2f6932cd8042e1102371f405cc7ad38e324210a1326192e4689e83a", } diff --git a/pyproject.toml b/pyproject.toml index bd209935..c0ae09c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,6 @@ force-exclude = '''( | examples/fdroid_exportkeystore\.py | examples/fdroid_fetchsrclibs\.py | examples/fdroid_nitrokeyimport\.py - | fdroidserver/__init__\.py | fdroidserver/__main__\.py | fdroidserver/apksigcopier\.py | fdroidserver/looseversion\.py @@ -39,7 +38,6 @@ force-exclude = '''( | fdroidserver/common\.py | fdroidserver/index\.py | fdroidserver/metadata\.py - | fdroidserver/nightly\.py | fdroidserver/update\.py | fdroidserver/vmtools\.py | tests/config\.py @@ -78,7 +76,7 @@ disable_error_code = "no-redef, misc, arg-type" # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the # number of processors available to use, and will cap the count on Windows to # avoid hangs. -jobs = 4 +jobs = 0 # Minimum Python version to use for version dependent checks. Will default to the # version used to run pylint. @@ -87,10 +85,6 @@ py-version = "3.9" # Files or directories to be skipped. They should be base names, not paths. ignore = ["apksigcopier.py", "looseversion.py"] -[tool.pylint.basic] -# Good variable names which should always be accepted, separated by a comma. -good-names = ["i", "j", "k", "ex", "Run", "f", "fp"] - [tool.pylint."messages control"] # Only show warnings with the listed confidence levels. Leave empty to show all. # Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, UNDEFINED. diff --git a/setup.py b/setup.py index 377c2409..e6d374a8 100755 --- a/setup.py +++ b/setup.py @@ -70,7 +70,7 @@ with open("README.md", "r") as fh: setup( name='fdroidserver', - version='2.4.0', + version='2.4.2', description='F-Droid Server Tools', long_description=long_description, long_description_content_type='text/markdown', @@ -116,7 +116,7 @@ setup( # Some requires are only needed for very limited cases: # * biplist is only used for parsing Apple .ipa files # * pycountry is only for linting config/mirrors.yml - # * python-magic is preferred when libmagic is available, but its not in pypi.org + # * python-magic is preferred when the C library libmagic is installed extras_require={ 'optional': [ 'biplist', diff --git a/tests/config/antiFeatures.yml b/tests/config/antiFeatures.yml index 06d794a1..cb4dc676 100644 --- a/tests/config/antiFeatures.yml +++ b/tests/config/antiFeatures.yml @@ -39,7 +39,3 @@ Tracking: description: This app tracks and reports your activity icon: ic_antifeature_tracking.xml name: Tracking -UpstreamNonFree: - description: The upstream source code is not entirely Free - icon: ic_antifeature_upstreamnonfree.xml - name: Upstream Non-Free diff --git a/tests/config/de/antiFeatures.yml b/tests/config/de/antiFeatures.yml index 3053e41a..65111db1 100644 --- a/tests/config/de/antiFeatures.yml +++ b/tests/config/de/antiFeatures.yml @@ -38,7 +38,3 @@ Tracking: description: Diese App verfolgt und versendet Ihre Aktivitäten icon: ic_antifeature_tracking.xml name: Tracking -UpstreamNonFree: - description: Der Originalcode ist nicht völlig quelloffen - icon: ic_antifeature_upstreamnonfree.xml - name: Originalcode nicht-quelloffen diff --git a/tests/config/fa/antiFeatures.yml b/tests/config/fa/antiFeatures.yml index 554dcee9..aa8290ef 100644 --- a/tests/config/fa/antiFeatures.yml +++ b/tests/config/fa/antiFeatures.yml @@ -37,7 +37,3 @@ Tracking: description: این کاره، فعّالیتتان را ردیابی و گزارش می‌کند icon: ic_antifeature_tracking.xml name: ردیابی -UpstreamNonFree: - description: کد مبدأ بالادستی کاملاً آزاد نیست - icon: ic_antifeature_upstreamnonfree.xml - name: بالادست ناآزاد diff --git a/tests/config/ro/antiFeatures.yml b/tests/config/ro/antiFeatures.yml index 97d61172..9610b448 100644 --- a/tests/config/ro/antiFeatures.yml +++ b/tests/config/ro/antiFeatures.yml @@ -38,7 +38,3 @@ Tracking: description: Aplicația îți înregistrează și raportează activitatea undeva icon: ic_antifeature_tracking.xml name: Urmărire -UpstreamNonFree: - description: Codul sursa originar nu este în totalitatea lui software liber - icon: ic_antifeature_upstreamnonfree.xml - name: Surse ne-libere diff --git a/tests/config/zh-rCN/antiFeatures.yml b/tests/config/zh-rCN/antiFeatures.yml index a1b287b9..2c9f0819 100644 --- a/tests/config/zh-rCN/antiFeatures.yml +++ b/tests/config/zh-rCN/antiFeatures.yml @@ -37,7 +37,3 @@ Tracking: description: 此应用会记录并报告你的活动 icon: ic_antifeature_tracking.xml name: 跟踪用户 -UpstreamNonFree: - description: 上游源代码不是完全自由的 - icon: ic_antifeature_upstreamnonfree.xml - name: 上游代码非自由 diff --git a/tests/dump_internal_metadata_format.py b/tests/dump_internal_metadata_format.py index f9763ebc..ffc72059 100755 --- a/tests/dump_internal_metadata_format.py +++ b/tests/dump_internal_metadata_format.py @@ -25,7 +25,6 @@ import sys from argparse import ArgumentParser import git - import yaml localmodule = os.path.realpath( diff --git a/tests/extra/manual-vmtools-test.py b/tests/extra/manual-vmtools-test.py index 0f0c745b..2f01c9ff 100755 --- a/tests/extra/manual-vmtools-test.py +++ b/tests/extra/manual-vmtools-test.py @@ -4,12 +4,12 @@ # that run in the buildserver setup. It is not really maintained, but # is still here as a kind of reference. +import inspect +import logging import os import sys -import logging -import textwrap import tempfile -import inspect +import textwrap from argparse import ArgumentParser localmodule = os.path.realpath( diff --git a/tests/get-country-region-data.py b/tests/get-country-region-data.py index f0f52e4b..240d70b2 100755 --- a/tests/get-country-region-data.py +++ b/tests/get-country-region-data.py @@ -5,11 +5,12 @@ import collections import os import re -import requests -import requests_cache import sys import tempfile +import requests +import requests_cache + def main(): # we want all the data diff --git a/tests/gradle-release-checksums.py b/tests/gradle-release-checksums.py index 0c190ebf..53ceb1a5 100755 --- a/tests/gradle-release-checksums.py +++ b/tests/gradle-release-checksums.py @@ -1,16 +1,14 @@ #!/usr/bin/env python3 -import git -import gitlab import os import re -import requests import subprocess import sys + +import requests from colorama import Fore, Style from packaging.version import Version - checksums = None versions = dict() @@ -64,88 +62,6 @@ for version in sorted(versions.keys()): with open('makebuildserver', 'w') as fp: fp.write(makebuildserver_current) -# write out update to gradlew-fdroid -with open('gradlew-fdroid') as fp: - gradlew_fdroid = fp.read() -current = '' -get_sha_pat = re.compile(r""" +'([0-9][0-9.]+[0-9])'\)\s+echo '([0-9a-f]{64})' ;;\n""") -for m in get_sha_pat.finditer(gradlew_fdroid): - current += m.group() - checksum = m.group(2) - if checksum != versions[m.group(1)]: - print(Fore.RED - + 'ERROR: checksum mismatch:', checksum, versions[m.group(1)] - + Style.RESET_ALL) - errors += 1 -new = '' -for version in sorted(versions.keys(), key=Version): - sha256 = versions[version] - spaces = '' - for i in range(6 - len(version)): - spaces += ' ' - new += """ '%s')%s echo '%s' ;;\n""" % (version, spaces, sha256) -gradlew_fdroid = gradlew_fdroid.replace(current, new) -plugin_v = ' '.join(sorted(versions.keys(), key=Version, reverse=True)) -plugin_v_pat = re.compile(r'\nplugin_v=\(([0-9. ]+)\)') -with open('gradlew-fdroid', 'w') as fp: - fp.write(plugin_v_pat.sub('\nplugin_v=(%s)' % plugin_v, gradlew_fdroid)) - -if os.getenv('CI_PROJECT_NAMESPACE') != 'fdroid': - p = subprocess.run(['git', '--no-pager', 'diff']) - print(p.stdout) - sys.exit(errors) - -# This only runs after commits are pushed to fdroid/fdroidserver -git_repo = git.repo.Repo('.') -modified = git_repo.git().ls_files(modified=True).split() -if git_repo.is_dirty() and ('gradlew-fdroid' in modified or 'makebuildserver' in modified): - private_token = os.getenv('PERSONAL_ACCESS_TOKEN') - if not private_token: - print(Fore.RED - + 'ERROR: GitLab Token not found in PERSONAL_ACCESS_TOKEN!' - + Style.RESET_ALL) - sys.exit(1) - - branch = git_repo.create_head(os.path.basename(__file__), force=True) - branch.checkout() - git_repo.index.add(['gradlew-fdroid', 'makebuildserver']) - author = git.Actor('fdroid-bot', 'fdroid-bot@f-droid.org') - git_repo.index.commit('gradle v' + version, author=author) - project_path = 'fdroid-bot/' + os.getenv('CI_PROJECT_NAME') - url = ('https://gitlab-ci-token:%s@%s/%s.git' - % (os.getenv('PERSONAL_ACCESS_TOKEN'), os.getenv('CI_SERVER_HOST'), project_path)) - remote_name = 'fdroid-bot' - try: - remote = git_repo.create_remote(remote_name, url) - # See https://github.com/PyCQA/pylint/issues/2856 . - # pylint: disable-next=no-member - except git.exc.GitCommandError: - remote = git.remote.Remote(git_repo, remote_name) - remote.set_url(url) - remote.push(force=True) - git.remote.Remote.rm(git_repo, remote_name) - - gl = gitlab.Gitlab(os.getenv('CI_SERVER_URL'), api_version=4, - private_token=private_token) - project = gl.projects.get(project_path, lazy=True) - description = ( - 'see ' - '\n\n

generated by GitLab CI Job #%s

' - % (os.getenv('CI_PROJECT_URL'), os.getenv('CI_JOB_ID'), os.getenv('CI_JOB_ID')) - ) - try: - mr = project.mergerequests.create({ - 'source_branch': branch.name, - 'target_project_id': 36527, # fdroid/fdroidserver - 'target_branch': 'master', - 'title': 'update to gradle v' + version, - 'description': description, - 'labels': ['fdroid-bot', 'gradle'], - 'remove_source_branch': True, - }) - mr.save() - except gitlab.exceptions.GitlabCreateError as e: - if e.response_code == 409: # Another open merge request already exists for this source branch - print(e.error_message) - else: - raise e +p = subprocess.run(['git', '--no-pager', 'diff']) +errors += p.returncode +sys.exit(errors) diff --git a/tests/key-tricks.py b/tests/key-tricks.py index 7fc0f3ea..a01bf0bf 100755 --- a/tests/key-tricks.py +++ b/tests/key-tricks.py @@ -1,9 +1,10 @@ #!/usr/bin/env python3 import os -import fdroidserver import shutil import sys + +import fdroidserver from fdroidserver import common, nightly if os.getenv('CI') is None: diff --git a/tests/metadata-rewrite-yml/app.with.special.build.params.yml b/tests/metadata-rewrite-yml/app.with.special.build.params.yml index 0fc97b65..95c1695c 100644 --- a/tests/metadata-rewrite-yml/app.with.special.build.params.yml +++ b/tests/metadata-rewrite-yml/app.with.special.build.params.yml @@ -1,5 +1,5 @@ AntiFeatures: - - UpstreamNonFree + - Tracking Categories: - System License: GPL-3.0-only diff --git a/tests/metadata/app.with.special.build.params.yml b/tests/metadata/app.with.special.build.params.yml index d12c713c..c58cadf1 100644 --- a/tests/metadata/app.with.special.build.params.yml +++ b/tests/metadata/app.with.special.build.params.yml @@ -1,5 +1,5 @@ AntiFeatures: - - UpstreamNonFree + - Tracking Categories: - System License: GPL-3.0-only diff --git a/tests/metadata/com.politedroid.yml b/tests/metadata/com.politedroid.yml index cd474d6c..87d13bcb 100644 --- a/tests/metadata/com.politedroid.yml +++ b/tests/metadata/com.politedroid.yml @@ -22,7 +22,6 @@ Builds: target: android-10 antifeatures: - KnownVuln - - UpstreamNonFree - NonFreeAssets - versionName: '1.3' @@ -43,7 +42,6 @@ Builds: - yes antifeatures: - KnownVuln - - UpstreamNonFree - NonFreeAssets ArchivePolicy: 4 versions diff --git a/tests/metadata/dump/app.with.special.build.params.yaml b/tests/metadata/dump/app.with.special.build.params.yaml index 9f2c61f6..fae6c9ae 100644 --- a/tests/metadata/dump/app.with.special.build.params.yaml +++ b/tests/metadata/dump/app.with.special.build.params.yaml @@ -2,7 +2,7 @@ --- AllowedAPKSigningKeys: [] AntiFeatures: - UpstreamNonFree: {} + Tracking: {} ArchivePolicy: 0 AuthorEmail: null AuthorName: null diff --git a/tests/metadata/dump/com.politedroid.yaml b/tests/metadata/dump/com.politedroid.yaml index b4d56c3e..01d55b82 100644 --- a/tests/metadata/dump/com.politedroid.yaml +++ b/tests/metadata/dump/com.politedroid.yaml @@ -19,7 +19,6 @@ Builds: antifeatures: KnownVuln: {} NonFreeAssets: {} - UpstreamNonFree: {} binary: null build: '' buildjni: [] @@ -127,7 +126,6 @@ Builds: antifeatures: KnownVuln: {} NonFreeAssets: {} - UpstreamNonFree: {} binary: null build: '' buildjni: [] diff --git a/tests/openssl-version-check-test.py b/tests/openssl-version-check-test.py index d4022126..69a1ff59 100755 --- a/tests/openssl-version-check-test.py +++ b/tests/openssl-version-check-test.py @@ -6,6 +6,7 @@ # This is used in update.has_known_vulnerability() import re + import requests # this list was generated using: diff --git a/tests/repo/entry.json b/tests/repo/entry.json index 1eb017bc..85b6b14f 100644 --- a/tests/repo/entry.json +++ b/tests/repo/entry.json @@ -3,8 +3,8 @@ "version": 20002, "index": { "name": "/index-v2.json", - "sha256": "f0912b64db80168ee807f43ab3470bb709b6659aee05ad63057dcbcd1c97dc5e", - "size": 55186, + "sha256": "94dca5f4398d2a0167bbe69c790cdd66f1bc305ca5e362ee5e3f793e9f88e3cf", + "size": 53355, "numPackages": 11 }, "diffs": {} diff --git a/tests/repo/index-v1.json b/tests/repo/index-v1.json index ed1cbcde..03f8f060 100644 --- a/tests/repo/index-v1.json +++ b/tests/repo/index-v1.json @@ -244,8 +244,7 @@ "added": 1498176000000, "antiFeatures": [ "KnownVuln", - "NonFreeAssets", - "UpstreamNonFree" + "NonFreeAssets" ], "apkName": "com.politedroid_6.apk", "hash": "70c2f776a2bac38a58a7d521f96ee0414c6f0fb1de973c3ca8b10862a009247d", @@ -332,8 +331,7 @@ "added": 1498176000000, "antiFeatures": [ "KnownVuln", - "NonFreeAssets", - "UpstreamNonFree" + "NonFreeAssets" ], "apkName": "com.politedroid_3.apk", "hash": "665d03d61ebc642289fda697f71a59305b0202b16cafc5ffdae91cbe91f0b25d", diff --git a/tests/repo/index-v2.json b/tests/repo/index-v2.json index 96c2cfea..263dffd2 100644 --- a/tests/repo/index-v2.json +++ b/tests/repo/index-v2.json @@ -453,49 +453,6 @@ "ro": "Urmărire", "zh-rCN": "跟踪用户" } - }, - "UpstreamNonFree": { - "description": { - "de": "Der Originalcode ist nicht völlig quelloffen", - "en-US": "The upstream source code is not entirely Free", - "fa": "کد مبدأ بالادستی کاملاً آزاد نیست", - "ro": "Codul sursa originar nu este în totalitatea lui software liber", - "zh-rCN": "上游源代码不是完全自由的" - }, - "icon": { - "de": { - "name": "/icons/ic_antifeature_upstreamnonfree.xml", - "sha256": "06a9af843ff56ecd7a270f98c0b19b3154edf3ffa854e6d50a84ef00d0ce1a86", - "size": 1442 - }, - "en-US": { - "name": "/icons/ic_antifeature_upstreamnonfree.xml", - "sha256": "06a9af843ff56ecd7a270f98c0b19b3154edf3ffa854e6d50a84ef00d0ce1a86", - "size": 1442 - }, - "fa": { - "name": "/icons/ic_antifeature_upstreamnonfree.xml", - "sha256": "06a9af843ff56ecd7a270f98c0b19b3154edf3ffa854e6d50a84ef00d0ce1a86", - "size": 1442 - }, - "ro": { - "name": "/icons/ic_antifeature_upstreamnonfree.xml", - "sha256": "06a9af843ff56ecd7a270f98c0b19b3154edf3ffa854e6d50a84ef00d0ce1a86", - "size": 1442 - }, - "zh-rCN": { - "name": "/icons/ic_antifeature_upstreamnonfree.xml", - "sha256": "06a9af843ff56ecd7a270f98c0b19b3154edf3ffa854e6d50a84ef00d0ce1a86", - "size": 1442 - } - }, - "name": { - "de": "Originalcode nicht-quelloffen", - "en-US": "Upstream Non-Free", - "fa": "بالادست ناآزاد", - "ro": "Surse ne-libere", - "zh-rCN": "上游代码非自由" - } } }, "categories": { @@ -627,8 +584,7 @@ "en-US": "1.5" }, "NonFreeAssets": {}, - "NonFreeNet": {}, - "UpstreamNonFree": {} + "NonFreeNet": {} } }, "5bdbfa071cca4b8d05ced41d6b28763595d6e8096cca5bbf0f9253c9a2622e5d": { @@ -756,8 +712,7 @@ "en-US": "1.5" }, "NonFreeAssets": {}, - "NonFreeNet": {}, - "UpstreamNonFree": {} + "NonFreeNet": {} } } } diff --git a/tests/repo/index.xml b/tests/repo/index.xml index 4036a6f7..04e8f87d 100644 --- a/tests/repo/index.xml +++ b/tests/repo/index.xml @@ -346,7 +346,7 @@ APK is called F-Droid Privileged Extension. https://github.com/miguelvps/PoliteDroid/issues 1.5 6 - KnownVuln,NoSourceSince,NonFreeAssets,NonFreeNet,UpstreamNonFree + KnownVuln,NoSourceSince,NonFreeAssets,NonFreeNet 1.5 6 diff --git a/tests/shared_test_code.py b/tests/shared_test_code.py index 59f515a7..3e34900b 100644 --- a/tests/shared_test_code.py +++ b/tests/shared_test_code.py @@ -20,10 +20,8 @@ import sys import tempfile import unittest import unittest.mock - from pathlib import Path - GP_FINGERPRINT = 'B7C2EEFD8DAC7806AF67DFCD92EB18126BC08312A7F2D6F3862E46013C7A6135' diff --git a/tests/source-files/flavor.test/build.gradle b/tests/source-files/flavor.test/build.gradle new file mode 100644 index 00000000..2c958bdc --- /dev/null +++ b/tests/source-files/flavor.test/build.gradle @@ -0,0 +1,15 @@ +dependenies { + /// dependencies for app building + fossImplementation 'com.android.support:multidex:1.0.2' + implementation 'com.github.nextcloud:android-library:1.0.33' + devImplementation 'com.github.nextcloud:android-library:master-SNAPSHOT' // use always latest master + implementation "com.android.support:support-v4:${supportLibraryVersion}" + prodImplementation "com.android.support:design:${supportLibraryVersion}" + gplayImplementation 'com.jakewharton:disklrucache:2.0.2' + implementation "com.android.support:appcompat-v7:${supportLibraryVersion}" + gplayProdImplementation "com.android.support:cardview-v7:${supportLibraryVersion}" + implementation "com.android.support:exifinterface:${supportLibraryVersion}" + fossDevImplementation 'com.github.tobiasKaminsky:android-floating-action-button:1.10.2' + gplayDevImplementation 'com.github.albfernandez:juniversalchardet:v2.0.0' + fossProdImplementation 'com.google.code.findbugs:annotations:2.0.1' +} diff --git a/tests/test_api.py b/tests/test_api.py index 6cb9a53b..ba18caa6 100755 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -8,8 +8,8 @@ from unittest import mock import fdroidserver from fdroidserver import common, signindex -from .shared_test_code import GP_FINGERPRINT, mkdtemp +from .shared_test_code import GP_FINGERPRINT, mkdtemp basedir = Path(__file__).parent diff --git a/tests/test_build.py b/tests/test_build.py index e8e6927e..578837ed 100755 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -6,15 +6,16 @@ import sys import tempfile import textwrap import unittest -import yaml from pathlib import Path from unittest import mock -from .shared_test_code import TmpCwd, mkdtemp +import yaml import fdroidserver.build import fdroidserver.common +from .shared_test_code import TmpCwd, mkdtemp + class FakeProcess: output = 'fake output' @@ -205,6 +206,7 @@ class BuildTest(unittest.TestCase): @mock.patch('fdroidserver.build.FDroidPopen') @mock.patch('fdroidserver.common.is_debuggable_or_testOnly', lambda f: False) @mock.patch('fdroidserver.common.get_native_code', lambda f: 'x86') + @mock.patch('fdroidserver.common.get_source_date_epoch', lambda f: '1234567890') def test_build_local_maven(self, fake_FDroidPopen, fake_get_apk_id): """Test build_local() with a maven project""" @@ -330,6 +332,8 @@ class BuildTest(unittest.TestCase): 'fdroidserver.build.FDroidPopen', FakeProcess ) as _ignored, mock.patch( 'sdkmanager.install', wraps=fake_sdkmanager_install + ) as _ignored, mock.patch( + 'fdroidserver.common.get_source_date_epoch', lambda f: '1234567890' ) as _ignored: _ignored # silence the linters with self.assertRaises( @@ -378,6 +382,7 @@ class BuildTest(unittest.TestCase): @mock.patch('fdroidserver.build.FDroidPopen', FakeProcess) @mock.patch('fdroidserver.common.get_native_code', lambda _ignored: 'x86') @mock.patch('fdroidserver.common.is_debuggable_or_testOnly', lambda _ignored: False) + @mock.patch('fdroidserver.common.get_source_date_epoch', lambda f: '1234567890') @mock.patch( 'fdroidserver.common.sha256sum', lambda f: 'ad7ce5467e18d40050dc51b8e7affc3e635c85bd8c59be62de32352328ed467e', @@ -453,6 +458,7 @@ class BuildTest(unittest.TestCase): self.assertTrue(ndk_dir.exists()) self.assertTrue(os.path.exists(config['ndk_paths'][ndk_version])) + @mock.patch('fdroidserver.common.get_source_date_epoch', lambda f: '1234567890') def test_build_local_clean(self): """Test if `fdroid build` cleans ant and gradle build products""" os.chdir(self.testdir) diff --git a/tests/test_checkupdates.py b/tests/test_checkupdates.py index fcd6f642..107caf29 100755 --- a/tests/test_checkupdates.py +++ b/tests/test_checkupdates.py @@ -1,19 +1,19 @@ #!/usr/bin/env python3 -import git import os import platform import shutil import tempfile import time import unittest -from unittest import mock from pathlib import Path +from unittest import mock + +import git import fdroidserver import fdroidserver.checkupdates - basedir = Path(__file__).parent @@ -696,3 +696,12 @@ class CheckupdatesTest(unittest.TestCase): push.assert_called_once() sys_exit.assert_called_once() self.assertIn(appid, git_repo.heads) + + def test_push_commits_invalid_branch_name(self): + git_repo, origin_repo, upstream_repo = self._get_test_git_repos() + for remote in git_repo.remotes: + remote.push(git_repo.active_branch) + self.assertEqual(git_repo.head, upstream_repo.head) + self.assertEqual(origin_repo.head, upstream_repo.head) + # pretend that checkupdates ran but didn't create any new commits + fdroidserver.checkupdates.push_commits('') diff --git a/tests/test_common.py b/tests/test_common.py index b9953c71..3110b446 100755 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -1,40 +1,44 @@ #!/usr/bin/env python3 import difflib -import git import glob +import gzip import importlib import json import logging import os import re -import ruamel.yaml import shutil import subprocess import sys import tempfile +import textwrap import time import unittest -import textwrap -import gzip from argparse import ArgumentParser from datetime import datetime, timezone -from zipfile import BadZipFile, ZipFile -from unittest import mock from pathlib import Path +from unittest import mock +from zipfile import BadZipFile, ZipFile +import git +import ruamel.yaml import fdroidserver -import fdroidserver.signindex import fdroidserver.common import fdroidserver.metadata -from .shared_test_code import TmpCwd, mkdtemp, mkdir_testfiles +import fdroidserver.signindex +from fdroidserver._yaml import config_dump, yaml, yaml_dumper from fdroidserver.common import ANTIFEATURES_CONFIG_NAME, CATEGORIES_CONFIG_NAME -from fdroidserver._yaml import yaml, yaml_dumper, config_dump -from fdroidserver.exception import FDroidException, VCSException,\ - MetaDataException, VerificationException +from fdroidserver.exception import ( + FDroidException, + MetaDataException, + VCSException, + VerificationException, +) from fdroidserver.looseversion import LooseVersion +from .shared_test_code import TmpCwd, mkdir_testfiles, mkdtemp basedir = Path(__file__).parent @@ -794,18 +798,6 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): self.assertEqual(keytoolcertfingerprint, fdroidserver.common.apk_signer_fingerprint(apkfile)) - @unittest.skipIf(sys.byteorder == 'big', 'androguard is not ported to big-endian') - def test_apk_signer_fingerprint_short(self): - - # fingerprints fetched with: keytool -printcert -file ____.RSA - testapks = (('repo/obb.main.oldversion_1444412523.apk', '818e469'), - ('repo/obb.main.twoversions_1101613.apk', '32a2362'), - ('repo/obb.main.twoversions_1101617.apk', '32a2362')) - - for apkfile, keytoolcertfingerprint in testapks: - self.assertEqual(keytoolcertfingerprint, - fdroidserver.common.apk_signer_fingerprint_short(apkfile)) - def test_find_apksigner_system_package_default_path(self): """apksigner should be automatically used from the PATH""" usr_bin_apksigner = '/usr/bin/apksigner' @@ -2041,6 +2033,49 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): config = fdroidserver.common.read_config() self.assertEqual('/usr/lib/jvm/java-8-openjdk', config['java_paths']['8']) + @mock.patch.dict(os.environ, {'PATH': os.getenv('PATH')}, clear=True) + def test_config_lazy_load_env_vars(self): + """Test the environment variables in config.yml is lazy loaded. + + It shouldn't throw errors when read the config if the environment variables are + not set. It should throw errors when the variables are get from the config. + """ + os.chdir(self.testdir) + fdroidserver.common.write_config_file( + textwrap.dedent( + """ + serverwebroot: {env: serverwebroot} + servergitmirrors: + - url: {env: mirror1} + - url: {env: mirror2} + keypass: {env: keypass} + keystorepass: {env: keystorepass} + """ + ) + ) + with self.assertNoLogs(level=logging.ERROR): + config = fdroidserver.common.read_config() + + # KeyError should be raised if a key is not in the config.yml + with self.assertRaises(KeyError): + config['gpghome'] + + self.assertEqual(config.get('gpghome', 'gpg'), 'gpg') + os.environ.update({key: f"{key}supersecret" for key in ["serverwebroot", "mirror1", "mirror2", "keystorepass"]}) + self.assertEqual(config['keystorepass'], 'keystorepasssupersecret') + self.assertEqual(config['serverwebroot'], [{'url': 'serverwebrootsupersecret/'}]) + self.assertEqual(config['servergitmirrors'], [{'url': 'mirror1supersecret'}, {'url': 'mirror2supersecret'}]) + + @mock.patch.dict(os.environ, {'PATH': os.getenv('PATH')}, clear=True) + def test_config_lazy_load_env_vars_not_set(self): + os.chdir(self.testdir) + fdroidserver.common.write_config_file('keypass: {env: keypass}') + fdroidserver.common.read_config() + with self.assertLogs(level=logging.ERROR) as lw: + fdroidserver.common.config['keypass'] + self.assertTrue('is not set' in lw.output[0]) + self.assertEqual(1, len(lw.output)) + @mock.patch.dict(os.environ, {'PATH': os.getenv('PATH')}, clear=True) def test_test_sdk_exists_fails_on_bad_sdk_path(self): config = {'sdk_path': 'nothinghere'} @@ -2384,9 +2419,10 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): @mock.patch('sdkmanager._generate_package_xml', lambda a, b, c: None) def test_auto_install_ndk_mock_dl(self): """Test NDK installs by actually calling sdkmanager""" - import sdkmanager import importlib.metadata + import sdkmanager + sdkmanager_version = LooseVersion(importlib.metadata.version('sdkmanager')) if sdkmanager_version < LooseVersion('0.6.4'): raise unittest.SkipTest('needs fdroid sdkmanager >= 0.6.4') @@ -2480,7 +2516,7 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): fdroidserver.common.fill_config_defaults(config) build = fdroidserver.metadata.Build() with self.assertRaises(TypeError): - fdroidserver.common.set_FDroidPopen_env(build) + fdroidserver.common.set_FDroidPopen_env(build=build) @mock.patch.dict(os.environ, clear=True) def test_ndk_paths_in_config_must_be_strings(self): @@ -2492,7 +2528,7 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): build.ndk = 'r21d' os.environ['PATH'] = '/usr/bin:/usr/sbin' with self.assertRaises(TypeError): - fdroidserver.common.set_FDroidPopen_env(build) + fdroidserver.common.set_FDroidPopen_env(build=build) @mock.patch.dict(os.environ, clear=True) def test_FDroidPopen_envs_paths_can_be_pathlib(self): @@ -2579,7 +2615,7 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): with mock.patch.dict(os.environ, clear=True): os.environ['PATH'] = '/usr/bin:/usr/sbin' - fdroidserver.common.set_FDroidPopen_env(build) + fdroidserver.common.set_FDroidPopen_env(build=build) self.assertNotIn('', os.getenv('PATH').split(os.pathsep)) def test_is_repo_file(self): @@ -2748,7 +2784,6 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): 'NonFreeDep', 'NonFreeNet', 'Tracking', - 'UpstreamNonFree', ], list(antiFeatures.keys()), ) @@ -2784,6 +2819,46 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): ) self.assertEqual(['en-US'], list(categories['GuardianProject']['name'].keys())) + def test_load_localized_config_copy_icon(self): + os.chdir(self.testdir) + os.mkdir('config') + Path('config/categories.yml').write_text('System:\n icon: system.png') + source_file = 'config/system.png' + Path(source_file).write_text('placeholder') + time.sleep(0.01) # ensure reliable failure if mtime isn't preserved + fdroidserver.common.load_localized_config(CATEGORIES_CONFIG_NAME, 'repo') + dest_file = f'repo/icons/{os.path.basename(source_file)}' + self.assertEqual(os.path.getsize(source_file), os.path.getsize(dest_file)) + self.assertEqual(os.path.getmtime(source_file), os.path.getmtime(dest_file)) + + def test_load_localized_config_copy_unchanged(self): + """The destination file should only change if the source file did.""" + os.chdir(self.testdir) + os.mkdir('config') + Path('config/categories.yml').write_text('System:\n icon: system.png') + source_file = 'config/system.png' + Path(source_file).write_text('placeholder') + fdroidserver.common.load_localized_config(CATEGORIES_CONFIG_NAME, 'repo') + delta = 0.01 + time.sleep(delta) # ensure reliable failure if file isn't preserved + fdroidserver.common.load_localized_config(CATEGORIES_CONFIG_NAME, 'repo') + dest_file = f'repo/icons/{os.path.basename(source_file)}' + self.assertAlmostEqual( + os.path.getctime(source_file), os.path.getctime(dest_file), delta=delta + ) + + def test_load_localized_config_copy_over_dest(self): + os.chdir(self.testdir) + os.mkdir('config') + Path('config/categories.yml').write_text('System:\n icon: system.png') + source_file = Path('config/system.png') + dest_file = Path(f'repo/icons/{os.path.basename(source_file)}') + source_file.write_text('placeholder') + dest_file.parent.mkdir(parents=True) + dest_file.write_text('different contents') + fdroidserver.common.load_localized_config(CATEGORIES_CONFIG_NAME, 'repo') + self.assertEqual(os.path.getsize(source_file), os.path.getsize(dest_file)) + def test_load_localized_config_0_file(self): os.chdir(self.testdir) os.mkdir('config') @@ -3005,6 +3080,58 @@ class CommonTest(SetUpTearDownMixin, unittest.TestCase): for mirror in fdroidserver.common.append_filename_to_mirrors(filename, mirrors): self.assertTrue(mirror['url'].endswith('/' + filename)) + def test_get_source_date_epoch(self): + git_repo = git.Repo.init(self.testdir) + Path('README').write_text('file to commit') + git_repo.git.add(all=True) + git_repo.index.commit("README") + self.assertEqual( + git_repo.git.log(n=1, pretty='%ct'), + fdroidserver.common.get_source_date_epoch(self.testdir), + ) + + def test_get_source_date_epoch_no_scm(self): + self.assertIsNone(fdroidserver.common.get_source_date_epoch(self.testdir)) + + def test_get_source_date_epoch_not_git(self): + """Test when build_dir is not a git repo, e.g. hg, svn, etc.""" + appid = 'com.example' + build_dir = Path(self.testdir) / 'build' / appid + fdroiddata = build_dir.parent.parent + (fdroiddata / 'metadata').mkdir() + build_dir.mkdir(parents=True) + os.chdir(build_dir) + git_repo = git.Repo.init(fdroiddata) # fdroiddata is always a git repo + with (fdroiddata / f'metadata/{appid}.yml').open('w') as fp: + fp.write('AutoName: Example App\n') + git_repo.git.add(all=True) + git_repo.index.commit("update README") + self.assertEqual( + git.repo.Repo(fdroiddata).git.log(n=1, pretty='%ct'), + fdroidserver.common.get_source_date_epoch(build_dir), + ) + + @mock.patch.dict(os.environ, {'PATH': os.getenv('PATH')}, clear=True) + def test_set_FDroidPopen_env_with_app(self): + """Test SOURCE_DATE_EPOCH in FDroidPopen when build_dir is a git repo.""" + os.chdir(self.testdir) + app = fdroidserver.metadata.App() + app.id = 'com.example' + build_dir = Path(self.testdir) / 'build' / app.id + git_repo = git.Repo.init(build_dir) + Path('README').write_text('file to commit') + git_repo.git.add(all=True) + now = datetime.now(timezone.utc) + git_repo.index.commit("README", commit_date=now) + fdroidserver.common.set_FDroidPopen_env(app) + p = fdroidserver.common.FDroidPopen(['printenv', 'SOURCE_DATE_EPOCH']) + self.assertEqual(int(p.output), int(now.timestamp())) + + def test_calculate_gradle_flavor_combination(self): + flavors = ['aa', 'BB', 'δδ'] + combinations = ['aaBBΔδ', 'aaBB', 'aaΔδ', 'aa', 'BBΔδ', 'BB', 'δδ', ''] + self.assertEqual(fdroidserver.common.calculate_gradle_flavor_combination(flavors), combinations) + APKS_WITH_JAR_SIGNATURES = ( ( @@ -3425,7 +3552,7 @@ class ConfigOptionsScopeTest(unittest.TestCase): self.assertIsNone(fdroidserver.common.config) config = fdroidserver.common.read_config() self.assertIsNotNone(fdroidserver.common.config) - self.assertEqual(dict, type(config)) + self.assertTrue(isinstance(config, dict)) self.assertEqual(config, fdroidserver.common.config) def test_get_config_global(self): @@ -3435,7 +3562,7 @@ class ConfigOptionsScopeTest(unittest.TestCase): self.assertIsNone(fdroidserver.common.config) c = fdroidserver.common.read_config() self.assertIsNotNone(fdroidserver.common.config) - self.assertEqual(dict, type(c)) + self.assertTrue(isinstance(c, dict)) self.assertEqual(c, fdroidserver.common.config) self.assertTrue( 'config' not in vars() and 'config' not in globals(), @@ -3475,10 +3602,52 @@ class UnsafePermissionsTest(SetUpTearDownMixin, unittest.TestCase): self.assertTrue('unsafe' in lw.output[0]) self.assertEqual(1, len(lw.output)) - @mock.patch.dict(os.environ, {'PATH': os.getenv('PATH')}, clear=True) - def test_config_perm_unset_env_no_warning(self): - fdroidserver.common.write_config_file('keypass: {env: keypass}') - with self.assertLogs(level=logging.WARNING) as lw: - fdroidserver.common.read_config() - self.assertTrue('unsafe' not in lw.output[0]) - self.assertEqual(1, len(lw.output)) + +class GetHeadCommitIdTest(unittest.TestCase): + """Test and compare two methods of getting the commit ID.""" + + def setUp(self): + self._td = mkdtemp() + self.testdir = self._td.name + os.chdir(self.testdir) + logging.getLogger('git.cmd').setLevel(logging.INFO) + + def tearDown(self): + os.chdir(basedir) + self._td.cleanup() + + @unittest.skipUnless((basedir.parent / '.git').exists(), 'Needs a working git repo') + def test_get_head_commit_id_compare(self): + """Run on this git repo to get some real world noise in there.""" + git_dir = basedir.parent + self.assertIsNotNone(fdroidserver.common.get_head_commit_id(git_dir)) + + def test_get_head_commit_id_error_bare_repo(self): + """Error because it is an empty, bare git repo.""" + git_repo = git.Repo.init(self.testdir) + self.assertIsNone(fdroidserver.common.get_head_commit_id(git_repo)) + + def test_get_head_commit_id_error_no_repo(self): + """Error because there is no .git/ dir.""" + with self.assertLogs('root', level=logging.DEBUG): + self.assertIsNone(fdroidserver.common.get_head_commit_id(self.testdir)) + + def test_get_head_commit_id_detached_and_branch(self): + """Fetching commit ID must work from detached HEADs and branches.""" + git_repo = git.Repo.init(self.testdir) + Path('README').write_text('this is just a test') + git_repo.git.add(all=True) + git_repo.index.commit("add README") + Path('LICENSE').write_text('free!') + git_repo.git.add(all=True) + git_repo.index.commit("add LICENSE") + self.assertIsNotNone(fdroidserver.common.get_head_commit_id(git_repo)) + # detached HEAD + git_repo.git.checkout('HEAD^') + self.assertIsNotNone(fdroidserver.common.get_head_commit_id(git_repo)) + # on a branch with a new commits + git_repo.git.checkout('test', b=True) + Path('foo.py').write_text('print("code!")') + git_repo.git.add(all=True) + git_repo.index.commit("add code") + self.assertIsNotNone(fdroidserver.common.get_head_commit_id(git_repo)) diff --git a/tests/test_deploy.py b/tests/test_deploy.py index b821725c..60d157c3 100755 --- a/tests/test_deploy.py +++ b/tests/test_deploy.py @@ -11,7 +11,8 @@ from unittest import mock import git import fdroidserver -from .shared_test_code import TmpCwd, mkdtemp, VerboseFalseOptions + +from .shared_test_code import TmpCwd, VerboseFalseOptions, mkdtemp basedir = Path(__file__).parent diff --git a/tests/test_exception.py b/tests/test_exception.py index accc6653..01a6cd46 100755 --- a/tests/test_exception.py +++ b/tests/test_exception.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import unittest + import fdroidserver diff --git a/tests/test_github.py b/tests/test_github.py index 39514c5d..f30ce0bb 100755 --- a/tests/test_github.py +++ b/tests/test_github.py @@ -3,9 +3,10 @@ import unittest import unittest.mock -from .shared_test_code import mock_urlopen import fdroidserver +from .shared_test_code import mock_urlopen + class GithubApiTest(unittest.TestCase): def test__init(self): diff --git a/tests/test_gpgsign.py b/tests/test_gpgsign.py index f73b217e..84634874 100755 --- a/tests/test_gpgsign.py +++ b/tests/test_gpgsign.py @@ -5,11 +5,11 @@ import os import shutil import tempfile import unittest - -from fdroidserver import common, gpgsign from pathlib import Path from unittest.mock import MagicMock, patch +from fdroidserver import common, gpgsign + basedir = Path(__file__).parent diff --git a/tests/test_gradlew-fdroid b/tests/test_gradlew-fdroid deleted file mode 100755 index 26d9bf5b..00000000 --- a/tests/test_gradlew-fdroid +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -red='\033[0;31m' -green='\033[0;32m' -nocolor='\033[0m' - -TEST_VALUE='HELLO WORLD!' - -run_test() { - 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" - else - printf "${red}ERROR: $2 not found in $1\n" - ((exit_value++)) - fi - printf $nocolor -} - -download_cache_test() { - if $basedir/gradlew-fdroid helloWorld 2>/dev/null | grep -F "$TEST_VALUE"; then - printf "${green}passed: $1\n" - else - printf "${red}ERROR: \n" - $basedir/gradlew-fdroid helloWorld - ((exit_value++)) - fi - printf $nocolor -} - -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 - -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 - -cd $tmpdir -mkdir -p download_cache_test/gradle/wrapper -cd download_cache_test -echo 'distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip' \ - > gradle/wrapper/gradle-wrapper.properties -printf "task helloWorld {\n\tdoLast {\n\t\tprintln '$TEST_VALUE'\n\t}\n}" > build.gradle - -export GRADLE_VERSION_DIR=$tmpdir/gradle/versions -mkdir -p $GRADLE_VERSION_DIR - -unset https_proxy -printf "download, unpack, and run: " -download_cache_test 7.3 -printf "unpack and run: " -rm -rf $GRADLE_VERSION_DIR/7.3/ -download_cache_test 7.3 -printf "just run: " -download_cache_test 7.3 - -exit $exit_value diff --git a/tests/test_import_subcommand.py b/tests/test_import_subcommand.py index 05e2c379..530e10fb 100755 --- a/tests/test_import_subcommand.py +++ b/tests/test_import_subcommand.py @@ -13,11 +13,11 @@ import git import requests import yaml -from .shared_test_code import TmpCwd, mkdtemp, VerboseFalseOptions - import fdroidserver import fdroidserver.import_subcommand +from .shared_test_code import TmpCwd, VerboseFalseOptions, mkdtemp + basedir = Path(__file__).parent logging.basicConfig(level=logging.DEBUG) diff --git a/tests/test_index.py b/tests/test_index.py index b4973d79..c8ff5cbe 100755 --- a/tests/test_index.py +++ b/tests/test_index.py @@ -3,21 +3,22 @@ import copy import datetime import glob -import os -import unittest -from pathlib import Path -import yaml -import zipfile -from unittest.mock import patch -import requests -import tempfile import json +import os import shutil +import tempfile +import unittest +import zipfile +from pathlib import Path +from unittest.mock import patch + +import requests +import yaml import fdroidserver from fdroidserver import common, index, publish, signindex, update -from .shared_test_code import GP_FINGERPRINT, TmpCwd, mkdtemp +from .shared_test_code import GP_FINGERPRINT, TmpCwd, mkdtemp basedir = Path(__file__).parent diff --git a/tests/test_init.py b/tests/test_init.py index 179f06c7..a038493b 100755 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -8,6 +8,7 @@ import unittest import fdroidserver.common import fdroidserver.init + from .shared_test_code import mkdtemp basedir = pathlib.Path(__file__).parent diff --git a/tests/test_install.py b/tests/test_install.py index b4e404d5..aa239d4d 100755 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -3,7 +3,6 @@ import os import textwrap import unittest - from pathlib import Path from unittest.mock import Mock, patch diff --git a/tests/test_integration.py b/tests/test_integration.py index 76a7e82b..6d757b1e 100755 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -18,6 +18,7 @@ except ModuleNotFoundError: from androguard.core.apk import get_apkid from fdroidserver._yaml import yaml, yaml_dumper + from .shared_test_code import mkdir_testfiles # TODO: port generic tests that use index.xml to index-v2 (test that diff --git a/tests/test_lint.py b/tests/test_lint.py index f0bf6b4d..37b7ce95 100755 --- a/tests/test_lint.py +++ b/tests/test_lint.py @@ -9,13 +9,13 @@ import unittest from pathlib import Path from unittest import mock -from .shared_test_code import mkdtemp - import fdroidserver.common import fdroidserver.lint import fdroidserver.metadata from fdroidserver._yaml import config_dump +from .shared_test_code import mkdtemp + basedir = Path(__file__).parent @@ -510,7 +510,7 @@ class LintAntiFeaturesTest(unittest.TestCase): def test_check_antiFeatures(self): app = fdroidserver.metadata.App() - app['AntiFeatures'] = ['Ads', 'UpstreamNonFree'] + app['AntiFeatures'] = ['Ads', 'Tracking'] self.assertEqual([], list(fdroidserver.lint.check_antiFeatures(app))) def test_check_antiFeatures_fails_one(self): diff --git a/tests/test_main.py b/tests/test_main.py index 50fda3e2..68984088 100755 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -2,12 +2,13 @@ import os import pkgutil +import tempfile import textwrap import unittest -import tempfile from unittest import mock import fdroidserver.__main__ + from .shared_test_code import TmpCwd, TmpPyPath diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 8c3f7591..84040024 100755 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -4,22 +4,23 @@ import copy import io import os import random -import ruamel.yaml import shutil -import unittest import tempfile import textwrap +import unittest from collections import OrderedDict from pathlib import Path from unittest import mock +import ruamel.yaml + import fdroidserver from fdroidserver import metadata -from fdroidserver.exception import MetaDataException -from fdroidserver.common import DEFAULT_LOCALE from fdroidserver._yaml import yaml -from .shared_test_code import TmpCwd, mkdtemp +from fdroidserver.common import DEFAULT_LOCALE +from fdroidserver.exception import MetaDataException +from .shared_test_code import TmpCwd, mkdtemp basedir = Path(__file__).parent @@ -671,7 +672,7 @@ class MetadataTest(unittest.TestCase): """Definitions in .yml files should override the localized versions.""" app = metadata.parse_metadata('metadata/app.with.special.build.params.yml') - self.assertEqual(app['AntiFeatures'], {'UpstreamNonFree': {}}) + self.assertEqual(app['AntiFeatures'], {'Tracking': {}}) self.assertEqual(49, app['Builds'][-3]['versionCode']) self.assertEqual( @@ -960,7 +961,6 @@ class MetadataTest(unittest.TestCase): - versionCode: 123 antifeatures: - KnownVuln - - UpstreamNonFree - NonFreeAssets """ ) @@ -971,11 +971,7 @@ class MetadataTest(unittest.TestCase): 'AntiFeatures': {'Ads': {}}, 'Builds': [ { - 'antifeatures': { - 'KnownVuln': {}, - 'NonFreeAssets': {}, - 'UpstreamNonFree': {}, - }, + 'antifeatures': {'KnownVuln': {}, 'NonFreeAssets': {}}, 'versionCode': 123, } ], @@ -996,7 +992,7 @@ class MetadataTest(unittest.TestCase): es: 2nd az: zero en-US: first - UpstreamNonFree: + Tracking: NonFreeAssets: AntiFeatures: NonFreeDep: @@ -1018,7 +1014,7 @@ class MetadataTest(unittest.TestCase): 'antifeatures': { 'KnownVuln': {'az': 'zero', 'en-US': 'first', 'es': '2nd'}, 'NonFreeAssets': {}, - 'UpstreamNonFree': {}, + 'Tracking': {}, }, 'versionCode': 123, } @@ -1872,7 +1868,6 @@ class MetadataTest(unittest.TestCase): antifeatures: - KnownVuln - NonFreeAssets - - UpstreamNonFree ArchivePolicy: 4 AutoUpdateMode: Version v%v diff --git a/tests/test_net.py b/tests/test_net.py index 581edcfb..beacd9af 100755 --- a/tests/test_net.py +++ b/tests/test_net.py @@ -2,16 +2,17 @@ import os import random -import requests import socket import tempfile import threading import time import unittest +from pathlib import Path from unittest.mock import MagicMock, patch +import requests + from fdroidserver import net -from pathlib import Path class RetryServer: diff --git a/tests/test_nightly.py b/tests/test_nightly.py index 750a22fc..fb1614b7 100755 --- a/tests/test_nightly.py +++ b/tests/test_nightly.py @@ -2,19 +2,18 @@ import os import platform -import requests import shutil import subprocess import tempfile import time import unittest -import yaml - from pathlib import Path from unittest.mock import patch -from fdroidserver import common, exception, index, nightly +import requests +import yaml +from fdroidserver import common, exception, index, nightly DEBUG_KEYSTORE = '/u3+7QAAAAIAAAABAAAAAQAPYW5kcm9pZGRlYnVna2V5AAABNYhAuskAAAK8MIICuDAOBgorBgEEASoCEQEBBQAEggKkqRnFlhidQmVff83bsAeewXPIsF0jiymzJnvrnUAQtCK0MV9uZonu37Mrj/qKLn56mf6QcvEoKvpCstZxzftgYYpAHWMVLM+hy2Z707QZEHlY7Ukppt8DItj+dXkeqGt7f8KzOb2AQwDbt9lm1fJb+MefLowTaubtvrLMcKIne43CbCu2D8HyN7RPWpEkVetA2Qgr5W4sa3tIUT80afqo9jzwJjKCspuxY9A1M8EIM3/kvyLo2B9r0cuWwRjYZXJ6gmTYI2ARNz0KQnCZUok14NDg+mZTb1B7AzRfb0lfjbA6grbzuAL+WaEpO8/LgGfuOh7QBZBT498TElOaFfQ9toQWA79wAmrQCm4OoFukpPIy2m/l6VjJSmlK5Q+CMOl/Au7OG1sUUCTvPaIr0XKnsiwDJ7a71n9garnPWHkvuWapSRCzCNgaUoGQjB+fTMJFFrwT8P1aLfM6onc3KNrDStoQZuYe5ngCLlNS56bENkVGvJBfdkboxtHZjqDXXON9jWGSOI527J3o2D5sjSVyx3T9XPrsL4TA/nBtdU+c/+M6aoASZR2VymzAKdMrGfj9kE5GXp8vv2vkJj9+OJ4Jm5yeczocc/Idtojjb1yg+sq1yY8kAQxgezpY1rpgi2jF3tSN01c23DNvAaSJLJX2ZuH8sD40ACc80Y1Qp1nUTdpwBZUeaeNruBwx4PHU8GnC71FwtiUpwNs0OoSl0pgDUJ3ODC5bs8B5QmW1wu1eg7I4mMSmCsNGW6VN3sFcu+WEqnmTxPoZombdFZKxsr2oq359Nn4bJ6Uc9PBz/sXsns7Zx1vND/oK/Jv5Y269UVAMeKX/eGpfnxzagW3tqGbOu12C2p9Azo5VxiU2fG/tmk2PjaG5hV/ywReco7I6C1p8OWM2fwAAAAEABVguNTA5AAAB6TCCAeUwggFOoAMCAQICBE89gTUwDQYJKoZIhvcNAQEFBQAwNzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxFjAUBgNVBAMTDUFuZHJvaWQgRGVidWcwHhcNMTIwMjE2MjIyMDM3WhcNNDIwMjA4MjIyMDM3WjA3MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHQW5kcm9pZDEWMBQGA1UEAxMNQW5kcm9pZCBEZWJ1ZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3AKU7S7JXhUjEwxWP1/LPHXieh61SaA/+xbpqsPA+yjGz1sAcGAyuG6bjNAVm56pq7nkjJzicX7Wi83nUBo58DEC/quxOLdy0C4PEOSAeTnTT1RJIwMDvOgiL1GFCErvQ7gCH6zuAID/JRFbN6nIkhDjs2DYnSBl7aJJf8wCLc0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAoq/TJffA0l+ZGf89xndmHdxrO6qi+TzSlByvLZ4eFfCovTh1iO+Edrd5V1yXGLxyyvdsadMAFZT8SaxMrP5xxhJ0nra0APWYLpA96M//auMhQBWPgqPntwgvEZuEH7f0kdItjBJ39yijbG8xfgwid6XqNUo0TDDkp/wNWKpJ9tJe+2PrGw1NAvrgSydoH2j8DI1Eq' DEBUG_KEYSTORE_KEY_FILE_NAME = ( @@ -192,6 +191,29 @@ class NightlyTest(unittest.TestCase): with self.assertRaises(exception.VCSException): nightly.main() + def test_clone_git_repo(self): + os.chdir(self.testdir) + common.options = Options + d = 'fakeappid' + nightly.clone_git_repo('https://gitlab.com/fdroid/ci-test-tiny-repo.git', d) + self.assertTrue(os.path.isdir(Path(d) / '.git')) + + def test_clone_git_repo_fails_on_gitlab_password_prompt(self): + os.chdir(self.testdir) + common.options = Options + d = 'shouldnotbecreated' + with self.assertRaises(exception.VCSException): + nightly.clone_git_repo(f'https://gitlab.com/{d}/{d}.git', d) + self.assertFalse(os.path.isdir(Path(d))) + + def test_clone_git_repo_fails_on_github_password_prompt(self): + os.chdir(self.testdir) + common.options = Options + d = 'shouldnotbecreated' + with self.assertRaises(exception.VCSException): + nightly.clone_git_repo(f'https://github.com/{d}/{d}.git', d) + self.assertFalse(os.path.isdir(Path(d))) + def _put_fdroid_in_args(self, args): """Find fdroid command that belongs to this source code tree""" fdroid = os.path.join(basedir.parent, 'fdroid') diff --git a/tests/test_publish.py b/tests/test_publish.py index cb47bff5..82c670d7 100755 --- a/tests/test_publish.py +++ b/tests/test_publish.py @@ -15,17 +15,15 @@ import os import pathlib import shutil import sys -import unittest import tempfile +import unittest from unittest import mock -from fdroidserver import publish -from fdroidserver import common -from fdroidserver import metadata -from fdroidserver import signatures +from fdroidserver import common, metadata, publish, signatures from fdroidserver._yaml import yaml from fdroidserver.exception import FDroidException -from .shared_test_code import mkdtemp, VerboseFalseOptions + +from .shared_test_code import VerboseFalseOptions, mkdtemp basedir = pathlib.Path(__file__).parent diff --git a/tests/test_rewritemeta.py b/tests/test_rewritemeta.py index 5ad1b94d..4dcdd03f 100755 --- a/tests/test_rewritemeta.py +++ b/tests/test_rewritemeta.py @@ -1,13 +1,14 @@ #!/usr/bin/env python3 import os -import unittest import tempfile import textwrap +import unittest from pathlib import Path from unittest import mock from fdroidserver import metadata, rewritemeta + from .shared_test_code import TmpCwd, mkdtemp basedir = Path(__file__).parent @@ -39,7 +40,6 @@ class RewriteMetaTest(unittest.TestCase): 'target': 'android-10', 'antifeatures': { 'KnownVuln': {}, - 'UpstreamNonFree': {}, 'NonFreeAssets': {}, }, }, diff --git a/tests/test_scanner.py b/tests/test_scanner.py index 1dbe15b0..849476e6 100755 --- a/tests/test_scanner.py +++ b/tests/test_scanner.py @@ -26,6 +26,7 @@ import fdroidserver.common import fdroidserver.exception import fdroidserver.metadata import fdroidserver.scanner + from .shared_test_code import TmpCwd, mkdtemp, mock_open_to_str basedir = pathlib.Path(__file__).parent @@ -74,6 +75,7 @@ class ScannerTest(unittest.TestCase): 'com.jens.automation2': 3, 'firebase-suspect': 1, 'org.mozilla.rocket': 2, + 'org.piepmeyer.gauguin': 1, 'org.tasks': 3, 'realm': 1, 'se.manyver': 3, @@ -107,12 +109,16 @@ class ScannerTest(unittest.TestCase): ('source-files/eu.siacs.conversations/build.gradle', 'free', 21), ('source-files/org.mozilla.rocket/app/build.gradle', 'focus', 40), ('source-files/com.jens.automation2/app/build.gradle', 'fdroidFlavor', 5), + ('source-files/flavor.test/build.gradle', ['foss', 'prod'], 7), ] for f, flavor, count in test_files: i = 0 build = fdroidserver.metadata.Build() - build.gradle = [flavor] + if isinstance(flavor, list): + build.gradle = flavor + else: + build.gradle = [flavor] regexs = fdroidserver.scanner.get_gradle_compile_commands_without_catalog( build ) @@ -350,6 +356,8 @@ class ScannerTest(unittest.TestCase): with mock.patch( 'fdroidserver.common.get_apk_id', return_value=(app.id, build.versionCode, build.versionName), + ), mock.patch( + 'fdroidserver.common.get_source_date_epoch', lambda f: '1234567890' ): with mock.patch( 'fdroidserver.common.is_debuggable_or_testOnly', diff --git a/tests/test_signatures.py b/tests/test_signatures.py index 603ddf2c..4f7bd105 100755 --- a/tests/test_signatures.py +++ b/tests/test_signatures.py @@ -6,9 +6,10 @@ import sys import unittest from tempfile import TemporaryDirectory -from .shared_test_code import TmpCwd from fdroidserver import common, signatures +from .shared_test_code import TmpCwd + basedir = os.path.dirname(__file__) diff --git a/tests/test_signindex.py b/tests/test_signindex.py index 149afb24..21d54585 100755 --- a/tests/test_signindex.py +++ b/tests/test_signindex.py @@ -6,11 +6,11 @@ import shutil import subprocess import tempfile import unittest - -from fdroidserver import apksigcopier, common, exception, signindex, update from pathlib import Path from unittest.mock import patch +from fdroidserver import apksigcopier, common, exception, signindex, update + class Options: allow_disabled_algorithms = False diff --git a/tests/test_update.py b/tests/test_update.py index dfe353b5..623f48cc 100755 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import copy -import git import glob import hashlib import json @@ -12,15 +11,18 @@ import shutil import string import subprocess import sys -import unittest -import yaml -import zipfile import textwrap +import time +import unittest +import zipfile from binascii import hexlify from datetime import datetime from pathlib import Path from unittest import mock +import git +import yaml + try: # these were moved in androguard 4.0 from androguard.core.apk import APK @@ -43,15 +45,16 @@ except ImportError: except ImportError: from yaml import Loader as FullLoader +from PIL import PngImagePlugin + import fdroidserver.common import fdroidserver.exception import fdroidserver.metadata import fdroidserver.update from fdroidserver.common import CATEGORIES_CONFIG_NAME from fdroidserver.looseversion import LooseVersion -from .shared_test_code import TmpCwd, mkdtemp -from PIL import PngImagePlugin +from .shared_test_code import TmpCwd, mkdtemp DONATION_FIELDS = ('Donate', 'Liberapay', 'OpenCollective') @@ -252,6 +255,113 @@ class UpdateTest(unittest.TestCase): fdroidserver.update.insert_localized_app_metadata(apps) self.assertEqual('42', apps[app.id]['localized']['en-US']['whatsNew']) + def test_fastlane_with_subdir(self): + """Test if fastlane in simple one-level subdir is found.""" + os.chdir(self.testdir) + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.update.config = config + + app = fdroidserver.metadata.App() + app.id = 'com.example.app' + build_dir = f'build/{app.id}' + flavor = 'flavor' + subdir = 'subproject' + apps = {app.id: app} + build = fdroidserver.metadata.Build() + build.versionCode = 42 + build.gradle = [flavor] + build.subdir = subdir + app['Builds'] = [build] + + first_value = 'first' + first_dir = Path(f'{build_dir}/src/{flavor}/fastlane/metadata/android/en-US') + first_dir.mkdir(parents=True) + (first_dir / 'title.txt').write_text(first_value) + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(first_value, apps[app.id]['localized']['en-US']['name']) + + second_value = 'second' + second_dir = Path(f'{build_dir}/{subdir}/fastlane/metadata/android/en-US') + second_dir.mkdir(parents=True) + (second_dir / 'title.txt').write_text(second_value) + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(second_value, apps[app.id]['localized']['en-US']['name']) + + def test_fastlane_with_schildichat(self): + """Test if fastlane is found in this tangle of dirs and symlinks. + + https://github.com/SchildiChat/schildichat-android-next/tree/sc_v0.10.3-ex_25_6_2 + """ + os.chdir(self.testdir) + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.update.config = config + + app = fdroidserver.metadata.App() + app.id = 'chat.schildi.android' + build_dir = f'build/{app.id}' + flavors = ['fdroid', 'sc', 'default'] + subdir = 'app' + apps = {app.id: app} + build = fdroidserver.metadata.Build() + build.versionCode = 42 + build.gradle = flavors + build.subdir = subdir + app['Builds'] = [build] + + wrong_value = 'wrong' + wrong_dir = Path(f'{build_dir}/upstream_infra/fastlane/metadata/android/en-US') + wrong_dir.mkdir(parents=True) + (wrong_dir / 'title.txt').write_text(wrong_value) + + right_value = 'right' + right_dir = Path(f'{build_dir}/metadata/en-US') + right_dir.mkdir(parents=True) + (right_dir / 'title.txt').write_text(right_value) + _fastlane = Path('.fastlane/metadata') + _fastlane.mkdir(parents=True) + os.symlink('../../metadata', _fastlane / 'android') + os.symlink('.fastlane', 'fastlane') + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(right_value, apps[app.id]['localized']['en-US']['name']) + + def test_fastlane_with_multi_level_subdir(self): + """Test if fastlane in multi-level subdir is found.""" + os.chdir(self.testdir) + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.update.config = config + + app = fdroidserver.metadata.App() + app.id = 'org.videolan.vlc' + build_dir = f'build/{app.id}' + subdir = 'application/app' + apps = {app.id: app} + build = fdroidserver.metadata.Build() + build.versionCode = 42 + build.gradle = ['yes'] + build.subdir = subdir + app['Builds'] = [build] + + first_value = 'first' + first_dir = Path(f'{build_dir}/{subdir}/fastlane/metadata/android/en-US') + first_dir.mkdir(parents=True) + (first_dir / 'title.txt').write_text(first_value) + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(first_value, apps[app.id]['localized']['en-US']['name']) + + # I'm not sure that it is correct behavior for this path to + # override the above path, but it is how it is working now. It + # seems to me it should be the other way around, but that is + # really hard to implement using the current algorithm. + second_value = 'second' + second_dir = Path(f'{build_dir}/fastlane/metadata/android/en-US') + second_dir.mkdir(parents=True) + (second_dir / 'title.txt').write_text(second_value) + fdroidserver.update.insert_localized_app_metadata(apps) + self.assertEqual(second_value, apps[app.id]['localized']['en-US']['name']) + def test_name_title_scraping(self): """metadata file --> fdroiddata localized files --> fastlane/triple-t in app source --> APK""" shutil.copytree(basedir, self.testdir, dirs_exist_ok=True) @@ -436,6 +546,24 @@ class UpdateTest(unittest.TestCase): locales = sorted(apps['org.fdroid.ci.test.app']['localized']) self.assertEqual(correctlocales, locales) + def test_insert_triple_t_1_graphics(self): + packageName = 'de.wivewa.dialer' + shutil.copytree(basedir / 'triple-t-1-graphics', self.testdir, dirs_exist_ok=True) + os.chdir(self.testdir) + + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config + fdroidserver.update.config = config + + apps = fdroidserver.metadata.read_metadata() + fdroidserver.update.copy_triple_t_store_metadata(apps) + + 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', '1.png'))) + def test_insert_triple_t_2_metadata(self): packageName = 'org.piwigo.android' shutil.copytree(basedir / 'triple-t-2', self.testdir, dirs_exist_ok=True) @@ -1247,7 +1375,7 @@ class UpdateTest(unittest.TestCase): if apk['packageName'] == 'com.politedroid' and apk['versionCode'] == 3: antiFeatures = apk.get('antiFeatures') self.assertTrue('KnownVuln' in antiFeatures) - self.assertEqual(3, len(antiFeatures)) + self.assertEqual(2, len(antiFeatures)) foundtest = True self.assertTrue(foundtest) @@ -1351,15 +1479,64 @@ class UpdateTest(unittest.TestCase): def test_strip_and_copy_image(self): in_file = basedir / 'metadata/info.guardianproject.urzip/en-US/images/icon.png' out_file = os.path.join(self.testdir, 'icon.png') - fdroidserver.update._strip_and_copy_image(in_file, out_file) + with self.assertLogs(level=logging.DEBUG): + fdroidserver.update._strip_and_copy_image(in_file, out_file) self.assertTrue(os.path.exists(out_file)) def test_strip_and_copy_image_bad_filename(self): in_file = basedir / 'corrupt-featureGraphic.png' out_file = os.path.join(self.testdir, 'corrupt-featureGraphic.png') - fdroidserver.update._strip_and_copy_image(in_file, out_file) + with self.assertLogs(level=logging.DEBUG): + fdroidserver.update._strip_and_copy_image(in_file, out_file) self.assertFalse(os.path.exists(out_file)) + def test_strip_and_copy_image_unchanged(self): + in_file = basedir / 'metadata/info.guardianproject.urzip/en-US/images/icon.png' + out_file = os.path.join(self.testdir, 'icon.png') + shutil.copy2(in_file, out_file) + ctime = os.path.getctime(out_file) + delta = 0.01 + time.sleep(delta) # ensure reliable failure if file isn't preserved + with self.assertLogs(level=logging.DEBUG): # suppress log output + fdroidserver.update._strip_and_copy_image(in_file, out_file) + self.assertAlmostEqual(ctime, os.path.getctime(out_file), delta=delta) + + def test_strip_and_copy_image_in_file_ctime_changed(self): + out_file = os.path.join(self.testdir, 'icon.png') + with open(out_file, 'w') as fp: + fp.write('to be replaced') + size = os.path.getsize(out_file) + delta = 0.01 + time.sleep(delta) # ensure reliable failure when testing ctime + src_file = basedir / 'metadata/info.guardianproject.urzip/en-US/images/icon.png' + in_file = os.path.join(self.testdir, 'in-icon.png') + shutil.copy(src_file, in_file) + time.sleep(delta) # ensure reliable failure when testing ctime + with self.assertLogs(level=logging.DEBUG): # suppress log output + fdroidserver.update._strip_and_copy_image(in_file, out_file) + self.assertNotEqual(size, os.path.getsize(out_file)) + self.assertTrue(os.path.getctime(in_file) <= os.path.getctime(out_file)) + # _strip_and_copy_image syncs mtime from in_file to out_file + self.assertAlmostEqual( + os.path.getmtime(in_file), os.path.getmtime(out_file), delta=delta + ) + + def test_strip_and_copy_image_in_file_mtime_changed(self): + in_file = basedir / 'metadata/info.guardianproject.urzip/en-US/images/icon.png' + out_file = os.path.join(self.testdir, 'icon.png') + shutil.copy(in_file, out_file) + os.utime(out_file, (12345, 12345)) # set atime/mtime to something old + with self.assertLogs(level=logging.DEBUG): # suppress log output + fdroidserver.update._strip_and_copy_image(in_file, out_file) + delta = 0.01 + self.assertNotAlmostEqual( + os.path.getctime(in_file), os.path.getctime(out_file), delta=delta + ) + # _strip_and_copy_image syncs mtime from in_file to out_file + self.assertAlmostEqual( + os.path.getmtime(in_file), os.path.getmtime(out_file), delta=delta + ) + def test_create_metadata_from_template_empty_keys(self): apk = {'packageName': 'rocks.janicerand'} with mkdtemp() as tmpdir, TmpCwd(tmpdir): @@ -1639,7 +1816,7 @@ class UpdateTest(unittest.TestCase): with mkdtemp() as tmpdir: os.chdir(tmpdir) with mock.patch('sys.argv', ['fdroid update', '']): - fdroidserver.update.status_update_json([], []) + fdroidserver.update.status_update_json({}, [], []) with open('repo/status/update.json') as fp: data = json.load(fp) self.assertTrue('apksigner' in data) @@ -1647,14 +1824,14 @@ class UpdateTest(unittest.TestCase): fdroidserver.update.config = { 'apksigner': 'apksigner', } - fdroidserver.update.status_update_json([], []) + fdroidserver.update.status_update_json({}, [], []) with open('repo/status/update.json') as fp: data = json.load(fp) self.assertEqual(shutil.which(fdroidserver.update.config['apksigner']), data['apksigner']) fdroidserver.update.config = {} fdroidserver.common.fill_config_defaults(fdroidserver.update.config) - fdroidserver.update.status_update_json([], []) + fdroidserver.update.status_update_json({}, [], []) with open('repo/status/update.json') as fp: data = json.load(fp) self.assertEqual(fdroidserver.update.config.get('apksigner'), data['apksigner']) @@ -1843,6 +2020,41 @@ class UpdateTest(unittest.TestCase): index['repo'][CATEGORIES_CONFIG_NAME], ) + def test_categories_with_only_icon_defined(self): + """If cateogories.yml only includes the icon, the name should be added.""" + os.chdir(self.testdir) + os.mkdir('config') + os.mkdir('metadata') + os.mkdir('repo') + fdroidserver.common.write_config_file( + 'repo_pubkey: ffffffffffffffffffffffffffffffffffffffff\n' + ) + testvalue = 'Time' + Path('config/time.png').write_text('placeholder') + Path('config/categories.yml').write_text(testvalue + ': {icon: time.png}') + + testapk = os.path.join('repo', 'com.politedroid_6.apk') + shutil.copy(basedir / testapk, testapk) + Path('metadata/com.politedroid.yml').write_text(f'Categories: [{testvalue}]') + + with mock.patch('sys.argv', ['fdroid update', '--delete-unknown', '--nosign']): + fdroidserver.update.main() + with open('repo/index-v2.json') as fp: + index = json.load(fp) + self.assertEqual( + { + 'icon': { + 'en-US': { + 'name': '/icons/time.png', + 'sha256': '4097889236a2af26c293033feb964c4cf118c0224e0d063fec0a89e9d0569ef2', + 'size': 11, + } + }, + 'name': {'en-US': testvalue}, + }, + index['repo'][CATEGORIES_CONFIG_NAME][testvalue], + ) + def test_auto_defined_categories_two_apps(self): """Repos that don't define categories in config/ should use auto-generated.""" os.chdir(self.testdir) diff --git a/tests/test_vcs.py b/tests/test_vcs.py index 2b640a9e..a007feae 100755 --- a/tests/test_vcs.py +++ b/tests/test_vcs.py @@ -7,7 +7,8 @@ from git import Repo import fdroidserver.common import fdroidserver.metadata -from .shared_test_code import mkdtemp, VerboseFalseOptions + +from .shared_test_code import VerboseFalseOptions, mkdtemp class VCSTest(unittest.TestCase): diff --git a/tests/test_verify.py b/tests/test_verify.py index adb24b29..e5a2f7c4 100755 --- a/tests/test_verify.py +++ b/tests/test_verify.py @@ -6,13 +6,11 @@ import shutil import sys import tempfile import unittest - from pathlib import Path from unittest.mock import patch from fdroidserver import verify - TEST_APP_ENTRY = { "1539780240.3885746": { "local": { @@ -122,3 +120,50 @@ class VerifyTest(unittest.TestCase): secondpass = json.load(fp) self.assertEqual(firstpass, secondpass) + + @patch('fdroidserver.common.sha256sum') + @patch('fdroidserver.verify.write_verified_json', lambda s: s) + def test_write_json_report_appid_json(self, sha256sum): + sha256sum.return_value = ( + '70c2f776a2bac38a58a7d521f96ee0414c6f0fb1de973c3ca8b10862a009247d' + ) + os.mkdir('tmp') + os.mkdir('unsigned') + appid = 'com.politedroid' + apk_name = f'{appid}_6.apk' + remote_apk = 'tmp/' + apk_name + unsigned_apk = 'unsigned/' + apk_name + shutil.copy(basedir / 'repo' / apk_name, remote_apk) + shutil.copy(basedir / 'repo' / apk_name, unsigned_apk) + url = TEST_APP_ENTRY['1539780240.3885746']['url'] + with open(f'unsigned/{apk_name}.json', 'w') as fp: + json.dump(TEST_APP_ENTRY, fp) + + # make a fake existing report where the newer one broke verifiability + with open(f'unsigned/{appid}_16.apk.json', 'w') as fp: + json.dump( + { + "1444444444.4444444": { + 'local': {'versionCode': 16}, + 'verified': False, + }, + "1333333333.3333333": { + 'local': {'versionCode': 16}, + 'verified': True, + }, + }, + fp, + ) + + verify.write_json_report(url, remote_apk, unsigned_apk, {'fake': 'fail'}) + with open(f'unsigned/{appid}.json') as fp: + self.assertEqual( + { + 'apkReports': [ + 'unsigned/com.politedroid_6.apk.json', + 'unsigned/com.politedroid_16.apk.json', + ], + 'lastRunVerified': False, + }, + json.load(fp), + ) diff --git a/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/featureGraphic/play_store_feature_graphic.png b/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/featureGraphic/play_store_feature_graphic.png new file mode 100644 index 00000000..0d5e3591 Binary files /dev/null and b/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/featureGraphic/play_store_feature_graphic.png differ diff --git a/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/icon/icon.png b/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/icon/icon.png new file mode 100644 index 00000000..17a31d54 Binary files /dev/null and b/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/icon/icon.png differ diff --git a/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/phoneScreenshots/1.png b/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/phoneScreenshots/1.png new file mode 100644 index 00000000..717be319 Binary files /dev/null and b/tests/triple-t-1-graphics/build/de.wivewa.dialer/app/src/main/play/en-US/listing/phoneScreenshots/1.png differ diff --git a/tests/triple-t-1-graphics/metadata/de.wivewa.dialer.yml b/tests/triple-t-1-graphics/metadata/de.wivewa.dialer.yml new file mode 100644 index 00000000..a86e2c53 --- /dev/null +++ b/tests/triple-t-1-graphics/metadata/de.wivewa.dialer.yml @@ -0,0 +1,25 @@ +Categories: + - Phone & SMS + - System +License: GPL-3.0-only +AuthorEmail: welefon@jolo.software +SourceCode: https://codeberg.org/wivewa/wivewa-dialer-android +IssueTracker: https://codeberg.org/wivewa/wivewa-dialer-android/issues + +AutoName: Welefon + +RepoType: git +Repo: https://codeberg.org/wivewa/wivewa-dialer-android.git + +Builds: + - versionName: 1.7.0 + versionCode: 13 + commit: 3550193fa6b6f7836876f2ca9bf5819a34eef404 + subdir: app + gradle: + - yes + +AutoUpdateMode: Version +UpdateCheckMode: Tags +CurrentVersion: 1.7.0 +CurrentVersionCode: 13