├── .eslintrc.js ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── dependabot.yml └── workflows │ ├── appstore-build-publish.yml │ ├── lint-eslint.yml │ ├── lint-info-xml.yml │ ├── lint-php-cs.yml │ ├── lint-php.yml │ ├── node.yml │ ├── pr-feedback.yml │ ├── psalm-matrix.yml │ └── release.yml ├── .gitignore ├── .l10nignore ├── .php-cs-fixer.dist.php ├── .tx └── config ├── AUTHORS.md ├── CHANGELOG.md ├── COPYING ├── README.md ├── appinfo ├── info.xml └── routes.php ├── composer.json ├── composer.lock ├── css └── dashboard.css ├── img ├── app-dark.svg ├── app.svg ├── google.svg └── screenshot1.jpg ├── l10n ├── .gitkeep ├── ar.js ├── ar.json ├── ast.js ├── ast.json ├── az.js ├── az.json ├── bg.js ├── bg.json ├── br.js ├── br.json ├── ca.js ├── ca.json ├── cs.js ├── cs.json ├── da.js ├── da.json ├── de.js ├── de.json ├── de_DE.js ├── de_DE.json ├── el.js ├── el.json ├── en_GB.js ├── en_GB.json ├── eo.js ├── eo.json ├── es.js ├── es.json ├── es_419.js ├── es_419.json ├── es_AR.js ├── es_AR.json ├── es_CL.js ├── es_CL.json ├── es_CO.js ├── es_CO.json ├── es_CR.js ├── es_CR.json ├── es_DO.js ├── es_DO.json ├── es_EC.js ├── es_EC.json ├── es_GT.js ├── es_GT.json ├── es_HN.js ├── es_HN.json ├── es_MX.js ├── es_MX.json ├── es_NI.js ├── es_NI.json ├── es_PA.js ├── es_PA.json ├── es_PE.js ├── es_PE.json ├── es_PR.js ├── es_PR.json ├── es_PY.js ├── es_PY.json ├── es_SV.js ├── es_SV.json ├── es_UY.js ├── es_UY.json ├── et_EE.js ├── et_EE.json ├── eu.js ├── eu.json ├── fa.js ├── fa.json ├── fi.js ├── fi.json ├── fr.js ├── fr.json ├── ga.js ├── ga.json ├── gl.js ├── gl.json ├── he.js ├── he.json ├── hr.js ├── hr.json ├── hu.js ├── hu.json ├── id.js ├── id.json ├── is.js ├── is.json ├── it.js ├── it.json ├── ja.js ├── ja.json ├── ka.js ├── ka.json ├── ka_GE.js ├── ka_GE.json ├── ko.js ├── ko.json ├── lb.js ├── lb.json ├── lt_LT.js ├── lt_LT.json ├── lv.js ├── lv.json ├── mk.js ├── mk.json ├── nb.js ├── nb.json ├── nl.js ├── nl.json ├── nn_NO.js ├── nn_NO.json ├── oc.js ├── oc.json ├── pl.js ├── pl.json ├── pt_BR.js ├── pt_BR.json ├── pt_PT.js ├── pt_PT.json ├── ro.js ├── ro.json ├── ru.js ├── ru.json ├── sc.js ├── sc.json ├── si.js ├── si.json ├── sk.js ├── sk.json ├── sl.js ├── sl.json ├── sq.js ├── sq.json ├── sr.js ├── sr.json ├── sv.js ├── sv.json ├── th.js ├── th.json ├── tr.js ├── tr.json ├── ug.js ├── ug.json ├── uk.js ├── uk.json ├── uz.js ├── uz.json ├── vi.js ├── vi.json ├── zh_CN.js ├── zh_CN.json ├── zh_HK.js ├── zh_HK.json ├── zh_TW.js └── zh_TW.json ├── lib ├── AppInfo │ └── Application.php ├── BackgroundJob │ ├── ImportDriveJob.php │ └── ImportPhotosJob.php ├── Controller │ ├── ConfigController.php │ └── GoogleAPIController.php ├── Migration │ └── Version03001001Date20241111105515.php ├── Notification │ └── Notifier.php ├── Service │ ├── GoogleAPIService.php │ ├── GoogleCalendarAPIService.php │ ├── GoogleContactsAPIService.php │ ├── GoogleDriveAPIService.php │ ├── GooglePhotosAPIService.php │ ├── SecretService.php │ └── UserScopeService.php └── Settings │ ├── Admin.php │ ├── AdminSection.php │ ├── Personal.php │ └── PersonalSection.php ├── makefile ├── package-lock.json ├── package.json ├── psalm-baseline.xml ├── psalm.xml ├── src ├── adminSettings.js ├── bootstrap.js ├── components │ ├── AdminSettings.vue │ ├── PersonalSettings.vue │ └── icons │ │ └── GoogleIcon.vue ├── personalSettings.js ├── popupSuccess.js └── utils.js ├── stylelint.config.js ├── templates ├── adminSettings.php ├── personalSettings.php └── popupSuccess.php ├── tests └── stub.phpstub └── webpack.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | globals: { 3 | appVersion: true 4 | }, 5 | parserOptions: { 6 | requireConfigFile: false 7 | }, 8 | extends: [ 9 | '@nextcloud' 10 | ], 11 | rules: { 12 | 'jsdoc/require-jsdoc': 'off', 13 | 'jsdoc/tag-lines': 'off', 14 | 'vue/first-attribute-linebreak': 'off', 15 | 'import/extensions': 'off' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | /appinfo/info.xml @marcelklehr @julien-nc 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a bug report for integration_google 3 | labels: ['bug'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: Thanks for taking the time to file a bug report! Please fill out this form as completely as possible. 8 | - type: input 9 | attributes: 10 | label: Which version of integration_google are you using? 11 | description: 'Please specify the exact version instead of "latest". For example: 2.0.2' 12 | validations: 13 | required: true 14 | - type: input 15 | attributes: 16 | label: Which version of Nextcloud are you using? 17 | description: 'For example: v23.0.1' 18 | validations: 19 | required: true 20 | - type: input 21 | attributes: 22 | label: Which browser are you using? In case you are using the phone App, specify the Android or iOS version and device please. 23 | description: 'Please specify the exact version instead of "latest". For example: Chrome 100.0.4878.0 or ' 24 | - type: textarea 25 | attributes: 26 | label: Describe the Bug 27 | description: A clear and concise description of what the bug is. 28 | validations: 29 | required: true 30 | - type: textarea 31 | attributes: 32 | label: Expected Behavior 33 | description: A clear and concise description of what you expected to happen. 34 | validations: 35 | required: true 36 | - type: textarea 37 | attributes: 38 | label: To Reproduce 39 | description: Steps to reproduce the behavior, please provide a clear number of steps that always reproduces the issue. Screenshots can be provided in the issue body below. 40 | validations: 41 | required: true 42 | - type: markdown 43 | attributes: 44 | value: | 45 | Before posting the issue go through the steps you've written down to make sure the steps provided are detailed and clear. 46 | Contributors should be able to follow the steps provided in order to reproduce the bug. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Create a feature request for integration_google 3 | labels: ['enhancement'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: Thanks for taking the time to file a feature request! Please fill out this form as completely as possible. 8 | - type: textarea 9 | attributes: 10 | label: Describe the feature you'd like to request 11 | description: A clear and concise description of what you want and what your use case is. 12 | validations: 13 | required: true 14 | - type: textarea 15 | attributes: 16 | label: Describe the solution you'd like 17 | description: A clear and concise description of what you want to happen. 18 | validations: 19 | required: true 20 | - type: textarea 21 | attributes: 22 | label: Describe alternatives you've considered 23 | description: A clear and concise description of any alternative solutions or features you've considered. 24 | validations: 25 | required: true 26 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: composer 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | day: saturday 8 | time: "03:00" 9 | timezone: Europe/Paris 10 | open-pull-requests-limit: 10 11 | - package-ecosystem: npm 12 | directory: "/" 13 | schedule: 14 | interval: weekly 15 | day: saturday 16 | time: "03:00" 17 | timezone: Europe/Paris 18 | open-pull-requests-limit: 10 19 | - package-ecosystem: "github-actions" 20 | directory: "/" 21 | schedule: 22 | interval: weekly 23 | day: saturday 24 | time: "03:00" 25 | timezone: Europe/Paris 26 | open-pull-requests-limit: 10 27 | -------------------------------------------------------------------------------- /.github/workflows/lint-eslint.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint eslint 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-eslint-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | changes: 22 | runs-on: ubuntu-latest-low 23 | permissions: 24 | contents: read 25 | pull-requests: read 26 | 27 | outputs: 28 | src: ${{ steps.changes.outputs.src}} 29 | 30 | steps: 31 | - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 32 | id: changes 33 | continue-on-error: true 34 | with: 35 | filters: | 36 | src: 37 | - '.github/workflows/**' 38 | - 'src/**' 39 | - 'appinfo/info.xml' 40 | - 'package.json' 41 | - 'package-lock.json' 42 | - 'tsconfig.json' 43 | - '.eslintrc.*' 44 | - '.eslintignore' 45 | - '**.js' 46 | - '**.ts' 47 | - '**.vue' 48 | 49 | lint: 50 | runs-on: ubuntu-latest 51 | 52 | needs: changes 53 | if: needs.changes.outputs.src != 'false' 54 | 55 | name: NPM lint 56 | 57 | steps: 58 | - name: Checkout 59 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 60 | with: 61 | persist-credentials: false 62 | 63 | - name: Read package.json node and npm engines version 64 | uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3 65 | id: versions 66 | with: 67 | fallbackNode: '^20' 68 | fallbackNpm: '^10' 69 | 70 | - name: Set up node ${{ steps.versions.outputs.nodeVersion }} 71 | uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 72 | with: 73 | node-version: ${{ steps.versions.outputs.nodeVersion }} 74 | 75 | - name: Set up npm ${{ steps.versions.outputs.npmVersion }} 76 | run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}' 77 | 78 | - name: Install dependencies 79 | env: 80 | CYPRESS_INSTALL_BINARY: 0 81 | PUPPETEER_SKIP_DOWNLOAD: true 82 | run: npm ci 83 | 84 | - name: Lint 85 | run: npm run lint 86 | 87 | summary: 88 | permissions: 89 | contents: none 90 | runs-on: ubuntu-latest-low 91 | needs: [changes, lint] 92 | 93 | if: always() 94 | 95 | # This is the summary, we just avoid to rename it so that branch protection rules still match 96 | name: eslint 97 | 98 | steps: 99 | - name: Summary status 100 | run: if ${{ needs.changes.outputs.src != 'false' && needs.lint.result != 'success' }}; then exit 1; fi 101 | -------------------------------------------------------------------------------- /.github/workflows/lint-info-xml.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint info.xml 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-info-xml-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | xml-linters: 22 | runs-on: ubuntu-latest-low 23 | 24 | name: info.xml lint 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 28 | with: 29 | persist-credentials: false 30 | 31 | - name: Download schema 32 | run: wget https://raw.githubusercontent.com/nextcloud/appstore/master/nextcloudappstore/api/v1/release/info.xsd 33 | 34 | - name: Lint info.xml 35 | uses: ChristophWurst/xmllint-action@36f2a302f84f8c83fceea0b9c59e1eb4a616d3c1 # v1.2 36 | with: 37 | xml-file: ./appinfo/info.xml 38 | xml-schema-file: ./info.xsd 39 | -------------------------------------------------------------------------------- /.github/workflows/lint-php-cs.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint php-cs 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-php-cs-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | lint: 22 | runs-on: ubuntu-latest 23 | 24 | name: php-cs 25 | 26 | steps: 27 | - name: Checkout 28 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 29 | with: 30 | persist-credentials: false 31 | 32 | - name: Get php version 33 | id: versions 34 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1 35 | 36 | - name: Set up php${{ steps.versions.outputs.php-min }} 37 | uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 38 | with: 39 | php-version: ${{ steps.versions.outputs.php-min }} 40 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite 41 | coverage: none 42 | ini-file: development 43 | env: 44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 45 | 46 | - name: Install dependencies 47 | run: | 48 | composer remove nextcloud/ocp --dev 49 | composer i 50 | 51 | - name: Lint 52 | run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 ) 53 | -------------------------------------------------------------------------------- /.github/workflows/lint-php.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint php 10 | 11 | on: 12 | pull_request: 13 | push: 14 | branches: 15 | - main 16 | - master 17 | - stable* 18 | 19 | permissions: 20 | contents: read 21 | 22 | concurrency: 23 | group: lint-php-${{ github.head_ref || github.run_id }} 24 | cancel-in-progress: true 25 | 26 | jobs: 27 | matrix: 28 | runs-on: ubuntu-latest-low 29 | outputs: 30 | php-versions: ${{ steps.versions.outputs.php-versions }} 31 | steps: 32 | - name: Checkout app 33 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 34 | with: 35 | persist-credentials: false 36 | 37 | - name: Get version matrix 38 | id: versions 39 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.0.0 40 | 41 | php-lint: 42 | runs-on: ubuntu-latest 43 | needs: matrix 44 | strategy: 45 | matrix: 46 | php-versions: ${{fromJson(needs.matrix.outputs.php-versions)}} 47 | 48 | name: php-lint 49 | 50 | steps: 51 | - name: Checkout 52 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 53 | with: 54 | persist-credentials: false 55 | 56 | - name: Set up php ${{ matrix.php-versions }} 57 | uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 58 | with: 59 | php-version: ${{ matrix.php-versions }} 60 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite 61 | coverage: none 62 | ini-file: development 63 | env: 64 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 65 | 66 | - name: Lint 67 | run: composer run lint 68 | 69 | summary: 70 | permissions: 71 | contents: none 72 | runs-on: ubuntu-latest-low 73 | needs: php-lint 74 | 75 | if: always() 76 | 77 | name: php-lint-summary 78 | 79 | steps: 80 | - name: Summary status 81 | run: if ${{ needs.php-lint.result != 'success' && needs.php-lint.result != 'skipped' }}; then exit 1; fi 82 | -------------------------------------------------------------------------------- /.github/workflows/node.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Node 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: node-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | changes: 22 | runs-on: ubuntu-latest-low 23 | permissions: 24 | contents: read 25 | pull-requests: read 26 | 27 | outputs: 28 | src: ${{ steps.changes.outputs.src}} 29 | 30 | steps: 31 | - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 32 | id: changes 33 | continue-on-error: true 34 | with: 35 | filters: | 36 | src: 37 | - '.github/workflows/**' 38 | - 'src/**' 39 | - 'appinfo/info.xml' 40 | - 'package.json' 41 | - 'package-lock.json' 42 | - 'tsconfig.json' 43 | - '**.js' 44 | - '**.ts' 45 | - '**.vue' 46 | 47 | build: 48 | runs-on: ubuntu-latest 49 | 50 | needs: changes 51 | if: needs.changes.outputs.src != 'false' 52 | 53 | name: NPM build 54 | steps: 55 | - name: Checkout 56 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 57 | with: 58 | persist-credentials: false 59 | 60 | - name: Read package.json node and npm engines version 61 | uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3 62 | id: versions 63 | with: 64 | fallbackNode: '^20' 65 | fallbackNpm: '^10' 66 | 67 | - name: Set up node ${{ steps.versions.outputs.nodeVersion }} 68 | uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 69 | with: 70 | node-version: ${{ steps.versions.outputs.nodeVersion }} 71 | 72 | - name: Set up npm ${{ steps.versions.outputs.npmVersion }} 73 | run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}' 74 | 75 | - name: Install dependencies & build 76 | env: 77 | CYPRESS_INSTALL_BINARY: 0 78 | PUPPETEER_SKIP_DOWNLOAD: true 79 | run: | 80 | npm ci 81 | npm run build --if-present 82 | 83 | - name: Check webpack build changes 84 | run: | 85 | bash -c "[[ ! \"`git status --porcelain `\" ]] || (echo 'Please recompile and commit the assets, see the section \"Show changes on failure\" for details' && exit 1)" 86 | 87 | - name: Show changes on failure 88 | if: failure() 89 | run: | 90 | git status 91 | git --no-pager diff 92 | exit 1 # make it red to grab attention 93 | 94 | summary: 95 | permissions: 96 | contents: none 97 | runs-on: ubuntu-latest-low 98 | needs: [changes, build] 99 | 100 | if: always() 101 | 102 | # This is the summary, we just avoid to rename it so that branch protection rules still match 103 | name: node 104 | 105 | steps: 106 | - name: Summary status 107 | run: if ${{ needs.changes.outputs.src != 'false' && needs.build.result != 'success' }}; then exit 1; fi 108 | -------------------------------------------------------------------------------- /.github/workflows/pr-feedback.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | 6 | # SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-FileCopyrightText: 2023 Marcel Klehr 8 | # SPDX-FileCopyrightText: 2023 Joas Schilling <213943+nickvergessen@users.noreply.github.com> 9 | # SPDX-FileCopyrightText: 2023 Daniel Kesselberg 10 | # SPDX-FileCopyrightText: 2023 Florian Steffens 11 | # SPDX-License-Identifier: MIT 12 | 13 | name: 'Ask for feedback on PRs' 14 | on: 15 | schedule: 16 | - cron: '30 1 * * *' 17 | 18 | permissions: 19 | contents: read 20 | pull-requests: write 21 | 22 | jobs: 23 | pr-feedback: 24 | if: ${{ github.repository_owner == 'nextcloud' }} 25 | runs-on: ubuntu-latest 26 | steps: 27 | - name: The get-github-handles-from-website action 28 | uses: marcelklehr/get-github-handles-from-website-action@06b2239db0a48fe1484ba0bfd966a3ab81a08308 # v1.0.1 29 | id: scrape 30 | with: 31 | website: 'https://nextcloud.com/team/' 32 | 33 | - name: Get blocklist 34 | id: blocklist 35 | run: | 36 | blocklist=$(curl https://raw.githubusercontent.com/nextcloud/.github/master/non-community-usernames.txt | paste -s -d, -) 37 | echo "blocklist=$blocklist" >> "$GITHUB_OUTPUT" 38 | 39 | - uses: nextcloud/pr-feedback-action@1883b38a033fb16f576875e0cf45f98b857655c4 # main 40 | with: 41 | feedback-message: | 42 | Hello there, 43 | Thank you so much for taking the time and effort to create a pull request to our Nextcloud project. 44 | 45 | We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. 46 | 47 | Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 48 | 49 | Thank you for contributing to Nextcloud and we hope to hear from you soon! 50 | 51 | (If you believe you should not receive this message, you can add yourself to the [blocklist](https://github.com/nextcloud/.github/blob/master/non-community-usernames.txt).) 52 | days-before-feedback: 14 53 | start-date: '2024-04-30' 54 | exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }}' 55 | exempt-bots: true 56 | -------------------------------------------------------------------------------- /.github/workflows/psalm-matrix.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Static analysis 10 | 11 | on: 12 | pull_request: 13 | push: 14 | branches: 15 | - main 16 | - master 17 | - stable* 18 | 19 | concurrency: 20 | group: psalm-${{ github.head_ref || github.run_id }} 21 | cancel-in-progress: true 22 | 23 | permissions: 24 | contents: read 25 | 26 | jobs: 27 | matrix: 28 | runs-on: ubuntu-latest-low 29 | outputs: 30 | ocp-matrix: ${{ steps.versions.outputs.ocp-matrix }} 31 | steps: 32 | - name: Checkout app 33 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 34 | with: 35 | persist-credentials: false 36 | 37 | - name: Get version matrix 38 | id: versions 39 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1 40 | 41 | - name: Check enforcement of minimum PHP version ${{ steps.versions.outputs.php-min }} in psalm.xml 42 | run: grep 'phpVersion="${{ steps.versions.outputs.php-min }}' psalm.xml 43 | 44 | static-analysis: 45 | runs-on: ubuntu-latest 46 | needs: matrix 47 | strategy: 48 | # do not stop on another job's failure 49 | fail-fast: false 50 | matrix: ${{ fromJson(needs.matrix.outputs.ocp-matrix) }} 51 | 52 | name: static-psalm-analysis ${{ matrix.ocp-version }} 53 | steps: 54 | - name: Checkout 55 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 56 | with: 57 | persist-credentials: false 58 | 59 | - name: Set up php${{ matrix.php-versions }} 60 | uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 61 | with: 62 | php-version: ${{ matrix.php-versions }} 63 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite 64 | coverage: none 65 | ini-file: development 66 | # Temporary workaround for missing pcntl_* in PHP 8.3 67 | ini-values: disable_functions= 68 | env: 69 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 70 | 71 | - name: Install dependencies 72 | run: | 73 | composer remove nextcloud/ocp --dev 74 | composer i 75 | 76 | 77 | - name: Install dependencies # zizmor: ignore[template-injection] 78 | run: composer require --dev 'nextcloud/ocp:${{ matrix.ocp-version }}' --ignore-platform-reqs --with-dependencies 79 | 80 | - name: Run coding standards check 81 | run: composer run psalm -- --threads=1 --monochrome --no-progress --output-format=github 82 | 83 | summary: 84 | runs-on: ubuntu-latest-low 85 | needs: static-analysis 86 | 87 | if: always() 88 | 89 | name: static-psalm-analysis-summary 90 | 91 | steps: 92 | - name: Summary status 93 | run: if ${{ needs.static-analysis.result != 'success' }}; then exit 1; fi 94 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [release] 4 | 5 | name: Publish release 6 | 7 | jobs: 8 | build: 9 | name: Build, upload and release in the appstore 10 | environment: release 11 | env: 12 | APP_ID: integration_google 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Use Node 16 16 | uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.2.0 17 | with: 18 | node-version: 16 19 | 20 | - name: Set up npm 21 | run: npm i -g npm@^8.0.0 22 | 23 | - name: Setup PHP 24 | uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 25 | with: 26 | php-version: '7.4' 27 | extensions: mbstring, intl, sqlite3 28 | ini-values: post_max_size=256M, max_execution_time=180 29 | coverage: xdebug 30 | tools: php-cs-fixer, phpunit 31 | 32 | - name: Checkout code 33 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 34 | 35 | - name: Get current tag 36 | id: tag 37 | run: | 38 | git fetch --tags --force 39 | tag=$(git tag -l --points-at HEAD) 40 | vtag=$(echo $tag | grep "^v[0-9]\+\.[0-9]\+\.[0-9]\+" || echo "") 41 | echo "##[set-output name=currenttag;]$vtag" 42 | 43 | - name: Build project 44 | if: ${{ startsWith( steps.tag.outputs.currenttag , 'v' ) }} 45 | id: build_release 46 | run: | 47 | echo "##[set-output name=app_id;]$APP_ID" 48 | echo "###### copy certificate" 49 | mkdir -p ~/.nextcloud/certificates 50 | echo "$APP_CRT" > ~/.nextcloud/certificates/${APP_ID}.crt 51 | echo "$APP_KEY" > ~/.nextcloud/certificates/${APP_ID}.key 52 | echo "###### install dependencies" 53 | # remove repo answering 402 54 | #sudo rm -f /etc/apt/sources.list.d/github_git-lfs.list 55 | export DEBIAN_FRONTEND=noninteractive 56 | sudo apt update -y 57 | sudo apt install composer make openssl -y 58 | echo "###### installing nextcloud" 59 | mkdir ~/html 60 | git clone https://github.com/nextcloud/server.git --recursive --depth 1 -b master ~/html/nextcloud 61 | sed -i $'s|if (substr($fullPath, 0, strlen($root) + 1) === $root . \'/\')|if (is_string($root) and substr($fullPath, 0, strlen($root) + 1) === $root . \'/\')|g' ~/html/nextcloud/lib/autoloader.php 62 | cp -r $GITHUB_WORKSPACE ~/html/nextcloud/apps/${APP_ID} 63 | php ~/html/nextcloud/occ maintenance:install --database "sqlite" --admin-user "admin" --admin-pass "password" 64 | php ~/html/nextcloud/occ app:enable ${APP_ID} 65 | php ~/html/nextcloud/occ maintenance:mode --off 66 | cd ~/html/nextcloud/apps/${APP_ID} 67 | echo "###### build app" 68 | make 69 | echo "###### make appstore" 70 | tag=${{ steps.tag.outputs.currenttag }} 71 | version=${tag/v/} 72 | webserveruser=runner occ_dir=~/html/nextcloud version=$version make appstore 73 | echo "##[set-output name=version;]$version" 74 | env: 75 | APP_CRT: ${{ secrets.APP_CRT }} 76 | APP_KEY: ${{ secrets.APP_KEY }} 77 | 78 | - name: Create Release 79 | if: ${{ startsWith( steps.tag.outputs.currenttag , 'v' ) }} 80 | id: create_release 81 | uses: actions/create-release@0cb9c9b65d5d1901c1f53e5e66eaf4afd303e70e # v1.1.4 82 | env: 83 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 84 | with: 85 | tag_name: ${{ steps.tag.outputs.currenttag }} 86 | release_name: ${{ steps.tag.outputs.currenttag }} 87 | draft: false 88 | prerelease: false 89 | 90 | - name: Upload Release Asset 91 | if: ${{ startsWith( steps.tag.outputs.currenttag , 'v' ) }} 92 | id: upload-release-asset 93 | uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 # v1.0.2 94 | env: 95 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 96 | with: 97 | upload_url: ${{ steps.create_release.outputs.upload_url }} 98 | asset_path: /tmp/build/${{ steps.build_release.outputs.app_id }}-${{ steps.build_release.outputs.version }}.tar.gz 99 | asset_name: ${{ steps.build_release.outputs.app_id }}-${{ steps.build_release.outputs.version }}.tar.gz 100 | asset_content_type: application/gzip 101 | 102 | - name: Publish normal release to appstore 103 | if: ${{ startsWith( steps.tag.outputs.currenttag , 'v' ) && !endsWith( steps.tag.outputs.currenttag , 'nightly' ) }} 104 | id: publish 105 | run: | 106 | SIGNATURE=$(cat /tmp/build/sign.txt | tr -d '\n') 107 | VERSION=${{ steps.build_release.outputs.version }} 108 | DOWNLOAD_URL=https://github.com/${{ github.repository }}/releases/download/v${VERSION}/${APP_ID}-${VERSION}.tar.gz 109 | curl -X POST -H "Authorization: Token $APPSTORE_TOKEN" https://apps.nextcloud.com/api/v1/apps/releases -H "Content-Type: application/json" -d '{"download":"'${DOWNLOAD_URL}'", "signature": "'${SIGNATURE}'"}' 110 | env: 111 | APPSTORE_TOKEN: ${{ secrets.APPSTORE_TOKEN }} 112 | 113 | - name: Publish nightly release to appstore 114 | if: ${{ startsWith( steps.tag.outputs.currenttag , 'v' ) && endsWith( steps.tag.outputs.currenttag , 'nightly' ) }} 115 | id: nightly 116 | run: | 117 | SIGNATURE=$(cat /tmp/build/sign.txt | tr -d '\n') 118 | VERSION=${{ steps.build_release.outputs.version }} 119 | DOWNLOAD_URL=https://github.com/${{ github.repository }}/releases/download/v${VERSION}/${APP_ID}-${VERSION}.tar.gz 120 | curl -X POST -H "Authorization: Token $APPSTORE_TOKEN" https://apps.nextcloud.com/api/v1/apps/releases -H "Content-Type: application/json" -d '{"download":"'${DOWNLOAD_URL}'", "signature": "'${SIGNATURE}'", "nightly": true}' 121 | env: 122 | APPSTORE_TOKEN: ${{ secrets.APPSTORE_TOKEN }} 123 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | js/ 2 | .code-workspace 3 | .DS_Store 4 | .idea/ 5 | .vscode/ 6 | .vscode-upload.json 7 | .*.sw* 8 | node_modules 9 | /vendor/ 10 | -------------------------------------------------------------------------------- /.l10nignore: -------------------------------------------------------------------------------- 1 | # compiled vue templates 2 | js/ 3 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | getFinder() 11 | ->in(__DIR__ . '/lib'); 12 | return $config; 13 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | lang_map = fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja, bg_BG: bg, cs_CZ: cs 4 | 5 | [o:nextcloud:p:nextcloud:r:integration_google] 6 | file_filter = translationfiles//integration_google.po 7 | source_file = translationfiles/templates/integration_google.pot 8 | source_lang = en 9 | type = PO 10 | 11 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | 3 | * Julien Veyssier (Developper) 4 | * @Ludovicis (Best tester ever!) 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Google integration in Nextcloud 2 | 3 | 🇬 Google integration allows you to automatically migrate your Google calendars, contacts, photos and files into Nextcloud. 4 | 5 | Note that this is a one-time import and will not keep Nextcloud in sync with Google. 6 | 7 | ## 🚀 Installation 8 | 9 | In your Nextcloud, simply enable the Google Integration app through the Apps management. 10 | The Google Integration app is available for Nextcloud >= 22. 11 | 12 | ## 🔧 Setup 13 | 14 | The app needs some setup in the Google API Console in order to work. 15 | To do this, go to Nextcloud Settings > Administration > Connected accounts and follow the instructions in the "Google integration" section. 16 | 17 | ## **🛠️ State of maintenance** 18 | 19 | While there are many things that could be done to further improve this app, the app is currently maintained with **limited effort**. This means: 20 | 21 | - The main functionality works for the majority of the use cases 22 | - We will ensure that the app will continue to work like this for future releases and we will fix bugs that we classify as 'critical' 23 | - We will not invest further development resources ourselves in advancing the app with new features 24 | - We do review and enthusiastically welcome community PR's 25 | 26 | We would be more than excited if you would like to collaborate with us. We will merge pull requests for new features and fixes. We also would love to welcome co-maintainers. 27 | 28 | If there is a strong business case for any development of this app, we will consider your wishes for our roadmap. Please [contact your account manager](https://nextcloud.com/enterprise/) to talk about the possibilities. 29 | -------------------------------------------------------------------------------- /appinfo/info.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | integration_google 4 | Google integration 5 | Import Google data into Nextcloud 6 | 7 | 4.0.0-dev 8 | agpl 9 | Julien Veyssier 10 | Google 11 | 12 | https://github.com/nextcloud/integration_google 13 | 14 | integration 15 | https://github.com/nextcloud/integration_google 16 | https://github.com/nextcloud/integration_google/issues 17 | https://github.com/nextcloud/integration_google/raw/master/img/screenshot1.jpg 18 | 19 | 20 | 21 | 22 | OCA\Google\Settings\Admin 23 | OCA\Google\Settings\AdminSection 24 | OCA\Google\Settings\Personal 25 | OCA\Google\Settings\PersonalSection 26 | 27 | 28 | -------------------------------------------------------------------------------- /appinfo/routes.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright Julien Veyssier 2020 10 | */ 11 | 12 | return [ 13 | 'routes' => [ 14 | ['name' => 'config#oauthRedirect', 'url' => '/oauth-redirect', 'verb' => 'GET'], 15 | ['name' => 'config#setConfig', 'url' => '/config', 'verb' => 'PUT'], 16 | ['name' => 'config#setAdminConfig', 'url' => '/admin-config', 'verb' => 'PUT'], 17 | ['name' => 'config#getLocalAddressBooks', 'url' => '/local-addressbooks', 'verb' => 'GET'], 18 | ['name' => 'config#popupSuccessPage', 'url' => '/popup-success', 'verb' => 'GET'], 19 | 20 | ['name' => 'googleAPI#getDriveSize', 'url' => '/drive-size', 'verb' => 'GET'], 21 | ['name' => 'googleAPI#getCalendarList', 'url' => '/calendars', 'verb' => 'GET'], 22 | ['name' => 'googleAPI#getContactNumber', 'url' => '/contact-number', 'verb' => 'GET'], 23 | ['name' => 'googleAPI#getPhotoNumber', 'url' => '/photo-number', 'verb' => 'GET'], 24 | ['name' => 'googleAPI#importCalendar', 'url' => '/import-calendar', 'verb' => 'GET'], 25 | ['name' => 'googleAPI#importContacts', 'url' => '/import-contacts', 'verb' => 'GET'], 26 | ['name' => 'googleAPI#importPhotos', 'url' => '/import-photos', 'verb' => 'GET'], 27 | ['name' => 'googleAPI#getImportPhotosInformation', 'url' => '/import-photos-info', 'verb' => 'GET'], 28 | ['name' => 'googleAPI#importDrive', 'url' => '/import-files', 'verb' => 'GET'], 29 | ['name' => 'googleAPI#getImportDriveInformation', 'url' => '/import-files-info', 'verb' => 'GET'], 30 | ] 31 | ]; 32 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": ">=8.1.0", 4 | "ortic/color-converter": "^0.1.0" 5 | }, 6 | "scripts": { 7 | "lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l", 8 | "cs:check": "php-cs-fixer fix --dry-run --diff", 9 | "cs:fix": "php-cs-fixer fix", 10 | "psalm": "psalm.phar", 11 | "psalm:update-baseline": "psalm.phar --threads=1 --update-baseline", 12 | "psalm:update-baseline:force": "psalm.phar --threads=1 --update-baseline --set-baseline=psalm-baseline.xml" 13 | }, 14 | "require-dev": { 15 | "friendsofphp/php-cs-fixer": "^3", 16 | "nextcloud/coding-standard": "^1", 17 | "psalm/phar": "6.7.x", 18 | "nextcloud/ocp": "dev-master" 19 | }, 20 | "config": { 21 | "platform": { 22 | "php": "8.1.0" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /css/dashboard.css: -------------------------------------------------------------------------------- 1 | .icon-google { 2 | background-image: url(./../img/app-dark.svg); 3 | } 4 | 5 | body.theme--dark .icon-google { 6 | background-image: url(./../img/app.svg); 7 | } -------------------------------------------------------------------------------- /img/app-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /img/app.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /img/google.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | btn_google_light_normal_ios 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /img/screenshot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/integration_google/d403fafc22c05ecfb444a4e532ffb78a447f854c/img/screenshot1.jpg -------------------------------------------------------------------------------- /l10n/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/integration_google/d403fafc22c05ecfb444a4e532ffb78a447f854c/l10n/.gitkeep -------------------------------------------------------------------------------- /l10n/ast.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Google" : "Google", 5 | "Data migration" : "Migración de los datos", 6 | "Client ID" : "ID de veceru", 7 | "Client secret" : "Secretu de veceru", 8 | "Failed to save Google options" : "Nun se puen guardar les opciones de Google", 9 | "Failed to get number of Google photos" : "Nun se pue consiguir el númberu de semeyes de Google", 10 | "Failed to get number of Google contacts" : "Nun se pue consiguir el númberu de contautos de Google", 11 | "Failed to import Google calendar" : "Nun se pue importar el calendariu de Google", 12 | "Failed to start importing Google photos" : "Nun se pue comenzar a importar les semeyes de Google", 13 | "Failed to start importing Google Drive" : "Nun se pue comenzar a importar Google Drive", 14 | "Authentication" : "Autenticación", 15 | "Contacts" : "Contautos", 16 | "Calendars" : "Calendarios", 17 | "Photos" : "Semeyes" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/ast.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Google" : "Google", 3 | "Data migration" : "Migración de los datos", 4 | "Client ID" : "ID de veceru", 5 | "Client secret" : "Secretu de veceru", 6 | "Failed to save Google options" : "Nun se puen guardar les opciones de Google", 7 | "Failed to get number of Google photos" : "Nun se pue consiguir el númberu de semeyes de Google", 8 | "Failed to get number of Google contacts" : "Nun se pue consiguir el númberu de contautos de Google", 9 | "Failed to import Google calendar" : "Nun se pue importar el calendariu de Google", 10 | "Failed to start importing Google photos" : "Nun se pue comenzar a importar les semeyes de Google", 11 | "Failed to start importing Google Drive" : "Nun se pue comenzar a importar Google Drive", 12 | "Authentication" : "Autenticación", 13 | "Contacts" : "Contautos", 14 | "Calendars" : "Calendarios", 15 | "Photos" : "Semeyes" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/az.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "Müştəri İD-s", 5 | "Client secret" : "Müxtəri sirri", 6 | "Authentication" : "Autentifikasiya", 7 | "Contacts" : "Əlaqələr", 8 | "Photos" : "Photos" 9 | }, 10 | "nplurals=2; plural=(n != 1);"); 11 | -------------------------------------------------------------------------------- /l10n/az.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "Müştəri İD-s", 3 | "Client secret" : "Müxtəri sirri", 4 | "Authentication" : "Autentifikasiya", 5 | "Contacts" : "Əlaqələr", 6 | "Photos" : "Photos" 7 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 8 | } -------------------------------------------------------------------------------- /l10n/br.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Google" : "Google", 5 | "Client ID" : "ID kliant", 6 | "Contacts" : "Darempredoù", 7 | "Calendars" : "Deiziataerioù", 8 | "Photos" : "Fotoioù", 9 | "Drive" : "Bleinañ" 10 | }, 11 | "nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);"); 12 | -------------------------------------------------------------------------------- /l10n/br.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Google" : "Google", 3 | "Client ID" : "ID kliant", 4 | "Contacts" : "Darempredoù", 5 | "Calendars" : "Deiziataerioù", 6 | "Photos" : "Fotoioù", 7 | "Drive" : "Bleinañ" 8 | },"pluralForm" :"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);" 9 | } -------------------------------------------------------------------------------- /l10n/ca.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Missing refresh token in Google response." : "Falta el testimoni d'actualització a la resposta de Google.", 5 | "Error getting OAuth access token." : "S'ha produït un error en obtenir testimoni d'accés OAuth.", 6 | "Error during OAuth exchanges" : "Error durant els intercanvis d'OAuth", 7 | "Google" : "Google", 8 | "OAuth access token refused" : "S'ha rebutjat el testimoni d'accés oAuth", 9 | "Bad credentials" : "Credencials dolentes", 10 | "Google Calendar import" : "Importació de Google Calendar", 11 | "Private event" : "Esdeveniment privat", 12 | "Connected accounts" : "Comptes connectats", 13 | "Data migration" : "Migració de dades", 14 | "Google integration" : "Integració de Google", 15 | "Import Google data into Nextcloud" : "Importar dades de Google a Nextcloud", 16 | "Google admin options saved" : "Opcions d'administrador de Google desades", 17 | "Failed to save Google admin options" : "No s'han pogut desar les opcions d'administració de Google", 18 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Si voleu permetre que els usuaris de Nextcloud es puguin autenticar a Google, creeu una aplicació OAuth a la configuració de Google.", 19 | "Google API settings" : "Configuració de l'API de Google", 20 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Aneu a \"APIs i Serveis\" => \"Credencials\" i feu clic a \"+ CREA CREDENCIALS\" -> \"ID de client OAuth\".", 21 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Definiu el \"Tipus d'aplicació\" a \"Aplicació web\" i doneu un nom a l'aplicació.", 22 | "Make sure you set one \"Authorized redirect URI\" to" : "Assegureu-vos de definir un \"URI de redirecció autoritzat\" a", 23 | "Put the \"Client ID\" and \"Client secret\" below." : "Posi el “ID Client\" i “Secret de Client\" a sota.", 24 | "Finally, go to \"APIs & Services\" => \"Library\" and add the following APIs: \"Google Drive API\", \"Google Calendar API\", \"People API\" and \"Photos Library API\"." : "Finalment, aneu a \"APIs & Services\" => \"Biblioteca\" i afegiu les API següents: \"API de Google Drive\", \"API de Google Calendar\", \"API de Persones\" i \"API de la Biblioteca de Fotos\".", 25 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Els usuaris de Nextcloud veuran un botó \"Connecta't a Google\" a la configuració personal.", 26 | "Client ID" : "ID de Client", 27 | "Client ID of your Google application" : "ID de client o la vostra aplicació Google", 28 | "Client secret" : "Secret del client", 29 | "Client secret of your Google application" : "Secret del client o de la vostra aplicació Google", 30 | "Last photo import job at {date}" : "Últim treball d'importació de fotos a {date}", 31 | "Photo import background process will begin soon." : "El procés de fons d'importació de fotos començarà aviat.", 32 | "You can close this page. You will be notified when it finishes." : "Podeu tancar aquesta pàgina. Se us notificarà quan acabi.", 33 | "Last Google Drive import job at {date}" : "Darrer treball d'importació de Google Drive a {date}", 34 | "Google Drive background import process will begin soon." : "El procés d'importació de fons de Google Drive començarà aviat.", 35 | "Successfully connected to Google!" : "S'ha connectat correctament a Google!", 36 | "Google connection error:" : "Error de connexió de Google:", 37 | "Google options saved" : "Opcions de Google desades.", 38 | "Failed to save Google options" : "No s'han pogut desar les opcions de Google", 39 | "Sign in with Google" : "Inicieu la sessió amb Google", 40 | "Failed to save Google OAuth state" : "No s'ha pogut desar l'estat de Google OAuth", 41 | "Failed to get Google Drive information" : "No s'ha pogut obtenir la informació de Google Drive", 42 | "Failed to get calendar list" : "No s'ha pogut obtenir la llista de calendaris", 43 | "Failed to get number of Google photos" : "No s'ha pogut obtenir el nombre de fotos de Google", 44 | "Failed to get number of Google contacts" : "No s'ha pogut obtenir el nombre de contactes de Google", 45 | "Failed to get address book list" : "No s'ha pogut obtenir la llista de la llibreta d'adreces", 46 | "Failed to import Google calendar" : "No s'ha pogut importar el calendari de Google", 47 | "Starting importing photos in {targetPath} directory" : "S'està començant a importar fotos al {targetPath} directori", 48 | "Failed to start importing Google photos" : "No s'ha pogut començar a importar fotos de Google", 49 | "Starting importing files in {targetPath} directory" : "S'està iniciant la importació de fitxers al directori {targetPath}", 50 | "Failed to start importing Google Drive" : "No s'ha pogut començar a importar Google Drive", 51 | "Google data migration" : "Migració de dades de Google", 52 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "No s'ha configurat cap aplicació Google OAuth. Demaneu a l'administrador de Nextcloud que configuri la secció d'administració de comptes connectades a Google.", 53 | "Authentication" : "Autenticació", 54 | "Connected as {user}" : "S'ha connectat com a {user}", 55 | "Disconnect from Google" : "Desconnectar-se de Google", 56 | "Contacts" : "Contactes", 57 | "{amount} Google contacts" : "{amount} Contactes de Google", 58 | "Import Google Contacts in Nextcloud" : "Importar contactes de Google a Nextcloud", 59 | "Choose where to import the contacts" : "Trieu on voleu importar els contactes", 60 | "New address book" : "Nova llibreta d'adreces", 61 | "address book name" : "nom de la llibreta d'adreces", 62 | "Calendars" : "Celendaris", 63 | "Import calendar" : "Importa un calendari", 64 | "Photos" : "Fotografies", 65 | "Ignore shared albums" : "Ignora els àlbums compartits", 66 | "Import directory" : "Carpeta d'importació", 67 | "Import Google photos" : "Importació de fotos de Google", 68 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "S'estima que la mida de la seva colecció de fotos de Google és més gran que l'espai restant que queda ({formSpace})", 69 | "Cancel photo import" : "Cancel·la la importació de fotos", 70 | "Drive" : "Conduir", 71 | "Ignore shared files" : "Ignora els fitxers compartits", 72 | "Import Google Drive files" : "Importar fitxers de Google Drive", 73 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "El seu Google Drive és més gran que l'espai restant que queda ({formSpace})", 74 | "Cancel Google Drive import" : "Cancel·lar la importació de Google Drive", 75 | "_{amount} photo imported_::_{amount} photos imported_" : ["{amount} foto importada","{amount} fotos importades"], 76 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} fitxer importat ({progress}%)","{amount} fitxers importats ({progress}%)"] 77 | }, 78 | "nplurals=2; plural=(n != 1);"); 79 | -------------------------------------------------------------------------------- /l10n/ca.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "Falta el testimoni d'actualització a la resposta de Google.", 3 | "Error getting OAuth access token." : "S'ha produït un error en obtenir testimoni d'accés OAuth.", 4 | "Error during OAuth exchanges" : "Error durant els intercanvis d'OAuth", 5 | "Google" : "Google", 6 | "OAuth access token refused" : "S'ha rebutjat el testimoni d'accés oAuth", 7 | "Bad credentials" : "Credencials dolentes", 8 | "Google Calendar import" : "Importació de Google Calendar", 9 | "Private event" : "Esdeveniment privat", 10 | "Connected accounts" : "Comptes connectats", 11 | "Data migration" : "Migració de dades", 12 | "Google integration" : "Integració de Google", 13 | "Import Google data into Nextcloud" : "Importar dades de Google a Nextcloud", 14 | "Google admin options saved" : "Opcions d'administrador de Google desades", 15 | "Failed to save Google admin options" : "No s'han pogut desar les opcions d'administració de Google", 16 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Si voleu permetre que els usuaris de Nextcloud es puguin autenticar a Google, creeu una aplicació OAuth a la configuració de Google.", 17 | "Google API settings" : "Configuració de l'API de Google", 18 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Aneu a \"APIs i Serveis\" => \"Credencials\" i feu clic a \"+ CREA CREDENCIALS\" -> \"ID de client OAuth\".", 19 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Definiu el \"Tipus d'aplicació\" a \"Aplicació web\" i doneu un nom a l'aplicació.", 20 | "Make sure you set one \"Authorized redirect URI\" to" : "Assegureu-vos de definir un \"URI de redirecció autoritzat\" a", 21 | "Put the \"Client ID\" and \"Client secret\" below." : "Posi el “ID Client\" i “Secret de Client\" a sota.", 22 | "Finally, go to \"APIs & Services\" => \"Library\" and add the following APIs: \"Google Drive API\", \"Google Calendar API\", \"People API\" and \"Photos Library API\"." : "Finalment, aneu a \"APIs & Services\" => \"Biblioteca\" i afegiu les API següents: \"API de Google Drive\", \"API de Google Calendar\", \"API de Persones\" i \"API de la Biblioteca de Fotos\".", 23 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Els usuaris de Nextcloud veuran un botó \"Connecta't a Google\" a la configuració personal.", 24 | "Client ID" : "ID de Client", 25 | "Client ID of your Google application" : "ID de client o la vostra aplicació Google", 26 | "Client secret" : "Secret del client", 27 | "Client secret of your Google application" : "Secret del client o de la vostra aplicació Google", 28 | "Last photo import job at {date}" : "Últim treball d'importació de fotos a {date}", 29 | "Photo import background process will begin soon." : "El procés de fons d'importació de fotos començarà aviat.", 30 | "You can close this page. You will be notified when it finishes." : "Podeu tancar aquesta pàgina. Se us notificarà quan acabi.", 31 | "Last Google Drive import job at {date}" : "Darrer treball d'importació de Google Drive a {date}", 32 | "Google Drive background import process will begin soon." : "El procés d'importació de fons de Google Drive començarà aviat.", 33 | "Successfully connected to Google!" : "S'ha connectat correctament a Google!", 34 | "Google connection error:" : "Error de connexió de Google:", 35 | "Google options saved" : "Opcions de Google desades.", 36 | "Failed to save Google options" : "No s'han pogut desar les opcions de Google", 37 | "Sign in with Google" : "Inicieu la sessió amb Google", 38 | "Failed to save Google OAuth state" : "No s'ha pogut desar l'estat de Google OAuth", 39 | "Failed to get Google Drive information" : "No s'ha pogut obtenir la informació de Google Drive", 40 | "Failed to get calendar list" : "No s'ha pogut obtenir la llista de calendaris", 41 | "Failed to get number of Google photos" : "No s'ha pogut obtenir el nombre de fotos de Google", 42 | "Failed to get number of Google contacts" : "No s'ha pogut obtenir el nombre de contactes de Google", 43 | "Failed to get address book list" : "No s'ha pogut obtenir la llista de la llibreta d'adreces", 44 | "Failed to import Google calendar" : "No s'ha pogut importar el calendari de Google", 45 | "Starting importing photos in {targetPath} directory" : "S'està començant a importar fotos al {targetPath} directori", 46 | "Failed to start importing Google photos" : "No s'ha pogut començar a importar fotos de Google", 47 | "Starting importing files in {targetPath} directory" : "S'està iniciant la importació de fitxers al directori {targetPath}", 48 | "Failed to start importing Google Drive" : "No s'ha pogut començar a importar Google Drive", 49 | "Google data migration" : "Migració de dades de Google", 50 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "No s'ha configurat cap aplicació Google OAuth. Demaneu a l'administrador de Nextcloud que configuri la secció d'administració de comptes connectades a Google.", 51 | "Authentication" : "Autenticació", 52 | "Connected as {user}" : "S'ha connectat com a {user}", 53 | "Disconnect from Google" : "Desconnectar-se de Google", 54 | "Contacts" : "Contactes", 55 | "{amount} Google contacts" : "{amount} Contactes de Google", 56 | "Import Google Contacts in Nextcloud" : "Importar contactes de Google a Nextcloud", 57 | "Choose where to import the contacts" : "Trieu on voleu importar els contactes", 58 | "New address book" : "Nova llibreta d'adreces", 59 | "address book name" : "nom de la llibreta d'adreces", 60 | "Calendars" : "Celendaris", 61 | "Import calendar" : "Importa un calendari", 62 | "Photos" : "Fotografies", 63 | "Ignore shared albums" : "Ignora els àlbums compartits", 64 | "Import directory" : "Carpeta d'importació", 65 | "Import Google photos" : "Importació de fotos de Google", 66 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "S'estima que la mida de la seva colecció de fotos de Google és més gran que l'espai restant que queda ({formSpace})", 67 | "Cancel photo import" : "Cancel·la la importació de fotos", 68 | "Drive" : "Conduir", 69 | "Ignore shared files" : "Ignora els fitxers compartits", 70 | "Import Google Drive files" : "Importar fitxers de Google Drive", 71 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "El seu Google Drive és més gran que l'espai restant que queda ({formSpace})", 72 | "Cancel Google Drive import" : "Cancel·lar la importació de Google Drive", 73 | "_{amount} photo imported_::_{amount} photos imported_" : ["{amount} foto importada","{amount} fotos importades"], 74 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} fitxer importat ({progress}%)","{amount} fitxers importats ({progress}%)"] 75 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 76 | } -------------------------------------------------------------------------------- /l10n/da.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error during OAuth exchanges" : "Fejl under OAuth-udvekslinger", 5 | "OAuth access token refused" : "OAuth adgangsnøgle afvist", 6 | "Bad credentials" : "Forkerte legitimationsoplysninger", 7 | "Connected accounts" : "Forbundne konti", 8 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Gå til \"API'er & services\" => \"Legitimationsoplysninger\" og klik på \"+ OPRET LEGITIMATIONSOPLYSNINGER\" -> \"OAuth klient ID\".", 9 | "Client ID" : "Klient ID", 10 | "Client secret" : "Klienthemmelighed", 11 | "Sign in with Google" : "Log ind med Google", 12 | "Authentication" : "Godkendelse", 13 | "Connected as {user}" : "Forbundet som {user}", 14 | "Contacts" : "Kontakter", 15 | "Calendars" : "Kalendere", 16 | "Import calendar" : "Importer kalender", 17 | "Photos" : "Billeder", 18 | "Drive" : "Drev" 19 | }, 20 | "nplurals=2; plural=(n != 1);"); 21 | -------------------------------------------------------------------------------- /l10n/da.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error during OAuth exchanges" : "Fejl under OAuth-udvekslinger", 3 | "OAuth access token refused" : "OAuth adgangsnøgle afvist", 4 | "Bad credentials" : "Forkerte legitimationsoplysninger", 5 | "Connected accounts" : "Forbundne konti", 6 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Gå til \"API'er & services\" => \"Legitimationsoplysninger\" og klik på \"+ OPRET LEGITIMATIONSOPLYSNINGER\" -> \"OAuth klient ID\".", 7 | "Client ID" : "Klient ID", 8 | "Client secret" : "Klienthemmelighed", 9 | "Sign in with Google" : "Log ind med Google", 10 | "Authentication" : "Godkendelse", 11 | "Connected as {user}" : "Forbundet som {user}", 12 | "Contacts" : "Kontakter", 13 | "Calendars" : "Kalendere", 14 | "Import calendar" : "Importer kalender", 15 | "Photos" : "Billeder", 16 | "Drive" : "Drev" 17 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 18 | } -------------------------------------------------------------------------------- /l10n/eo.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "Klientidentigilo", 5 | "Client secret" : "Klientosekreto", 6 | "Authentication" : "Aŭtentigo", 7 | "Contacts" : "Kontaktoj", 8 | "Import calendar" : "Enporti kalendaron", 9 | "Photos" : "Fotoj" 10 | }, 11 | "nplurals=2; plural=(n != 1);"); 12 | -------------------------------------------------------------------------------- /l10n/eo.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "Klientidentigilo", 3 | "Client secret" : "Klientosekreto", 4 | "Authentication" : "Aŭtentigo", 5 | "Contacts" : "Kontaktoj", 6 | "Import calendar" : "Enporti kalendaron", 7 | "Photos" : "Fotoj" 8 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 9 | } -------------------------------------------------------------------------------- /l10n/es_419.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_419.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_AR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Calendars" : "Calendarios", 9 | "Import calendar" : "Importar calendario", 10 | "Photos" : "Fotos" 11 | }, 12 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 13 | -------------------------------------------------------------------------------- /l10n/es_AR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Calendars" : "Calendarios", 7 | "Import calendar" : "Importar calendario", 8 | "Photos" : "Fotos" 9 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 10 | } -------------------------------------------------------------------------------- /l10n/es_CL.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Calendars" : "Calendarios", 9 | "Import calendar" : "Importar calendario", 10 | "Photos" : "Fotos" 11 | }, 12 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 13 | -------------------------------------------------------------------------------- /l10n/es_CL.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Calendars" : "Calendarios", 7 | "Import calendar" : "Importar calendario", 8 | "Photos" : "Fotos" 9 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 10 | } -------------------------------------------------------------------------------- /l10n/es_CO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_CO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_CR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_CR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_DO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_DO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_GT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_GT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_HN.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_HN.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_MX.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Sign in with Google" : "Iniciar sesión con Google", 7 | "Authentication" : "Autenticación", 8 | "Contacts" : "Contactos", 9 | "Calendars" : "Calendarios", 10 | "Import calendar" : "Importar calendario", 11 | "Photos" : "Fotos" 12 | }, 13 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 14 | -------------------------------------------------------------------------------- /l10n/es_MX.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Sign in with Google" : "Iniciar sesión con Google", 5 | "Authentication" : "Autenticación", 6 | "Contacts" : "Contactos", 7 | "Calendars" : "Calendarios", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 11 | } -------------------------------------------------------------------------------- /l10n/es_NI.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_NI.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_PA.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_PA.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_PE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_PE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_PR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_PR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_PY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_PY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_SV.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_SV.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/es_UY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID del cliente", 5 | "Client secret" : "Secreto del cliente", 6 | "Authentication" : "Autenticación", 7 | "Contacts" : "Contactos", 8 | "Import calendar" : "Importar calendario", 9 | "Photos" : "Fotos" 10 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /l10n/es_UY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID del cliente", 3 | "Client secret" : "Secreto del cliente", 4 | "Authentication" : "Autenticación", 5 | "Contacts" : "Contactos", 6 | "Import calendar" : "Importar calendario", 7 | "Photos" : "Fotos" 8 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /l10n/et_EE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Bad credentials" : "Vale kasutajanimi, salasõna või tunnusluba", 5 | "Connected accounts" : "Ühendatud kasutajakontod", 6 | "Client ID" : "Kliendi ID", 7 | "Client secret" : "Kliendi salasõna", 8 | "Sign in with Google" : "Logi sisse Google'i kontoga", 9 | "Authentication" : "Autentimine", 10 | "Connected as {user}" : "Ühendatud kui {user}", 11 | "Contacts" : "Kontaktid", 12 | "Calendars" : "Kalendrid", 13 | "Import calendar" : "Impordi kalender", 14 | "Photos" : "Fotod", 15 | "Drive" : "Sõit" 16 | }, 17 | "nplurals=2; plural=(n != 1);"); 18 | -------------------------------------------------------------------------------- /l10n/et_EE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Bad credentials" : "Vale kasutajanimi, salasõna või tunnusluba", 3 | "Connected accounts" : "Ühendatud kasutajakontod", 4 | "Client ID" : "Kliendi ID", 5 | "Client secret" : "Kliendi salasõna", 6 | "Sign in with Google" : "Logi sisse Google'i kontoga", 7 | "Authentication" : "Autentimine", 8 | "Connected as {user}" : "Ühendatud kui {user}", 9 | "Contacts" : "Kontaktid", 10 | "Calendars" : "Kalendrid", 11 | "Import calendar" : "Impordi kalender", 12 | "Photos" : "Fotod", 13 | "Drive" : "Sõit" 14 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 15 | } -------------------------------------------------------------------------------- /l10n/he.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error getting OAuth access token." : "שגיאה בקבלת אסימון גישה מסוג OAuth.", 5 | "Error during OAuth exchanges" : "שגיאה במהלך החלפות OAuth", 6 | "Google" : "Google", 7 | "OAuth access token refused" : "אסימון הגישה ב־OAuth סורב", 8 | "Bad credentials" : "פרטי גישה שגויים", 9 | "Private event" : "אירוע פרטי", 10 | "Connected accounts" : "חשבונות מחוברים", 11 | "Data migration" : "הגירת נתונים", 12 | "Client ID" : "מזהה לקו", 13 | "Client secret" : "סוד לקוח", 14 | "Authentication" : "אימות", 15 | "Disconnect from Google" : "ניתוק מ־Google", 16 | "Contacts" : "אנשי קשר", 17 | "{amount} Google contacts" : "{amount} אנשי קשר ב־Google", 18 | "Calendars" : "לוחות שנה", 19 | "Import calendar" : "ייבוא יומן", 20 | "Photos" : "תמונות", 21 | "Ignore shared albums" : "התעלמות מאלבומים משותפים", 22 | "Drive" : "נהיגה" 23 | }, 24 | "nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;"); 25 | -------------------------------------------------------------------------------- /l10n/he.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error getting OAuth access token." : "שגיאה בקבלת אסימון גישה מסוג OAuth.", 3 | "Error during OAuth exchanges" : "שגיאה במהלך החלפות OAuth", 4 | "Google" : "Google", 5 | "OAuth access token refused" : "אסימון הגישה ב־OAuth סורב", 6 | "Bad credentials" : "פרטי גישה שגויים", 7 | "Private event" : "אירוע פרטי", 8 | "Connected accounts" : "חשבונות מחוברים", 9 | "Data migration" : "הגירת נתונים", 10 | "Client ID" : "מזהה לקו", 11 | "Client secret" : "סוד לקוח", 12 | "Authentication" : "אימות", 13 | "Disconnect from Google" : "ניתוק מ־Google", 14 | "Contacts" : "אנשי קשר", 15 | "{amount} Google contacts" : "{amount} אנשי קשר ב־Google", 16 | "Calendars" : "לוחות שנה", 17 | "Import calendar" : "ייבוא יומן", 18 | "Photos" : "תמונות", 19 | "Ignore shared albums" : "התעלמות מאלבומים משותפים", 20 | "Drive" : "נהיגה" 21 | },"pluralForm" :"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;" 22 | } -------------------------------------------------------------------------------- /l10n/id.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error during OAuth exchanges" : "Terjadi kesalahan saat penukaran OAuth", 5 | "OAuth access token refused" : "Token akses OAuth ditolak", 6 | "Bad credentials" : "Kredensial tidak benar", 7 | "Connected accounts" : "Akun terhubung", 8 | "Client ID" : "ID Klien", 9 | "Client secret" : "Rahasia klien", 10 | "Use a pop-up to authenticate" : "Gunakan pop-up untuk mengautentikasi", 11 | "Authentication" : "Otentikasi", 12 | "Connected as {user}" : "Terhubung sebagai {user}", 13 | "Contacts" : "Kontak", 14 | "Calendars" : "Kalender", 15 | "Photos" : "Foto" 16 | }, 17 | "nplurals=1; plural=0;"); 18 | -------------------------------------------------------------------------------- /l10n/id.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error during OAuth exchanges" : "Terjadi kesalahan saat penukaran OAuth", 3 | "OAuth access token refused" : "Token akses OAuth ditolak", 4 | "Bad credentials" : "Kredensial tidak benar", 5 | "Connected accounts" : "Akun terhubung", 6 | "Client ID" : "ID Klien", 7 | "Client secret" : "Rahasia klien", 8 | "Use a pop-up to authenticate" : "Gunakan pop-up untuk mengautentikasi", 9 | "Authentication" : "Otentikasi", 10 | "Connected as {user}" : "Terhubung sebagai {user}", 11 | "Contacts" : "Kontak", 12 | "Calendars" : "Kalender", 13 | "Photos" : "Foto" 14 | },"pluralForm" :"nplurals=1; plural=0;" 15 | } -------------------------------------------------------------------------------- /l10n/is.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error during OAuth exchanges" : "Villa í OAuth-samskiptum", 5 | "OAuth access token refused" : "OAuth-aðgangsteikni hafnað", 6 | "Bad credentials" : "Gölluð auðkenni", 7 | "Connected accounts" : "Tengdir aðgangar", 8 | "Client ID" : "Biðlaraauðkenni", 9 | "Client secret" : "Leynilykill biðlara", 10 | "Sign in with Google" : "Skrá inn með Google", 11 | "Authentication" : "Auðkenning", 12 | "Connected as {user}" : "Tengt sem {user}", 13 | "Contacts" : "Tengiliðir", 14 | "Calendars" : "Dagatöl", 15 | "Import calendar" : "Flytja inn dagatal", 16 | "Photos" : "Ljósmyndir", 17 | "Import directory" : "Flytja möppu inn", 18 | "Drive" : "Keyra" 19 | }, 20 | "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); 21 | -------------------------------------------------------------------------------- /l10n/is.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error during OAuth exchanges" : "Villa í OAuth-samskiptum", 3 | "OAuth access token refused" : "OAuth-aðgangsteikni hafnað", 4 | "Bad credentials" : "Gölluð auðkenni", 5 | "Connected accounts" : "Tengdir aðgangar", 6 | "Client ID" : "Biðlaraauðkenni", 7 | "Client secret" : "Leynilykill biðlara", 8 | "Sign in with Google" : "Skrá inn með Google", 9 | "Authentication" : "Auðkenning", 10 | "Connected as {user}" : "Tengt sem {user}", 11 | "Contacts" : "Tengiliðir", 12 | "Calendars" : "Dagatöl", 13 | "Import calendar" : "Flytja inn dagatal", 14 | "Photos" : "Ljósmyndir", 15 | "Import directory" : "Flytja möppu inn", 16 | "Drive" : "Keyra" 17 | },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" 18 | } -------------------------------------------------------------------------------- /l10n/ja.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error during OAuth exchanges" : "OAuth通信中のエラー", 5 | "Google" : "Google", 6 | "OAuth access token refused" : "OAuthアクセストークンが拒否されました", 7 | "Bad credentials" : "不正な資格情報", 8 | "Private event" : "非公開イベント", 9 | "Connected accounts" : "接続済みアカウント", 10 | "Data migration" : "データ移行", 11 | "Google API settings" : "Google API 設定", 12 | "Client ID" : "クライアント ID", 13 | "Client secret" : "クライアントシークレット", 14 | "Successfully connected to Google!" : "Google への接続に成功しました!", 15 | "Sign in with Google" : "Googleでサインイン", 16 | "Google data migration" : "Google データの移行", 17 | "Authentication" : "認証", 18 | "Connected as {user}" : "{user} を接続済み", 19 | "Disconnect from Google" : "Google から切断", 20 | "Contacts" : "連絡先", 21 | "Choose where to import the contacts" : "連絡先をインポートする場所を選択してください", 22 | "New address book" : "新しいアドレス帳", 23 | "address book name" : "アドレス帳の名前", 24 | "Calendars" : "カレンダー", 25 | "Import calendar" : "カレンダーのインポート", 26 | "Photos" : "写真", 27 | "Ignore shared albums" : "共有済みアルバムを無視", 28 | "Import Google photos" : "Google フォトをインポート", 29 | "Drive" : "ドライブ", 30 | "Ignore shared files" : "共有済みファイルを無視" 31 | }, 32 | "nplurals=1; plural=0;"); 33 | -------------------------------------------------------------------------------- /l10n/ja.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error during OAuth exchanges" : "OAuth通信中のエラー", 3 | "Google" : "Google", 4 | "OAuth access token refused" : "OAuthアクセストークンが拒否されました", 5 | "Bad credentials" : "不正な資格情報", 6 | "Private event" : "非公開イベント", 7 | "Connected accounts" : "接続済みアカウント", 8 | "Data migration" : "データ移行", 9 | "Google API settings" : "Google API 設定", 10 | "Client ID" : "クライアント ID", 11 | "Client secret" : "クライアントシークレット", 12 | "Successfully connected to Google!" : "Google への接続に成功しました!", 13 | "Sign in with Google" : "Googleでサインイン", 14 | "Google data migration" : "Google データの移行", 15 | "Authentication" : "認証", 16 | "Connected as {user}" : "{user} を接続済み", 17 | "Disconnect from Google" : "Google から切断", 18 | "Contacts" : "連絡先", 19 | "Choose where to import the contacts" : "連絡先をインポートする場所を選択してください", 20 | "New address book" : "新しいアドレス帳", 21 | "address book name" : "アドレス帳の名前", 22 | "Calendars" : "カレンダー", 23 | "Import calendar" : "カレンダーのインポート", 24 | "Photos" : "写真", 25 | "Ignore shared albums" : "共有済みアルバムを無視", 26 | "Import Google photos" : "Google フォトをインポート", 27 | "Drive" : "ドライブ", 28 | "Ignore shared files" : "共有済みファイルを無視" 29 | },"pluralForm" :"nplurals=1; plural=0;" 30 | } -------------------------------------------------------------------------------- /l10n/ka.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "Client ID", 5 | "Client secret" : "Client secret", 6 | "Sign in with Google" : "Sign in with Google", 7 | "Authentication" : "Authentication", 8 | "Contacts" : "Contacts", 9 | "Calendars" : "Calendars", 10 | "Import calendar" : "Import calendar", 11 | "Drive" : "Drive" 12 | }, 13 | "nplurals=2; plural=(n!=1);"); 14 | -------------------------------------------------------------------------------- /l10n/ka.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "Client ID", 3 | "Client secret" : "Client secret", 4 | "Sign in with Google" : "Sign in with Google", 5 | "Authentication" : "Authentication", 6 | "Contacts" : "Contacts", 7 | "Calendars" : "Calendars", 8 | "Import calendar" : "Import calendar", 9 | "Drive" : "Drive" 10 | },"pluralForm" :"nplurals=2; plural=(n!=1);" 11 | } -------------------------------------------------------------------------------- /l10n/ka_GE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "კლიენტის ID", 5 | "Client secret" : "კლიენტის საიდუმლო", 6 | "Authentication" : "აუტენტიფიკაცია", 7 | "Contacts" : "კონტაქტები", 8 | "Import calendar" : "კალენდრის იმპორტი", 9 | "Photos" : "ფოტოები" 10 | }, 11 | "nplurals=2; plural=(n!=1);"); 12 | -------------------------------------------------------------------------------- /l10n/ka_GE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "კლიენტის ID", 3 | "Client secret" : "კლიენტის საიდუმლო", 4 | "Authentication" : "აუტენტიფიკაცია", 5 | "Contacts" : "კონტაქტები", 6 | "Import calendar" : "კალენდრის იმპორტი", 7 | "Photos" : "ფოტოები" 8 | },"pluralForm" :"nplurals=2; plural=(n!=1);" 9 | } -------------------------------------------------------------------------------- /l10n/ko.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error during OAuth exchanges" : "OAuth 교환 중 오류가 발생했습니다.", 5 | "OAuth access token refused" : "OAuth 액세스 토큰 거부됨", 6 | "Bad credentials" : "잘못된 자격 증명", 7 | "Connected accounts" : "계정 연결됨", 8 | "Client ID" : "클라이언트 ID", 9 | "Client secret" : "클라이언트 비밀 값", 10 | "Sign in with Google" : "구글 계정으로 로그인", 11 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "설정된 Google OAuth 앱이 없습니다. 이 Nextcloud 관리자에게 Google 계정 연결을 설정하도록 요청하십시오.", 12 | "Authentication" : "인증", 13 | "Connected as {user}" : "[user]로 연결됨", 14 | "Contacts" : "연락처", 15 | "Calendars" : "달력", 16 | "Import calendar" : "달력 가져오기", 17 | "Photos" : "사진", 18 | "Drive" : "드라이브" 19 | }, 20 | "nplurals=1; plural=0;"); 21 | -------------------------------------------------------------------------------- /l10n/ko.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error during OAuth exchanges" : "OAuth 교환 중 오류가 발생했습니다.", 3 | "OAuth access token refused" : "OAuth 액세스 토큰 거부됨", 4 | "Bad credentials" : "잘못된 자격 증명", 5 | "Connected accounts" : "계정 연결됨", 6 | "Client ID" : "클라이언트 ID", 7 | "Client secret" : "클라이언트 비밀 값", 8 | "Sign in with Google" : "구글 계정으로 로그인", 9 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "설정된 Google OAuth 앱이 없습니다. 이 Nextcloud 관리자에게 Google 계정 연결을 설정하도록 요청하십시오.", 10 | "Authentication" : "인증", 11 | "Connected as {user}" : "[user]로 연결됨", 12 | "Contacts" : "연락처", 13 | "Calendars" : "달력", 14 | "Import calendar" : "달력 가져오기", 15 | "Photos" : "사진", 16 | "Drive" : "드라이브" 17 | },"pluralForm" :"nplurals=1; plural=0;" 18 | } -------------------------------------------------------------------------------- /l10n/lb.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "Client ID", 5 | "Contacts" : "Kontakter", 6 | "Calendars" : "Kalenneren", 7 | "Import calendar" : "Kalenner importéiren", 8 | "Photos" : "Photos" 9 | }, 10 | "nplurals=2; plural=(n != 1);"); 11 | -------------------------------------------------------------------------------- /l10n/lb.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "Client ID", 3 | "Contacts" : "Kontakter", 4 | "Calendars" : "Kalenneren", 5 | "Import calendar" : "Kalenner importéiren", 6 | "Photos" : "Photos" 7 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 8 | } -------------------------------------------------------------------------------- /l10n/lt_LT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Missing refresh token in Google response." : "„Google“ atsakyme trūksta įkėlimo iš naujo prieigos rakto.", 5 | "Error getting OAuth access token." : "Klaida gaunant „OAuth“ prieigos raktą.", 6 | "Error during OAuth exchanges" : "Klaida „OAuth“ apsikeitimo metu", 7 | "Google" : "„Google“", 8 | "OAuth access token refused" : "„OAuth“ prieigos raktas atmestas", 9 | "Bad credentials" : "Blogi prisijungimo duomenys", 10 | "Google Calendar import" : "„Google“ kalendoriaus importavimas", 11 | "Private event" : "Privatus įvykis", 12 | "Connected accounts" : "Prijungtos paskyros", 13 | "Data migration" : "Duomenų perkėlimas", 14 | "Google integration" : "„Google“ integracija", 15 | "Import Google data into Nextcloud" : "Importuoti „Google“ duomenis į Nextcloud", 16 | "Google admin options saved" : "„Google“ administratoriaus parinktys įrašytos", 17 | "Failed to save Google admin options" : "Nepavyko įrašyti „Google“ administratoriaus parinkčių", 18 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Jei norite leisti savo Nextcloud naudotojams nustatinėti savo tapatybę „Google“ sistemoje, tuomet „Google“ nustatymuose sukurkite „OAuth“ programą.", 19 | "Google API settings" : "„Google“ API nustatymai", 20 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Tuomet jūsų Nextcloud naudotojai savo asmeniniuose nustatymuose matys mygtuką „Prisijungti prie „Google““", 21 | "Client ID" : "Kliento ID", 22 | "Client ID of your Google application" : "Jūsų „Google“ programos kliento ID", 23 | "Client secret" : "Kliento paslaptis", 24 | "Client secret of your Google application" : "Jūsų „Google“ programos kliento paslaptis", 25 | "Last photo import job at {date}" : "Paskutinė nuotraukų importavimo užduotis ties {date}", 26 | "Photo import background process will begin soon." : "Netrukus prasidės foninis nuotraukų importavimo procesas.", 27 | "You can close this page. You will be notified when it finishes." : "Galite užverti šį puslapį. Jums bus pranešta, kai ji užbaigs savo darbą.", 28 | "Last Google Drive import job at {date}" : "Paskutinė „Google“ disko importavimo užduotis ties {date}", 29 | "Google Drive background import process will begin soon." : "Netrukus prasidės foninis „Google“ disko importavimo procesas.", 30 | "Successfully connected to Google!" : "Sėkmingai prisijungta prie „Google“!", 31 | "Google connection error:" : "Ryšio su „Google“ klaida:", 32 | "Google options saved" : "„Google“ parinktys įrašytos", 33 | "Failed to save Google options" : "Nepavyko įrašyti „Google“ parinkčių", 34 | "Sign in with Google" : "Prisijungti naudojant „Google“", 35 | "Failed to save Google OAuth state" : "Nepavyko įrašyti „Google“ „OAuth“ būsenos", 36 | "Failed to get Google Drive information" : "Nepavyko gauti informacijos apie „Google“ diską", 37 | "Failed to get calendar list" : "Nepavyko gauti kalendorių sąrašo", 38 | "Failed to get number of Google photos" : "Nepavyko gauti „Google“ nuotraukų skaičiaus", 39 | "Failed to get number of Google contacts" : "Nepavyko gauti „Google“ adresatų skaičiaus", 40 | "Failed to get address book list" : "Nepavyko gauti adresų knygų sąrašo", 41 | "Failed to import Google calendar" : "Nepavyko importuoti „Google“ kalendoriaus", 42 | "Starting importing photos in {targetPath} directory" : "Pradedamas nuotraukų importavimas į {targetPath} katalogą", 43 | "Failed to start importing Google photos" : "Nepavyko pradėti „Google“ nuotraukų importavimo", 44 | "Starting importing files in {targetPath} directory" : "Pradedamas failų importavimas į {targetPath} katalogą", 45 | "Failed to start importing Google Drive" : "Nepavyko pradėti „Google“ disko importavimo", 46 | "Google data migration" : "„Google“ duomenų perkėlimas", 47 | "Authentication" : "Tapatybės nustatymas", 48 | "Connected as {user}" : "Prisijungta kaip {user}", 49 | "Disconnect from Google" : "Atsijungti nuo „Google“", 50 | "Contacts" : "Adresatai", 51 | "{amount} Google contacts" : "„Google“ adresatų: {amount}", 52 | "Import Google Contacts in Nextcloud" : "Importuoti „Google“ adresatus į Nextcloud", 53 | "Choose where to import the contacts" : "Pasirinkite kur importuoti adresatus", 54 | "New address book" : "Nauja adresų knyga", 55 | "address book name" : "adresų knygos pavadinimas", 56 | "Calendars" : "Kalendoriai", 57 | "Import calendar" : "Importuoti kalendorių", 58 | "Photos" : "Nuotraukos", 59 | "Ignore shared albums" : "Nepaisyti bendrinamų albumų", 60 | "Import directory" : "Importuoti katalogą", 61 | "Import Google photos" : "Importuoti „Google“ nuotraukas", 62 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "Apskaičiuotas „Google“ nuotraukų kolekcijos dydis yra didesnis, nei jums yra likę laisvos vietos ({formSpace})", 63 | "Cancel photo import" : "Atsisakyti nuotraukų importavimo", 64 | "Drive" : "Vairavimas", 65 | "Ignore shared files" : "Nepaisyti bendrinamų failų", 66 | "Import Google Drive files" : "Importuoti „Google“ disko failus", 67 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Jūsų „Google“ diskas yra didesnis, nei jums yra likę laisvos vietos ({formSpace})", 68 | "Cancel Google Drive import" : "Atsisakyti „Google“ disko importavimo", 69 | "_{amount} photo imported_::_{amount} photos imported_" : ["Importuota {amount} nuotrauka","Importuotos {amount} nuotraukos","Importuota {amount} nuotraukų","Importuota {amount} nuotrauka"], 70 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["Importuotas {amount} failas ({progress}%)","Importuoti {amount} failai ({progress}%)","Importuota {amount} failų ({progress}%)","Importuotas {amount} failas ({progress}%)"] 71 | }, 72 | "nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"); 73 | -------------------------------------------------------------------------------- /l10n/lt_LT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "„Google“ atsakyme trūksta įkėlimo iš naujo prieigos rakto.", 3 | "Error getting OAuth access token." : "Klaida gaunant „OAuth“ prieigos raktą.", 4 | "Error during OAuth exchanges" : "Klaida „OAuth“ apsikeitimo metu", 5 | "Google" : "„Google“", 6 | "OAuth access token refused" : "„OAuth“ prieigos raktas atmestas", 7 | "Bad credentials" : "Blogi prisijungimo duomenys", 8 | "Google Calendar import" : "„Google“ kalendoriaus importavimas", 9 | "Private event" : "Privatus įvykis", 10 | "Connected accounts" : "Prijungtos paskyros", 11 | "Data migration" : "Duomenų perkėlimas", 12 | "Google integration" : "„Google“ integracija", 13 | "Import Google data into Nextcloud" : "Importuoti „Google“ duomenis į Nextcloud", 14 | "Google admin options saved" : "„Google“ administratoriaus parinktys įrašytos", 15 | "Failed to save Google admin options" : "Nepavyko įrašyti „Google“ administratoriaus parinkčių", 16 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Jei norite leisti savo Nextcloud naudotojams nustatinėti savo tapatybę „Google“ sistemoje, tuomet „Google“ nustatymuose sukurkite „OAuth“ programą.", 17 | "Google API settings" : "„Google“ API nustatymai", 18 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Tuomet jūsų Nextcloud naudotojai savo asmeniniuose nustatymuose matys mygtuką „Prisijungti prie „Google““", 19 | "Client ID" : "Kliento ID", 20 | "Client ID of your Google application" : "Jūsų „Google“ programos kliento ID", 21 | "Client secret" : "Kliento paslaptis", 22 | "Client secret of your Google application" : "Jūsų „Google“ programos kliento paslaptis", 23 | "Last photo import job at {date}" : "Paskutinė nuotraukų importavimo užduotis ties {date}", 24 | "Photo import background process will begin soon." : "Netrukus prasidės foninis nuotraukų importavimo procesas.", 25 | "You can close this page. You will be notified when it finishes." : "Galite užverti šį puslapį. Jums bus pranešta, kai ji užbaigs savo darbą.", 26 | "Last Google Drive import job at {date}" : "Paskutinė „Google“ disko importavimo užduotis ties {date}", 27 | "Google Drive background import process will begin soon." : "Netrukus prasidės foninis „Google“ disko importavimo procesas.", 28 | "Successfully connected to Google!" : "Sėkmingai prisijungta prie „Google“!", 29 | "Google connection error:" : "Ryšio su „Google“ klaida:", 30 | "Google options saved" : "„Google“ parinktys įrašytos", 31 | "Failed to save Google options" : "Nepavyko įrašyti „Google“ parinkčių", 32 | "Sign in with Google" : "Prisijungti naudojant „Google“", 33 | "Failed to save Google OAuth state" : "Nepavyko įrašyti „Google“ „OAuth“ būsenos", 34 | "Failed to get Google Drive information" : "Nepavyko gauti informacijos apie „Google“ diską", 35 | "Failed to get calendar list" : "Nepavyko gauti kalendorių sąrašo", 36 | "Failed to get number of Google photos" : "Nepavyko gauti „Google“ nuotraukų skaičiaus", 37 | "Failed to get number of Google contacts" : "Nepavyko gauti „Google“ adresatų skaičiaus", 38 | "Failed to get address book list" : "Nepavyko gauti adresų knygų sąrašo", 39 | "Failed to import Google calendar" : "Nepavyko importuoti „Google“ kalendoriaus", 40 | "Starting importing photos in {targetPath} directory" : "Pradedamas nuotraukų importavimas į {targetPath} katalogą", 41 | "Failed to start importing Google photos" : "Nepavyko pradėti „Google“ nuotraukų importavimo", 42 | "Starting importing files in {targetPath} directory" : "Pradedamas failų importavimas į {targetPath} katalogą", 43 | "Failed to start importing Google Drive" : "Nepavyko pradėti „Google“ disko importavimo", 44 | "Google data migration" : "„Google“ duomenų perkėlimas", 45 | "Authentication" : "Tapatybės nustatymas", 46 | "Connected as {user}" : "Prisijungta kaip {user}", 47 | "Disconnect from Google" : "Atsijungti nuo „Google“", 48 | "Contacts" : "Adresatai", 49 | "{amount} Google contacts" : "„Google“ adresatų: {amount}", 50 | "Import Google Contacts in Nextcloud" : "Importuoti „Google“ adresatus į Nextcloud", 51 | "Choose where to import the contacts" : "Pasirinkite kur importuoti adresatus", 52 | "New address book" : "Nauja adresų knyga", 53 | "address book name" : "adresų knygos pavadinimas", 54 | "Calendars" : "Kalendoriai", 55 | "Import calendar" : "Importuoti kalendorių", 56 | "Photos" : "Nuotraukos", 57 | "Ignore shared albums" : "Nepaisyti bendrinamų albumų", 58 | "Import directory" : "Importuoti katalogą", 59 | "Import Google photos" : "Importuoti „Google“ nuotraukas", 60 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "Apskaičiuotas „Google“ nuotraukų kolekcijos dydis yra didesnis, nei jums yra likę laisvos vietos ({formSpace})", 61 | "Cancel photo import" : "Atsisakyti nuotraukų importavimo", 62 | "Drive" : "Vairavimas", 63 | "Ignore shared files" : "Nepaisyti bendrinamų failų", 64 | "Import Google Drive files" : "Importuoti „Google“ disko failus", 65 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Jūsų „Google“ diskas yra didesnis, nei jums yra likę laisvos vietos ({formSpace})", 66 | "Cancel Google Drive import" : "Atsisakyti „Google“ disko importavimo", 67 | "_{amount} photo imported_::_{amount} photos imported_" : ["Importuota {amount} nuotrauka","Importuotos {amount} nuotraukos","Importuota {amount} nuotraukų","Importuota {amount} nuotrauka"], 68 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["Importuotas {amount} failas ({progress}%)","Importuoti {amount} failai ({progress}%)","Importuota {amount} failų ({progress}%)","Importuotas {amount} failas ({progress}%)"] 69 | },"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);" 70 | } -------------------------------------------------------------------------------- /l10n/lv.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Bad credentials" : "Nederīgi pieteikšanās dati", 5 | "Connected accounts" : "Sasaistītie konti", 6 | "Google API settings" : "Google API iestatījumi", 7 | "Client ID" : "Klienta ID", 8 | "You can close this page. You will be notified when it finishes." : "Šo lapu var aizvērt. Tiks paziņot, kad tas tiks pabeigts.", 9 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Kav konfigurēta neviena Google OAuth lietotne. Jāvaicā savam Nextcloud pārvaldītājam, lai konfigurē sasaistīto google kontu pārvaldības sadaļu.", 10 | "Authentication" : "Autentifikācija", 11 | "Contacts" : "Kontakti", 12 | "Calendars" : "Kalendāri", 13 | "Import calendar" : "Importēt kalendāru", 14 | "Photos" : "Fotoattēli", 15 | "Import Google photos" : "Ievietot Google fotoattēlus", 16 | "Drive" : "Braukt" 17 | }, 18 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); 19 | -------------------------------------------------------------------------------- /l10n/lv.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Bad credentials" : "Nederīgi pieteikšanās dati", 3 | "Connected accounts" : "Sasaistītie konti", 4 | "Google API settings" : "Google API iestatījumi", 5 | "Client ID" : "Klienta ID", 6 | "You can close this page. You will be notified when it finishes." : "Šo lapu var aizvērt. Tiks paziņot, kad tas tiks pabeigts.", 7 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Kav konfigurēta neviena Google OAuth lietotne. Jāvaicā savam Nextcloud pārvaldītājam, lai konfigurē sasaistīto google kontu pārvaldības sadaļu.", 8 | "Authentication" : "Autentifikācija", 9 | "Contacts" : "Kontakti", 10 | "Calendars" : "Kalendāri", 11 | "Import calendar" : "Importēt kalendāru", 12 | "Photos" : "Fotoattēli", 13 | "Import Google photos" : "Ievietot Google fotoattēlus", 14 | "Drive" : "Braukt" 15 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" 16 | } -------------------------------------------------------------------------------- /l10n/nn_NO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Connected accounts" : "Tilkopla kontoar", 5 | "Client ID" : "Klient-ID", 6 | "Authentication" : "Godkjenning", 7 | "Contacts" : "Kontaktar", 8 | "Photos" : "Foto" 9 | }, 10 | "nplurals=2; plural=(n != 1);"); 11 | -------------------------------------------------------------------------------- /l10n/nn_NO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Connected accounts" : "Tilkopla kontoar", 3 | "Client ID" : "Klient-ID", 4 | "Authentication" : "Godkjenning", 5 | "Contacts" : "Kontaktar", 6 | "Photos" : "Foto" 7 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 8 | } -------------------------------------------------------------------------------- /l10n/oc.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Bad credentials" : "Marrits identificants", 5 | "Connected accounts" : "Comptes connectats", 6 | "Client ID" : "ID client", 7 | "Authentication" : "Autentificacion", 8 | "Connected as {user}" : "Connectat coma {user}", 9 | "Contacts" : "Contactes", 10 | "Calendars" : "Calendièrs", 11 | "Import calendar" : "Importar un calendièr", 12 | "Photos" : "Photos" 13 | }, 14 | "nplurals=2; plural=(n > 1);"); 15 | -------------------------------------------------------------------------------- /l10n/oc.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Bad credentials" : "Marrits identificants", 3 | "Connected accounts" : "Comptes connectats", 4 | "Client ID" : "ID client", 5 | "Authentication" : "Autentificacion", 6 | "Connected as {user}" : "Connectat coma {user}", 7 | "Contacts" : "Contactes", 8 | "Calendars" : "Calendièrs", 9 | "Import calendar" : "Importar un calendièr", 10 | "Photos" : "Photos" 11 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 12 | } -------------------------------------------------------------------------------- /l10n/pt_PT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error during OAuth exchanges" : "Erro durante trocas com o OAuth", 5 | "Bad credentials" : "Credenciais inválidas", 6 | "Client ID" : "Id. do Cliente", 7 | "Client secret" : "Segredo do cliente\\\\", 8 | "Authentication" : "Autenticação", 9 | "Contacts" : "Contactos", 10 | "Calendars" : "Calendários", 11 | "Import calendar" : "Importar calendário", 12 | "Photos" : "Fotos" 13 | }, 14 | "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 15 | -------------------------------------------------------------------------------- /l10n/pt_PT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error during OAuth exchanges" : "Erro durante trocas com o OAuth", 3 | "Bad credentials" : "Credenciais inválidas", 4 | "Client ID" : "Id. do Cliente", 5 | "Client secret" : "Segredo do cliente\\\\", 6 | "Authentication" : "Autenticação", 7 | "Contacts" : "Contactos", 8 | "Calendars" : "Calendários", 9 | "Import calendar" : "Importar calendário", 10 | "Photos" : "Fotos" 11 | },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 12 | } -------------------------------------------------------------------------------- /l10n/ro.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error during OAuth exchanges" : "Eroare în schimbarea OAuth", 5 | "OAuth access token refused" : "Token-ul OAuth a fost refuzat", 6 | "Bad credentials" : "Credențiale greșite", 7 | "Connected accounts" : "Conturile conectate", 8 | "Client ID" : "ID client", 9 | "Client secret" : "Secret client", 10 | "Authentication" : "Autentificare", 11 | "Contacts" : "Contacte", 12 | "Calendars" : "Calendare", 13 | "Import calendar" : "Import calendar", 14 | "Photos" : "Poze", 15 | "Drive" : "Conducere" 16 | }, 17 | "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"); 18 | -------------------------------------------------------------------------------- /l10n/ro.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error during OAuth exchanges" : "Eroare în schimbarea OAuth", 3 | "OAuth access token refused" : "Token-ul OAuth a fost refuzat", 4 | "Bad credentials" : "Credențiale greșite", 5 | "Connected accounts" : "Conturile conectate", 6 | "Client ID" : "ID client", 7 | "Client secret" : "Secret client", 8 | "Authentication" : "Autentificare", 9 | "Contacts" : "Contacte", 10 | "Calendars" : "Calendare", 11 | "Import calendar" : "Import calendar", 12 | "Photos" : "Poze", 13 | "Drive" : "Conducere" 14 | },"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));" 15 | } -------------------------------------------------------------------------------- /l10n/si.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Google" : "ගූගල්", 5 | "Connected accounts" : "සම්බන්ධිත ගිණුම්", 6 | "Data migration" : "දත්ත සංක්‍රමණය", 7 | "Google admin options saved" : "ගූගල් පරිපාලක විකල්ප සුරකින ලදි", 8 | "Failed to save Google admin options" : "ගූගල් පරිපාලක විකල්ප සුරැකීමට අපොහොසත් විය", 9 | "Google data migration" : "ගූගල් දත්ත සංක්‍රමණය", 10 | "Authentication" : "සත්‍යාපනය", 11 | "Disconnect from Google" : "ගූගල් වෙතින් විසන්ධි කරන්න", 12 | "New address book" : "නව ලිපින පොත", 13 | "Photos" : "ඡායාරූප" 14 | }, 15 | "nplurals=2; plural=(n != 1);"); 16 | -------------------------------------------------------------------------------- /l10n/si.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Google" : "ගූගල්", 3 | "Connected accounts" : "සම්බන්ධිත ගිණුම්", 4 | "Data migration" : "දත්ත සංක්‍රමණය", 5 | "Google admin options saved" : "ගූගල් පරිපාලක විකල්ප සුරකින ලදි", 6 | "Failed to save Google admin options" : "ගූගල් පරිපාලක විකල්ප සුරැකීමට අපොහොසත් විය", 7 | "Google data migration" : "ගූගල් දත්ත සංක්‍රමණය", 8 | "Authentication" : "සත්‍යාපනය", 9 | "Disconnect from Google" : "ගූගල් වෙතින් විසන්ධි කරන්න", 10 | "New address book" : "නව ලිපින පොත", 11 | "Photos" : "ඡායාරූප" 12 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 13 | } -------------------------------------------------------------------------------- /l10n/sl.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Missing refresh token in Google response." : "V odzivu strežnika Google manjka žeton za osvežitev.", 5 | "Error getting OAuth access token." : " Napaka med pridobivanjem žetona OAuth za dostop", 6 | "Error during OAuth exchanges" : " Napaka med izmenjavo podatkov OAuth", 7 | "Google" : "Google", 8 | "OAuth access token refused" : "Žeton OAuth za dostop je bil zavrnjen", 9 | "Bad credentials" : "Neustrezna poverila", 10 | "Google Calendar import" : "Uvoz koledarja Google", 11 | "Private event" : "Zasebni dogodek", 12 | "Connected accounts" : "Povezani računi", 13 | "Data migration" : "Preselitev podatkov", 14 | "Google integration" : "Združevalnik Google", 15 | "Import Google data into Nextcloud" : "Uvažanje podatkov Google v oblak Nextcloud", 16 | "Google admin options saved" : "Skrbniške nastavitve povezave Google so shranjene", 17 | "Failed to save Google admin options" : "Shranjevanje skrbniških nastavitev računa Google je spodletelo", 18 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Za overitev okolja Google znotraj Nextcloud je treba ustvariti program OAuth med nastavitvami Google.", 19 | "Google API settings" : "Nastavitve vmesnika Google API", 20 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Odprite nastavitev »Vmesnik API in storitve« > »Poverila« in kliknite na možnost »+ USTVARI POVERILA« > »Določilo ID OAuth«.", 21 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Nastavite »Vrsto programa« na »Spletni program« in podajte ime temu programu.", 22 | "Make sure you set one \"Authorized redirect URI\" to" : "Poskrbite, da bo »preusmeritveni naslov URI« nastavljen na", 23 | "Put the \"Client ID\" and \"Client secret\" below." : "Spodaj vpišite »ID programa« in »Geslo programa«.", 24 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Uporabniki Nextcloud bodo med nastavitvami videli gumb »Poveži z računom Google«", 25 | "Client ID" : "ID Odjemalca", 26 | "Client ID of your Google application" : "ID Odjemalca Google", 27 | "Client secret" : "Skrivni ključ odjemalca", 28 | "Client secret of your Google application" : "Koda programa za povezavo z računom Google", 29 | "Last photo import job at {date}" : "Zadnji uvoz slik je bil izveden {date}", 30 | "Photo import background process will begin soon." : "Uvoz slik bo kmalu začet v ozadju.", 31 | "You can close this page. You will be notified when it finishes." : "To stran lahko zaprete. Ob koncu opravila boste obveščeni, ko se to zaključi.", 32 | "Last Google Drive import job at {date}" : "Zadnji uvoz datotek z računa Goggle Drive je bil izveden {date}", 33 | "Google Drive background import process will begin soon." : "Uvažanje datotek z računa Google Drive bo kmalu začeto.", 34 | "Successfully connected to Google!" : "Povezava z računom Google je uspešno vzpostavljena!", 35 | "Google connection error:" : "Napaka povezave Google:", 36 | "Google options saved" : "Nastavitve Google so shranjene", 37 | "Failed to save Google options" : "Shranjevanje nastavitev Google je spodletelo", 38 | "Sign in with Google" : "Prijava z računom Google", 39 | "Failed to save Google OAuth state" : "Shranjevanje stanja Google OAuth je spodletelo", 40 | "Failed to get Google Drive information" : "Pridobivanje podrobnosti datotek Google Drive je spodletelo", 41 | "Failed to get calendar list" : "Pridobivanje seznama koledarja je spodletelo", 42 | "Failed to get number of Google photos" : "Pridobivanje podatka o številu slik je spodletelo", 43 | "Failed to get number of Google contacts" : "Pridobivanje podatka o številu stikov je spodletelo", 44 | "Failed to get address book list" : "Pridobivanje seznama imenika je spodletelo", 45 | "Failed to import Google calendar" : "Uvažanje koledarja Google je spodletelo", 46 | "Starting importing photos in {targetPath} directory" : "Začeto je uvažanje slik v mapo {targetPath}.", 47 | "Failed to start importing Google photos" : "Uvažanje slik z računa Google Photos je spodletelo", 48 | "Starting importing files in {targetPath} directory" : "Začeto je uvažanje datotek v mapo {targetPath}.", 49 | "Failed to start importing Google Drive" : "Uvažanje vsebine Google Drive je spodletelo", 50 | "Choose where to write imported files" : "Izbor mesta za shranjevanje uvoženih datotek", 51 | "Choose where to write imported photos" : "Izbor mesta za shranjevanje uvoženih slik", 52 | "Google data migration" : "Preselitev podatkov Google", 53 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Ni nastavljenega programa Google OAuth. Stopite v stik s skrbnikom sistema za nastavitev skrbniških možnosti računa.", 54 | "Authentication" : "Overitev", 55 | "Connected as {user}" : "Povezan je uporabniški račun {user}", 56 | "Disconnect from Google" : "Odklopi račun Google", 57 | "Contacts" : "Stiki", 58 | "{amount} Google contacts" : "{amount} stikov Google", 59 | "Import Google Contacts in Nextcloud" : "Uvozi Stike Google v Nextcloud", 60 | "Choose where to import the contacts" : "Izbor mesta za uvoz stikov", 61 | "New address book" : "Nov imenik", 62 | "address book name" : "ime imenika", 63 | "Calendars" : "Koledarji", 64 | "Import calendar" : "Uvozi koledar", 65 | "Photos" : "Fotografije", 66 | "Ignore shared albums" : "Prezri albume v souporabi", 67 | "Warning: Google does not provide location data in imported photos." : "Opozorilo: storitve Google ne omogočajo geolokacijskih podatkov v uvoženih fotografijah.", 68 | "Import directory" : "Uvozi mapo", 69 | "Import Google photos" : "Uvozi slike Google", 70 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "Velikost zbirke slik je večja od preostalega prostora ({formSpace})", 71 | "Cancel photo import" : "Prekliči uvoz slik z oblaka", 72 | "Drive" : "Drive", 73 | "Ignore shared files" : "Prezri datoteke v souporabi", 74 | "Google documents import format" : "Zapis za uvoz dokumentov Google", 75 | "Import Google Drive files" : "Uvozi datoteke z oblaka Google Drive", 76 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Velikost datotek v oblaku Google Drive je večja od preostalega prostora ({formSpace})", 77 | "Cancel Google Drive import" : "Prekliči uvoz datotek Google Drive", 78 | "_{amount} photo imported_::_{amount} photos imported_" : ["{amount} uvožena slika","{amount} uvoženi sliki","{amount} uvožene slike","{amount} uvoženih slik"], 79 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} uvožena datoteka ({progress}%)","{amount} uvoženi datoteki ({progress}%)","{amount} uvožene datoteke ({progress}%)","{amount} uvoženih datotek ({progress}%)"] 80 | }, 81 | "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); 82 | -------------------------------------------------------------------------------- /l10n/sl.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "V odzivu strežnika Google manjka žeton za osvežitev.", 3 | "Error getting OAuth access token." : " Napaka med pridobivanjem žetona OAuth za dostop", 4 | "Error during OAuth exchanges" : " Napaka med izmenjavo podatkov OAuth", 5 | "Google" : "Google", 6 | "OAuth access token refused" : "Žeton OAuth za dostop je bil zavrnjen", 7 | "Bad credentials" : "Neustrezna poverila", 8 | "Google Calendar import" : "Uvoz koledarja Google", 9 | "Private event" : "Zasebni dogodek", 10 | "Connected accounts" : "Povezani računi", 11 | "Data migration" : "Preselitev podatkov", 12 | "Google integration" : "Združevalnik Google", 13 | "Import Google data into Nextcloud" : "Uvažanje podatkov Google v oblak Nextcloud", 14 | "Google admin options saved" : "Skrbniške nastavitve povezave Google so shranjene", 15 | "Failed to save Google admin options" : "Shranjevanje skrbniških nastavitev računa Google je spodletelo", 16 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Za overitev okolja Google znotraj Nextcloud je treba ustvariti program OAuth med nastavitvami Google.", 17 | "Google API settings" : "Nastavitve vmesnika Google API", 18 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Odprite nastavitev »Vmesnik API in storitve« > »Poverila« in kliknite na možnost »+ USTVARI POVERILA« > »Določilo ID OAuth«.", 19 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Nastavite »Vrsto programa« na »Spletni program« in podajte ime temu programu.", 20 | "Make sure you set one \"Authorized redirect URI\" to" : "Poskrbite, da bo »preusmeritveni naslov URI« nastavljen na", 21 | "Put the \"Client ID\" and \"Client secret\" below." : "Spodaj vpišite »ID programa« in »Geslo programa«.", 22 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Uporabniki Nextcloud bodo med nastavitvami videli gumb »Poveži z računom Google«", 23 | "Client ID" : "ID Odjemalca", 24 | "Client ID of your Google application" : "ID Odjemalca Google", 25 | "Client secret" : "Skrivni ključ odjemalca", 26 | "Client secret of your Google application" : "Koda programa za povezavo z računom Google", 27 | "Last photo import job at {date}" : "Zadnji uvoz slik je bil izveden {date}", 28 | "Photo import background process will begin soon." : "Uvoz slik bo kmalu začet v ozadju.", 29 | "You can close this page. You will be notified when it finishes." : "To stran lahko zaprete. Ob koncu opravila boste obveščeni, ko se to zaključi.", 30 | "Last Google Drive import job at {date}" : "Zadnji uvoz datotek z računa Goggle Drive je bil izveden {date}", 31 | "Google Drive background import process will begin soon." : "Uvažanje datotek z računa Google Drive bo kmalu začeto.", 32 | "Successfully connected to Google!" : "Povezava z računom Google je uspešno vzpostavljena!", 33 | "Google connection error:" : "Napaka povezave Google:", 34 | "Google options saved" : "Nastavitve Google so shranjene", 35 | "Failed to save Google options" : "Shranjevanje nastavitev Google je spodletelo", 36 | "Sign in with Google" : "Prijava z računom Google", 37 | "Failed to save Google OAuth state" : "Shranjevanje stanja Google OAuth je spodletelo", 38 | "Failed to get Google Drive information" : "Pridobivanje podrobnosti datotek Google Drive je spodletelo", 39 | "Failed to get calendar list" : "Pridobivanje seznama koledarja je spodletelo", 40 | "Failed to get number of Google photos" : "Pridobivanje podatka o številu slik je spodletelo", 41 | "Failed to get number of Google contacts" : "Pridobivanje podatka o številu stikov je spodletelo", 42 | "Failed to get address book list" : "Pridobivanje seznama imenika je spodletelo", 43 | "Failed to import Google calendar" : "Uvažanje koledarja Google je spodletelo", 44 | "Starting importing photos in {targetPath} directory" : "Začeto je uvažanje slik v mapo {targetPath}.", 45 | "Failed to start importing Google photos" : "Uvažanje slik z računa Google Photos je spodletelo", 46 | "Starting importing files in {targetPath} directory" : "Začeto je uvažanje datotek v mapo {targetPath}.", 47 | "Failed to start importing Google Drive" : "Uvažanje vsebine Google Drive je spodletelo", 48 | "Choose where to write imported files" : "Izbor mesta za shranjevanje uvoženih datotek", 49 | "Choose where to write imported photos" : "Izbor mesta za shranjevanje uvoženih slik", 50 | "Google data migration" : "Preselitev podatkov Google", 51 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Ni nastavljenega programa Google OAuth. Stopite v stik s skrbnikom sistema za nastavitev skrbniških možnosti računa.", 52 | "Authentication" : "Overitev", 53 | "Connected as {user}" : "Povezan je uporabniški račun {user}", 54 | "Disconnect from Google" : "Odklopi račun Google", 55 | "Contacts" : "Stiki", 56 | "{amount} Google contacts" : "{amount} stikov Google", 57 | "Import Google Contacts in Nextcloud" : "Uvozi Stike Google v Nextcloud", 58 | "Choose where to import the contacts" : "Izbor mesta za uvoz stikov", 59 | "New address book" : "Nov imenik", 60 | "address book name" : "ime imenika", 61 | "Calendars" : "Koledarji", 62 | "Import calendar" : "Uvozi koledar", 63 | "Photos" : "Fotografije", 64 | "Ignore shared albums" : "Prezri albume v souporabi", 65 | "Warning: Google does not provide location data in imported photos." : "Opozorilo: storitve Google ne omogočajo geolokacijskih podatkov v uvoženih fotografijah.", 66 | "Import directory" : "Uvozi mapo", 67 | "Import Google photos" : "Uvozi slike Google", 68 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "Velikost zbirke slik je večja od preostalega prostora ({formSpace})", 69 | "Cancel photo import" : "Prekliči uvoz slik z oblaka", 70 | "Drive" : "Drive", 71 | "Ignore shared files" : "Prezri datoteke v souporabi", 72 | "Google documents import format" : "Zapis za uvoz dokumentov Google", 73 | "Import Google Drive files" : "Uvozi datoteke z oblaka Google Drive", 74 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Velikost datotek v oblaku Google Drive je večja od preostalega prostora ({formSpace})", 75 | "Cancel Google Drive import" : "Prekliči uvoz datotek Google Drive", 76 | "_{amount} photo imported_::_{amount} photos imported_" : ["{amount} uvožena slika","{amount} uvoženi sliki","{amount} uvožene slike","{amount} uvoženih slik"], 77 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} uvožena datoteka ({progress}%)","{amount} uvoženi datoteki ({progress}%)","{amount} uvožene datoteke ({progress}%)","{amount} uvoženih datotek ({progress}%)"] 78 | },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" 79 | } -------------------------------------------------------------------------------- /l10n/sq.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "ID klienti", 5 | "Client secret" : "E fshehtë klienti", 6 | "Authentication" : "Mirëfilltësim", 7 | "Contacts" : "Kontaktet", 8 | "Import calendar" : "Importo kalendar", 9 | "Photos" : "Foto" 10 | }, 11 | "nplurals=2; plural=(n != 1);"); 12 | -------------------------------------------------------------------------------- /l10n/sq.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "ID klienti", 3 | "Client secret" : "E fshehtë klienti", 4 | "Authentication" : "Mirëfilltësim", 5 | "Contacts" : "Kontaktet", 6 | "Import calendar" : "Importo kalendar", 7 | "Photos" : "Foto" 8 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 9 | } -------------------------------------------------------------------------------- /l10n/sv.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error getting OAuth access token." : "Kunde inte hämta OAuth-token.", 5 | "Error during OAuth exchanges" : "Fel vid utväxling av OAuth-token", 6 | "OAuth access token refused" : "OAuth-token avvisades", 7 | "Bad credentials" : "Ogiltiga inloggningsuppgifter", 8 | "Connected accounts" : "Anslutna konton", 9 | "Data migration" : "Datamigrering", 10 | "Google integration" : "Google-integrering", 11 | "Google API settings" : "Google API-inställningar", 12 | "Client ID" : "Klient-ID", 13 | "Client secret" : "Klienthemlighet", 14 | "Use a pop-up to authenticate" : "Använd en popup för att autentisera", 15 | "Photo import background process will begin soon." : "Fotoimportbakgrundsprocessen börjar snart.", 16 | "Sign in with Google" : "Sign in with Google", 17 | "Authentication" : "Autentisering", 18 | "Connected as {user}" : "Ansluten som {user}", 19 | "Disconnect from Google" : "Koppla ner från Google", 20 | "Contacts" : "Kontakter", 21 | "{amount} Google contacts" : "{amount} Google-kontakter", 22 | "Choose where to import the contacts" : "Välj vart kontakterna ska importeras", 23 | "New address book" : "Ny adressbok", 24 | "address book name" : "adressbokens namn", 25 | "Calendars" : "Kalendrar", 26 | "Import calendar" : "Importera kalender", 27 | "Photos" : "Bilder", 28 | "Import Google photos" : "Importera Google-foton", 29 | "Drive" : "Biltur" 30 | }, 31 | "nplurals=2; plural=(n != 1);"); 32 | -------------------------------------------------------------------------------- /l10n/sv.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error getting OAuth access token." : "Kunde inte hämta OAuth-token.", 3 | "Error during OAuth exchanges" : "Fel vid utväxling av OAuth-token", 4 | "OAuth access token refused" : "OAuth-token avvisades", 5 | "Bad credentials" : "Ogiltiga inloggningsuppgifter", 6 | "Connected accounts" : "Anslutna konton", 7 | "Data migration" : "Datamigrering", 8 | "Google integration" : "Google-integrering", 9 | "Google API settings" : "Google API-inställningar", 10 | "Client ID" : "Klient-ID", 11 | "Client secret" : "Klienthemlighet", 12 | "Use a pop-up to authenticate" : "Använd en popup för att autentisera", 13 | "Photo import background process will begin soon." : "Fotoimportbakgrundsprocessen börjar snart.", 14 | "Sign in with Google" : "Sign in with Google", 15 | "Authentication" : "Autentisering", 16 | "Connected as {user}" : "Ansluten som {user}", 17 | "Disconnect from Google" : "Koppla ner från Google", 18 | "Contacts" : "Kontakter", 19 | "{amount} Google contacts" : "{amount} Google-kontakter", 20 | "Choose where to import the contacts" : "Välj vart kontakterna ska importeras", 21 | "New address book" : "Ny adressbok", 22 | "address book name" : "adressbokens namn", 23 | "Calendars" : "Kalendrar", 24 | "Import calendar" : "Importera kalender", 25 | "Photos" : "Bilder", 26 | "Import Google photos" : "Importera Google-foton", 27 | "Drive" : "Biltur" 28 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 29 | } -------------------------------------------------------------------------------- /l10n/th.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Client ID" : "รหัสไคลเอ็นต์", 5 | "Client secret" : "ข้อมูลลับไคลเอ็นต์", 6 | "Authentication" : "การตรวจสอบสิทธิ์", 7 | "Connected as {user}" : "เชื่อมต่อเป็น {user} แล้ว", 8 | "Disconnect from Google" : "ยกเลิกการเชื่อมต่อจาก Google", 9 | "Contacts" : "รายชื่อ", 10 | "{amount} Google contacts" : "{amount} รายชื่อผู้ติดต่อ Google", 11 | "Calendars" : "ปฏิทิน", 12 | "Import calendar" : "นำเข้าปฏิทิน", 13 | "Photos" : "รูปภาพ" 14 | }, 15 | "nplurals=1; plural=0;"); 16 | -------------------------------------------------------------------------------- /l10n/th.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "รหัสไคลเอ็นต์", 3 | "Client secret" : "ข้อมูลลับไคลเอ็นต์", 4 | "Authentication" : "การตรวจสอบสิทธิ์", 5 | "Connected as {user}" : "เชื่อมต่อเป็น {user} แล้ว", 6 | "Disconnect from Google" : "ยกเลิกการเชื่อมต่อจาก Google", 7 | "Contacts" : "รายชื่อ", 8 | "{amount} Google contacts" : "{amount} รายชื่อผู้ติดต่อ Google", 9 | "Calendars" : "ปฏิทิน", 10 | "Import calendar" : "นำเข้าปฏิทิน", 11 | "Photos" : "รูปภาพ" 12 | },"pluralForm" :"nplurals=1; plural=0;" 13 | } -------------------------------------------------------------------------------- /l10n/uk.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Error during OAuth exchanges" : "Помилка під час обміну OAuth", 5 | "OAuth access token refused" : "Токен доступу OAuth відхилено", 6 | "Bad credentials" : "Погані облікові дані", 7 | "Connected accounts" : "Підключені облікові записи", 8 | "Client ID" : "Ідентифікатор клієнта", 9 | "Client secret" : "Ключ клієнта", 10 | "Sign in with Google" : "Увійдіть за допомогою Google", 11 | "Authentication" : "Авторизація", 12 | "Contacts" : "Контакти", 13 | "New address book" : "Нова адресна книга", 14 | "Calendars" : "Календарі", 15 | "Import calendar" : "Імпортувати календар", 16 | "Photos" : "Світлини", 17 | "Drive" : "Їхати автомобілем" 18 | }, 19 | "nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"); 20 | -------------------------------------------------------------------------------- /l10n/uk.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Error during OAuth exchanges" : "Помилка під час обміну OAuth", 3 | "OAuth access token refused" : "Токен доступу OAuth відхилено", 4 | "Bad credentials" : "Погані облікові дані", 5 | "Connected accounts" : "Підключені облікові записи", 6 | "Client ID" : "Ідентифікатор клієнта", 7 | "Client secret" : "Ключ клієнта", 8 | "Sign in with Google" : "Увійдіть за допомогою Google", 9 | "Authentication" : "Авторизація", 10 | "Contacts" : "Контакти", 11 | "New address book" : "Нова адресна книга", 12 | "Calendars" : "Календарі", 13 | "Import calendar" : "Імпортувати календар", 14 | "Photos" : "Світлини", 15 | "Drive" : "Їхати автомобілем" 16 | },"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);" 17 | } -------------------------------------------------------------------------------- /l10n/uz.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Bad credentials" : "Akkaunt ma'lumotlari xato", 5 | "Client ID" : "Mijoz identifikatori", 6 | "Authentication" : "Autentifikatsiya", 7 | "Contacts" : "Contacts", 8 | "Calendars" : "Taqvimlar", 9 | "Photos" : "Photos" 10 | }, 11 | "nplurals=1; plural=0;"); 12 | -------------------------------------------------------------------------------- /l10n/uz.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Bad credentials" : "Akkaunt ma'lumotlari xato", 3 | "Client ID" : "Mijoz identifikatori", 4 | "Authentication" : "Autentifikatsiya", 5 | "Contacts" : "Contacts", 6 | "Calendars" : "Taqvimlar", 7 | "Photos" : "Photos" 8 | },"pluralForm" :"nplurals=1; plural=0;" 9 | } -------------------------------------------------------------------------------- /l10n/vi.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Bad credentials" : "Thông tin đăng nhập không hợp lệ.", 5 | "Connected accounts" : "Đã kết nối tài khoản", 6 | "Client ID" : "ID khách hàng", 7 | "Authentication" : "Xác thực", 8 | "Connected as {user}" : "Kết nối bởi {user}", 9 | "Contacts" : "Liên hệ", 10 | "Calendars" : "Lịch", 11 | "Import calendar" : "Nhập lịch biểu", 12 | "Photos" : "Ảnh", 13 | "Drive" : "Lái xe" 14 | }, 15 | "nplurals=1; plural=0;"); 16 | -------------------------------------------------------------------------------- /l10n/vi.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Bad credentials" : "Thông tin đăng nhập không hợp lệ.", 3 | "Connected accounts" : "Đã kết nối tài khoản", 4 | "Client ID" : "ID khách hàng", 5 | "Authentication" : "Xác thực", 6 | "Connected as {user}" : "Kết nối bởi {user}", 7 | "Contacts" : "Liên hệ", 8 | "Calendars" : "Lịch", 9 | "Import calendar" : "Nhập lịch biểu", 10 | "Photos" : "Ảnh", 11 | "Drive" : "Lái xe" 12 | },"pluralForm" :"nplurals=1; plural=0;" 13 | } -------------------------------------------------------------------------------- /l10n/zh_CN.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Missing refresh token in Google response." : "Google 回应中缺少刷新令牌。", 5 | "Error getting OAuth access token." : "获取 OAuth 访问令牌出错", 6 | "Error during OAuth exchanges" : "交换 OAuth 时出错", 7 | "Google" : "Google", 8 | "OAuth access token refused" : "OAuth 访问令牌拒绝", 9 | "Bad credentials" : "认证出错", 10 | "Google Calendar import" : "导入 Google 日历", 11 | "Private event" : "私人活动", 12 | "Connected accounts" : "关联账号", 13 | "Data migration" : "数据迁移", 14 | "Google integration" : "Google 集成", 15 | "Import Google data into Nextcloud" : "将 Google 数据导入 Nextcloud", 16 | "Google admin options saved" : "Google 管理员选项已保存", 17 | "Failed to save Google admin options" : "保存Google管理员选项失败", 18 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "如果你想允许你的 Nextcloud 用户进行 Google 验证,在 Google 设置中创建一个 OAuth 应用程序。", 19 | "Google API settings" : "Google API 设置", 20 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "前往 \"APIs & Services\" => \"Credentials\" 然后点击 \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"。", 21 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "将“应用程序类型”设置为“Web应用程序”,并为应用程序指定一个名称。 ", 22 | "Put the \"Client ID\" and \"Client secret\" below." : "请在下方输入\"客户端ID\"和\"客户端密码\"。", 23 | "Finally, go to \"APIs & Services\" => \"Library\" and add the following APIs: \"Google Drive API\", \"Google Calendar API\", \"People API\" and \"Photos Library API\"." : "最后,转到“API & Services”=>“Library”,添加以下API:“Google云端硬盘 API”、“Google日历 API”、“People API”和“Photos Library API”。", 24 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "您的Nextcloud用户将在他们的个人设置中看到一个“连接到Google”按钮。 ", 25 | "Client ID" : "客户端ID", 26 | "Client ID of your Google application" : "您的Google应用程序的客户端ID ", 27 | "Client secret" : "客户端 secret", 28 | "You can close this page. You will be notified when it finishes." : "您可以关闭此页面。当它完成时,您将收到通知。", 29 | "Google Drive background import process will begin soon." : "Google云端硬盘后台导入过程即将开始。", 30 | "Successfully connected to Google!" : "成功连接到Google!", 31 | "Google connection error:" : "Google连接错误:", 32 | "Google options saved" : "Google 选项已保存", 33 | "Failed to save Google options" : "保存Google选项失败", 34 | "Sign in with Google" : "使用Google登录", 35 | "Failed to save Google OAuth state" : "保存Google OAuth状态失败", 36 | "Failed to get Google Drive information" : "无法获取Google云端硬盘信息", 37 | "Failed to get calendar list" : "获取日历列表失败", 38 | "Failed to get number of Google photos" : "无法获取Google照片数量", 39 | "Failed to get number of Google contacts" : "无法获取Google联系人数量", 40 | "Failed to get address book list" : "获取通讯录列表失败", 41 | "Failed to import Google calendar" : "导入Google日历失败", 42 | "Failed to start importing Google photos" : "无法开始导入Google照片", 43 | "Failed to start importing Google Drive" : "无法开始导入Google云端硬盘", 44 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "没有配置Google OAuth应用。请求你的Nextcloud管理员配置谷歌连接帐户管理部分。", 45 | "Authentication" : "验证", 46 | "Connected as {user}" : "作为 {user} 已连接", 47 | "Disconnect from Google" : "已从Google断开连接", 48 | "Contacts" : "联系人", 49 | "{amount} Google contacts" : "{amount} 位Google联系人", 50 | "Import Google Contacts in Nextcloud" : "在Nextcloud中导入Google联系人", 51 | "Choose where to import the contacts" : "选择从哪里导入联系人", 52 | "New address book" : "新通讯录", 53 | "address book name" : "通讯录名称", 54 | "Calendars" : "日历", 55 | "Import calendar" : "导入日历", 56 | "Photos" : "照片", 57 | "Ignore shared albums" : "忽略共享的相册", 58 | "Warning: Google does not provide location data in imported photos." : "警告:Google不提供导入照片中的位置数据。 ", 59 | "Import directory" : "导入文件夹", 60 | "Import Google photos" : "导入 Google Photos", 61 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "你的Google照片集大小估计大于你剩余的剩余空间 ({formSpace})", 62 | "Cancel photo import" : "取消照片导入", 63 | "Drive" : "驾驶", 64 | "Ignore shared files" : "忽略共享的文件", 65 | "Google documents import format" : "Google 文件导入格式", 66 | "Import Google Drive files" : "导入 Google Drive 文件", 67 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "您的Google云端硬盘大于你的剩余空间 ({formSpace})", 68 | "Cancel Google Drive import" : "取消 Google Drive 导入" 69 | }, 70 | "nplurals=1; plural=0;"); 71 | -------------------------------------------------------------------------------- /l10n/zh_CN.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "Google 回应中缺少刷新令牌。", 3 | "Error getting OAuth access token." : "获取 OAuth 访问令牌出错", 4 | "Error during OAuth exchanges" : "交换 OAuth 时出错", 5 | "Google" : "Google", 6 | "OAuth access token refused" : "OAuth 访问令牌拒绝", 7 | "Bad credentials" : "认证出错", 8 | "Google Calendar import" : "导入 Google 日历", 9 | "Private event" : "私人活动", 10 | "Connected accounts" : "关联账号", 11 | "Data migration" : "数据迁移", 12 | "Google integration" : "Google 集成", 13 | "Import Google data into Nextcloud" : "将 Google 数据导入 Nextcloud", 14 | "Google admin options saved" : "Google 管理员选项已保存", 15 | "Failed to save Google admin options" : "保存Google管理员选项失败", 16 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "如果你想允许你的 Nextcloud 用户进行 Google 验证,在 Google 设置中创建一个 OAuth 应用程序。", 17 | "Google API settings" : "Google API 设置", 18 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "前往 \"APIs & Services\" => \"Credentials\" 然后点击 \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"。", 19 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "将“应用程序类型”设置为“Web应用程序”,并为应用程序指定一个名称。 ", 20 | "Put the \"Client ID\" and \"Client secret\" below." : "请在下方输入\"客户端ID\"和\"客户端密码\"。", 21 | "Finally, go to \"APIs & Services\" => \"Library\" and add the following APIs: \"Google Drive API\", \"Google Calendar API\", \"People API\" and \"Photos Library API\"." : "最后,转到“API & Services”=>“Library”,添加以下API:“Google云端硬盘 API”、“Google日历 API”、“People API”和“Photos Library API”。", 22 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "您的Nextcloud用户将在他们的个人设置中看到一个“连接到Google”按钮。 ", 23 | "Client ID" : "客户端ID", 24 | "Client ID of your Google application" : "您的Google应用程序的客户端ID ", 25 | "Client secret" : "客户端 secret", 26 | "You can close this page. You will be notified when it finishes." : "您可以关闭此页面。当它完成时,您将收到通知。", 27 | "Google Drive background import process will begin soon." : "Google云端硬盘后台导入过程即将开始。", 28 | "Successfully connected to Google!" : "成功连接到Google!", 29 | "Google connection error:" : "Google连接错误:", 30 | "Google options saved" : "Google 选项已保存", 31 | "Failed to save Google options" : "保存Google选项失败", 32 | "Sign in with Google" : "使用Google登录", 33 | "Failed to save Google OAuth state" : "保存Google OAuth状态失败", 34 | "Failed to get Google Drive information" : "无法获取Google云端硬盘信息", 35 | "Failed to get calendar list" : "获取日历列表失败", 36 | "Failed to get number of Google photos" : "无法获取Google照片数量", 37 | "Failed to get number of Google contacts" : "无法获取Google联系人数量", 38 | "Failed to get address book list" : "获取通讯录列表失败", 39 | "Failed to import Google calendar" : "导入Google日历失败", 40 | "Failed to start importing Google photos" : "无法开始导入Google照片", 41 | "Failed to start importing Google Drive" : "无法开始导入Google云端硬盘", 42 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "没有配置Google OAuth应用。请求你的Nextcloud管理员配置谷歌连接帐户管理部分。", 43 | "Authentication" : "验证", 44 | "Connected as {user}" : "作为 {user} 已连接", 45 | "Disconnect from Google" : "已从Google断开连接", 46 | "Contacts" : "联系人", 47 | "{amount} Google contacts" : "{amount} 位Google联系人", 48 | "Import Google Contacts in Nextcloud" : "在Nextcloud中导入Google联系人", 49 | "Choose where to import the contacts" : "选择从哪里导入联系人", 50 | "New address book" : "新通讯录", 51 | "address book name" : "通讯录名称", 52 | "Calendars" : "日历", 53 | "Import calendar" : "导入日历", 54 | "Photos" : "照片", 55 | "Ignore shared albums" : "忽略共享的相册", 56 | "Warning: Google does not provide location data in imported photos." : "警告:Google不提供导入照片中的位置数据。 ", 57 | "Import directory" : "导入文件夹", 58 | "Import Google photos" : "导入 Google Photos", 59 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "你的Google照片集大小估计大于你剩余的剩余空间 ({formSpace})", 60 | "Cancel photo import" : "取消照片导入", 61 | "Drive" : "驾驶", 62 | "Ignore shared files" : "忽略共享的文件", 63 | "Google documents import format" : "Google 文件导入格式", 64 | "Import Google Drive files" : "导入 Google Drive 文件", 65 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "您的Google云端硬盘大于你的剩余空间 ({formSpace})", 66 | "Cancel Google Drive import" : "取消 Google Drive 导入" 67 | },"pluralForm" :"nplurals=1; plural=0;" 68 | } -------------------------------------------------------------------------------- /l10n/zh_HK.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "No logged in user" : "沒有登錄用戶", 5 | "Missing refresh token in Google response." : "Google 回應中缺少刷新權杖。", 6 | "Error getting OAuth access token." : "取得 OAuth 存取權杖時發生錯誤。", 7 | "Error during OAuth exchanges" : "OAuth 交換時發生錯誤", 8 | "Google" : "Google", 9 | "_%n photo was imported from Google._::_%n photos were imported from Google._" : ["從 Google 匯入了 %n 張照片。"], 10 | "_%n file was imported from Google Drive._::_%n files were imported from Google Drive._" : ["從 Google Drive 匯入了 %n 個檔案。"], 11 | "OAuth access token refused" : "OAuth 存取權杖被拒絕", 12 | "Bad credentials" : "錯誤的身分驗證", 13 | "Google Calendar import" : "匯入 Google 日曆", 14 | "Private event" : "私人活動", 15 | "Connected accounts" : "已連線的帳號", 16 | "Data migration" : "數據遷移", 17 | "Google integration" : "Google 整合", 18 | "Import Google data into Nextcloud" : "將 Google 數據匯入 Nextcloud", 19 | "Google integration allows you to automatically migrate your Google calendars, contacts, photos and files into Nextcloud." : "Google 整合讓您自動將 Google Calendar,Contacts,Photos 和 Doc 遷移至 Nextcloud。", 20 | "Google admin options saved" : "已儲存 Google 管理員選項", 21 | "Failed to save Google admin options" : "儲存 Google 管理選項失敗", 22 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "如欲允許您的 Nextcloud 用戶向 Google 進行身份驗證,請在您的 Google 設置中創建一個 OAuth 應用程式。", 23 | "Google API settings" : "Google API 設定", 24 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "前往 \"APIs & Services\" => \"Credentials\" 然後單擊 \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"。", 25 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "將「Application type」設置為 \"Web application\",然後為應用程序命名。", 26 | "Google may require site verification for OAuth to work with your site, which can be done in Google's search console" : "Google可能需要對您的網站進行驗證,以便 OAuth 正常運作,這可以在 Google 搜尋控制台中完成", 27 | "Google Search console" : "Google 搜尋控制台", 28 | "Make sure you set one \"Authorized redirect URI\" to" : "確保您將「Authorized redirect URI」設定為", 29 | "Put the \"Client ID\" and \"Client secret\" below." : "在下方輸入「客戶端 ID」與「客戶端密碼」。", 30 | "Finally, go to \"APIs & Services\" => \"Library\" and add the following APIs: \"Google Drive API\", \"Google Calendar API\", \"People API\" and \"Photos Library API\"." : "最後,轉到 \"APIs & Services\" => \"Library\" 並添加以下 API:\"Google Drive API\"、\"Google Calendar API\"、\"People API\" 和 \"Photos Library API\"。", 31 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "您的 Nextcloud 用戶將會在他們的個人設定中看到【連線至 Google】按鈕。", 32 | "Client ID" : "客戶端 ID", 33 | "Client ID of your Google application" : "您 Google 應用程式的客戶端 ID", 34 | "Client secret" : "客戶端密碼", 35 | "Client secret of your Google application" : "您 Google 應用程式的客戶端密碼", 36 | "Use a pop-up to authenticate" : "使用彈出式視窗進行身份驗證", 37 | "Last photo import job at {date}" : "上次照片導入作業於 {date} 執行", 38 | "Photo import background process will begin soon." : "照片導入後台作業進程即將開始。", 39 | "You can close this page. You will be notified when it finishes." : "您可以關閉此頁面。完成時會通知您。", 40 | "Last Google Drive import job at {date}" : "上一次 Google Drive 導入作業的運行日期為 {date}", 41 | "Google Drive background import process will begin soon." : "Google Drive 導入後台作業進程即將開始。", 42 | "Successfully connected to Google!" : "與 Google 連線成功!", 43 | "Google connection error:" : "Google 連線錯誤: ", 44 | "Google options saved" : "已儲存 Google 選項", 45 | "Failed to save Google options" : "儲存 Google 選項失敗", 46 | "Sign in with Google" : "使用 Google 登入", 47 | "Failed to save Google OAuth state" : "儲存 Google OAuth 狀態失敗", 48 | "Failed to get Google Drive information" : "無法獲取Google Drive資訊", 49 | "Failed to get calendar list" : "讀取日曆清單失敗", 50 | "Failed to get number of Google photos" : "無法獲取Google照片數量", 51 | "Failed to get number of Google contacts" : "無法獲取Google聯絡人數量", 52 | "Failed to get address book list" : "讀取通訊錄清單失敗", 53 | "_{nbSeen} Google contact seen. {nbAdded} added, {nbUpdated} updated in {name}_::_{nbSeen} Google contacts seen. {nbAdded} added, {nbUpdated} updated in {name}_" : ["在 {name} 已看到 {nbSeen} 個 Google 聯絡人。已添加 {nbAdded} 個 ,更新了 {nbUpdated} 個"], 54 | "_{total} event successfully imported in {name} ({nbAdded} created, {nbUpdated} updated)_::_{total} events successfully imported in {name} ({nbAdded} created, {nbUpdated} updated)_" : ["在 {name} 中成功導入了 {total} 個活動(創建了 {nbAdded} 個,更新了 {nbUpdated} 個)"], 55 | "Failed to import Google calendar" : "無法匯入 Google 日曆", 56 | "Starting importing photos in {targetPath} directory" : "開始將照片導入到 {targetPath} 目錄", 57 | "Failed to start importing Google photos" : "無法開始導入 Google 照片", 58 | "Starting importing files in {targetPath} directory" : "開始將檔案導入到 {targetPath} 目錄", 59 | "Failed to start importing Google Drive" : "無法開始導入Google Drive", 60 | "Choose where to write imported files" : "選擇寫入導入檔案的位置", 61 | "Choose where to write imported photos" : "選擇寫入導入照片的位置", 62 | "Google data migration" : "Google 數據遷移", 63 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "未配置Google OAuth應用程式。要求您的Nextcloud管理員配置Google關聯帳戶管理部分。", 64 | "Authentication" : "驗證", 65 | "Connected as {user}" : "以 {user} 身分連線", 66 | "Disconnect from Google" : "與 Google 斷開連線", 67 | "Contacts" : "聯絡人", 68 | "{amount} Google contacts" : "{amount} 位 Google 聯絡人", 69 | "Import Google Contacts in Nextcloud" : "將 Google Contacts 匯入 Nextcloud", 70 | "Choose where to import the contacts" : "選擇導入聯絡人的通訊錄", 71 | "New address book" : "新通訊錄", 72 | "address book name" : "通訊錄名稱", 73 | "Import in \"{name}\" address book" : "導入 \"{name}\" 通訊錄", 74 | "Calendars" : "日曆", 75 | "Import calendar" : "導入日曆", 76 | "Photos" : "Photos", 77 | "Ignore shared albums" : "略過共享的相薄", 78 | "Warning: Google does not provide location data in imported photos." : "警告:Google不會在導入的照片中提供位置數據。", 79 | "Import directory" : "導入資料夾", 80 | "Import Google photos" : "導入 Google Photos", 81 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "您 Google 照片集的大小估計大於剩餘空間({formSpace})", 82 | "Cancel photo import" : "取消照片導入", 83 | "Drive" : "Drive", 84 | "Ignore shared files" : "略過共享的檔案", 85 | "Google documents import format" : "Google文件導入格式", 86 | "Your Google Drive ({formSize} + {formSharedSize} shared with you)" : "您的 Google Drive({formSize} + {formSharedSize} 與您共享)", 87 | "Your Google Drive ({formSize})" : "您的 Google Drive ({formSize})", 88 | "Import Google Drive files" : "導入 Google Drive 檔案", 89 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "您的 Google Drive 大於剩餘空間({formSpace})", 90 | "Cancel Google Drive import" : "取消 Google Drive 導入", 91 | "_{amount} photo imported_::_{amount} photos imported_" : ["導入了 {amount} 張照片"], 92 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["導入了 {amount} 個檔案({progress}%)"] 93 | }, 94 | "nplurals=1; plural=0;"); 95 | -------------------------------------------------------------------------------- /l10n/zh_HK.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No logged in user" : "沒有登錄用戶", 3 | "Missing refresh token in Google response." : "Google 回應中缺少刷新權杖。", 4 | "Error getting OAuth access token." : "取得 OAuth 存取權杖時發生錯誤。", 5 | "Error during OAuth exchanges" : "OAuth 交換時發生錯誤", 6 | "Google" : "Google", 7 | "_%n photo was imported from Google._::_%n photos were imported from Google._" : ["從 Google 匯入了 %n 張照片。"], 8 | "_%n file was imported from Google Drive._::_%n files were imported from Google Drive._" : ["從 Google Drive 匯入了 %n 個檔案。"], 9 | "OAuth access token refused" : "OAuth 存取權杖被拒絕", 10 | "Bad credentials" : "錯誤的身分驗證", 11 | "Google Calendar import" : "匯入 Google 日曆", 12 | "Private event" : "私人活動", 13 | "Connected accounts" : "已連線的帳號", 14 | "Data migration" : "數據遷移", 15 | "Google integration" : "Google 整合", 16 | "Import Google data into Nextcloud" : "將 Google 數據匯入 Nextcloud", 17 | "Google integration allows you to automatically migrate your Google calendars, contacts, photos and files into Nextcloud." : "Google 整合讓您自動將 Google Calendar,Contacts,Photos 和 Doc 遷移至 Nextcloud。", 18 | "Google admin options saved" : "已儲存 Google 管理員選項", 19 | "Failed to save Google admin options" : "儲存 Google 管理選項失敗", 20 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "如欲允許您的 Nextcloud 用戶向 Google 進行身份驗證,請在您的 Google 設置中創建一個 OAuth 應用程式。", 21 | "Google API settings" : "Google API 設定", 22 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "前往 \"APIs & Services\" => \"Credentials\" 然後單擊 \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"。", 23 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "將「Application type」設置為 \"Web application\",然後為應用程序命名。", 24 | "Google may require site verification for OAuth to work with your site, which can be done in Google's search console" : "Google可能需要對您的網站進行驗證,以便 OAuth 正常運作,這可以在 Google 搜尋控制台中完成", 25 | "Google Search console" : "Google 搜尋控制台", 26 | "Make sure you set one \"Authorized redirect URI\" to" : "確保您將「Authorized redirect URI」設定為", 27 | "Put the \"Client ID\" and \"Client secret\" below." : "在下方輸入「客戶端 ID」與「客戶端密碼」。", 28 | "Finally, go to \"APIs & Services\" => \"Library\" and add the following APIs: \"Google Drive API\", \"Google Calendar API\", \"People API\" and \"Photos Library API\"." : "最後,轉到 \"APIs & Services\" => \"Library\" 並添加以下 API:\"Google Drive API\"、\"Google Calendar API\"、\"People API\" 和 \"Photos Library API\"。", 29 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "您的 Nextcloud 用戶將會在他們的個人設定中看到【連線至 Google】按鈕。", 30 | "Client ID" : "客戶端 ID", 31 | "Client ID of your Google application" : "您 Google 應用程式的客戶端 ID", 32 | "Client secret" : "客戶端密碼", 33 | "Client secret of your Google application" : "您 Google 應用程式的客戶端密碼", 34 | "Use a pop-up to authenticate" : "使用彈出式視窗進行身份驗證", 35 | "Last photo import job at {date}" : "上次照片導入作業於 {date} 執行", 36 | "Photo import background process will begin soon." : "照片導入後台作業進程即將開始。", 37 | "You can close this page. You will be notified when it finishes." : "您可以關閉此頁面。完成時會通知您。", 38 | "Last Google Drive import job at {date}" : "上一次 Google Drive 導入作業的運行日期為 {date}", 39 | "Google Drive background import process will begin soon." : "Google Drive 導入後台作業進程即將開始。", 40 | "Successfully connected to Google!" : "與 Google 連線成功!", 41 | "Google connection error:" : "Google 連線錯誤: ", 42 | "Google options saved" : "已儲存 Google 選項", 43 | "Failed to save Google options" : "儲存 Google 選項失敗", 44 | "Sign in with Google" : "使用 Google 登入", 45 | "Failed to save Google OAuth state" : "儲存 Google OAuth 狀態失敗", 46 | "Failed to get Google Drive information" : "無法獲取Google Drive資訊", 47 | "Failed to get calendar list" : "讀取日曆清單失敗", 48 | "Failed to get number of Google photos" : "無法獲取Google照片數量", 49 | "Failed to get number of Google contacts" : "無法獲取Google聯絡人數量", 50 | "Failed to get address book list" : "讀取通訊錄清單失敗", 51 | "_{nbSeen} Google contact seen. {nbAdded} added, {nbUpdated} updated in {name}_::_{nbSeen} Google contacts seen. {nbAdded} added, {nbUpdated} updated in {name}_" : ["在 {name} 已看到 {nbSeen} 個 Google 聯絡人。已添加 {nbAdded} 個 ,更新了 {nbUpdated} 個"], 52 | "_{total} event successfully imported in {name} ({nbAdded} created, {nbUpdated} updated)_::_{total} events successfully imported in {name} ({nbAdded} created, {nbUpdated} updated)_" : ["在 {name} 中成功導入了 {total} 個活動(創建了 {nbAdded} 個,更新了 {nbUpdated} 個)"], 53 | "Failed to import Google calendar" : "無法匯入 Google 日曆", 54 | "Starting importing photos in {targetPath} directory" : "開始將照片導入到 {targetPath} 目錄", 55 | "Failed to start importing Google photos" : "無法開始導入 Google 照片", 56 | "Starting importing files in {targetPath} directory" : "開始將檔案導入到 {targetPath} 目錄", 57 | "Failed to start importing Google Drive" : "無法開始導入Google Drive", 58 | "Choose where to write imported files" : "選擇寫入導入檔案的位置", 59 | "Choose where to write imported photos" : "選擇寫入導入照片的位置", 60 | "Google data migration" : "Google 數據遷移", 61 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "未配置Google OAuth應用程式。要求您的Nextcloud管理員配置Google關聯帳戶管理部分。", 62 | "Authentication" : "驗證", 63 | "Connected as {user}" : "以 {user} 身分連線", 64 | "Disconnect from Google" : "與 Google 斷開連線", 65 | "Contacts" : "聯絡人", 66 | "{amount} Google contacts" : "{amount} 位 Google 聯絡人", 67 | "Import Google Contacts in Nextcloud" : "將 Google Contacts 匯入 Nextcloud", 68 | "Choose where to import the contacts" : "選擇導入聯絡人的通訊錄", 69 | "New address book" : "新通訊錄", 70 | "address book name" : "通訊錄名稱", 71 | "Import in \"{name}\" address book" : "導入 \"{name}\" 通訊錄", 72 | "Calendars" : "日曆", 73 | "Import calendar" : "導入日曆", 74 | "Photos" : "Photos", 75 | "Ignore shared albums" : "略過共享的相薄", 76 | "Warning: Google does not provide location data in imported photos." : "警告:Google不會在導入的照片中提供位置數據。", 77 | "Import directory" : "導入資料夾", 78 | "Import Google photos" : "導入 Google Photos", 79 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "您 Google 照片集的大小估計大於剩餘空間({formSpace})", 80 | "Cancel photo import" : "取消照片導入", 81 | "Drive" : "Drive", 82 | "Ignore shared files" : "略過共享的檔案", 83 | "Google documents import format" : "Google文件導入格式", 84 | "Your Google Drive ({formSize} + {formSharedSize} shared with you)" : "您的 Google Drive({formSize} + {formSharedSize} 與您共享)", 85 | "Your Google Drive ({formSize})" : "您的 Google Drive ({formSize})", 86 | "Import Google Drive files" : "導入 Google Drive 檔案", 87 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "您的 Google Drive 大於剩餘空間({formSpace})", 88 | "Cancel Google Drive import" : "取消 Google Drive 導入", 89 | "_{amount} photo imported_::_{amount} photos imported_" : ["導入了 {amount} 張照片"], 90 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["導入了 {amount} 個檔案({progress}%)"] 91 | },"pluralForm" :"nplurals=1; plural=0;" 92 | } -------------------------------------------------------------------------------- /l10n/zh_TW.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "No logged in user" : "無已登入的使用者", 5 | "Missing refresh token in Google response." : "Google 回應中缺少重新整理權杖。", 6 | "Error getting OAuth access token." : "取得 OAuth 存取權杖時發生錯誤", 7 | "Error during OAuth exchanges" : "OAuth 交換時發生錯誤", 8 | "Google" : "Google", 9 | "_%n photo was imported from Google._::_%n photos were imported from Google._" : ["從 Google 匯入 %n 張照片。"], 10 | "_%n file was imported from Google Drive._::_%n files were imported from Google Drive._" : ["從 Google 雲端硬碟匯入了 %n 個檔案。"], 11 | "OAuth access token refused" : "OAuth 存取權杖被拒絕", 12 | "Bad credentials" : "錯誤的憑證", 13 | "Google Calendar import" : "匯入 Google 日曆", 14 | "Private event" : "私人活動", 15 | "Connected accounts" : "已連結的帳號", 16 | "Data migration" : "資料遷移", 17 | "Google integration" : "Google 整合", 18 | "Import Google data into Nextcloud" : "將 Google 資料匯入至 Nextcloud", 19 | "Google integration allows you to automatically migrate your Google calendars, contacts, photos and files into Nextcloud." : "Google 整合讓您可以自動遷移您的 Google 日曆、聯絡人、照片與檔案至 Nextcloud。", 20 | "Google admin options saved" : "已儲存 Google 管理員選項", 21 | "Failed to save Google admin options" : "儲存 Google 管理員選項失敗", 22 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "若您想要讓您的 Nextcloud 使用者對 Google 進行身份驗證,請在您的 Google 設定中建立 OAuth 應用程式。", 23 | "Google API settings" : "Google API 設定", 24 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "前往「API 與服務」=>「憑證」然後點擊「建立憑證」->「OAuth 客戶端 ID」。", 25 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "將「應用程式類型」設定為「網路應用程式」,並為應用程式指定名稱。", 26 | "Google may require site verification for OAuth to work with your site, which can be done in Google's search console" : "Google 可能需要網站驗證才能讓 OAuth 與您的網站一起運作,這可以在 Google Search Console 中完成", 27 | "Google Search console" : "Google Search Console", 28 | "Make sure you set one \"Authorized redirect URI\" to" : "確保您將「已驗證重新導向 URI」設定為", 29 | "Put the \"Client ID\" and \"Client secret\" below." : "請在下方輸入「客戶端 ID」與「客戶端密碼」。", 30 | "Finally, go to \"APIs & Services\" => \"Library\" and add the following APIs: \"Google Drive API\", \"Google Calendar API\", \"People API\" and \"Photos Library API\"." : "最後,請到「API 與服務」=>「媒體庫」,然後新增以下 API:「Google Drive API」、「Google Calendar API」、「People API」與「Photos Library API」。", 31 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "您的 Nextcloud 使用者將會在他們的個人設定中看到「連結至 Google」按鈕", 32 | "Client ID" : "客戶端 ID", 33 | "Client ID of your Google application" : "您 Google 應用程式的客戶端 ID", 34 | "Client secret" : "客戶端密碼", 35 | "Client secret of your Google application" : "您 Google 應用程式的客戶端密碼", 36 | "Use a pop-up to authenticate" : "使用彈出式視窗進行驗證", 37 | "Last photo import job at {date}" : "上次照片匯入作業於 {date} 執行", 38 | "Photo import background process will begin soon." : "照片匯入背景流程即將開始。", 39 | "You can close this page. You will be notified when it finishes." : "您可以關閉此頁面。完成時會通知您。", 40 | "Last Google Drive import job at {date}" : "上次 Google 雲端硬碟匯入作業執行於 {date}", 41 | "Google Drive background import process will begin soon." : "Google 雲端硬碟匯入背景作業流程即將開始。", 42 | "Successfully connected to Google!" : "成功連結至 Google!", 43 | "Google connection error:" : "Google 連結錯誤:", 44 | "Google options saved" : "已儲存 Google 選項", 45 | "Failed to save Google options" : "儲存 Google 選項失敗", 46 | "Sign in with Google" : "使用 Google 登入", 47 | "Failed to save Google OAuth state" : "儲存 Google OAuth 狀態失敗", 48 | "Failed to get Google Drive information" : "取得 Google 雲端硬碟資訊失敗", 49 | "Failed to get calendar list" : "取得日曆清單失敗", 50 | "Failed to get number of Google photos" : "無法取得 Google 照片數量", 51 | "Failed to get number of Google contacts" : "無法取得 Google 聯絡人數量", 52 | "Failed to get address book list" : "取得通訊錄清單失敗", 53 | "_{nbSeen} Google contact seen. {nbAdded} added, {nbUpdated} updated in {name}_::_{nbSeen} Google contacts seen. {nbAdded} added, {nbUpdated} updated in {name}_" : ["在 {name} 已看到 {nbSeen} 個 Google 聯絡人。已新增 {nbAdded} 個 ,更新了 {nbUpdated} 個"], 54 | "_{total} event successfully imported in {name} ({nbAdded} created, {nbUpdated} updated)_::_{total} events successfully imported in {name} ({nbAdded} created, {nbUpdated} updated)_" : ["在 {name} 中成功匯入了 {total} 個事件(建立了 {nbAdded} 個,更新了 {nbUpdated} 個)"], 55 | "Failed to import Google calendar" : "匯入 Google 日曆失敗", 56 | "Starting importing photos in {targetPath} directory" : "開始將照片匯入至 {targetPath} 目錄", 57 | "Failed to start importing Google photos" : "無法開始匯入 Google 相簿", 58 | "Starting importing files in {targetPath} directory" : "開始匯入檔案至 {targetPath} 目錄", 59 | "Failed to start importing Google Drive" : "無法開始匯入 Google 雲端硬碟", 60 | "Choose where to write imported files" : "選擇要寫入匯入檔案的位置", 61 | "Choose where to write imported photos" : "選擇要寫入匯入照片的位置", 62 | "Google data migration" : "Google 資料遷移", 63 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "未設定 Google OAuth 應用程式。請要求您的 Nextcloud 管理員設定 Google 連結帳號管理員區塊。", 64 | "Authentication" : "驗證", 65 | "Connected as {user}" : "以 {user} 身份連線", 66 | "Disconnect from Google" : "已從 Google 斷開連結", 67 | "Contacts" : "聯絡人", 68 | "{amount} Google contacts" : "{amount} 位 Google 聯絡人", 69 | "Import Google Contacts in Nextcloud" : "在 Nextcloud 中匯入 Google 聯絡人", 70 | "Choose where to import the contacts" : "選擇要從哪裡匯入聯絡人", 71 | "New address book" : "新通訊錄", 72 | "address book name" : "通訊錄名稱", 73 | "Import in \"{name}\" address book" : "匯入於「{name}」通訊錄", 74 | "Calendars" : "日曆", 75 | "Import calendar" : "匯入日曆", 76 | "Photos" : "照片", 77 | "Ignore shared albums" : "戶略已分享的相簿", 78 | "Warning: Google does not provide location data in imported photos." : "警告:Google 不會在匯入的照片中提供位置資料。", 79 | "Import directory" : "匯入目錄", 80 | "Import Google photos" : "匯入 Google 相簿", 81 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "您 Google 相簿的大小預估大於剩餘空間({formSpace})", 82 | "Cancel photo import" : "取消照片匯入", 83 | "Drive" : "Drive", 84 | "Ignore shared files" : "忽略已分享的檔案", 85 | "Google documents import format" : "Google 文件匯入格式", 86 | "Your Google Drive ({formSize} + {formSharedSize} shared with you)" : "您的 Google 雲端硬碟({formSize} + 與您分享的 {formSharedSize})", 87 | "Your Google Drive ({formSize})" : "您的 Google 雲端硬碟({formSize})", 88 | "Import Google Drive files" : "匯入 Google 雲端硬碟檔案", 89 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "您的 Google 雲端硬碟大於剩餘空間({formSize})", 90 | "Cancel Google Drive import" : "取消 Google 雲端硬碟匯入", 91 | "_{amount} photo imported_::_{amount} photos imported_" : ["已匯入 {amount} 張照片"], 92 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["匯入了 {amount} 個檔案({progress}%)"] 93 | }, 94 | "nplurals=1; plural=0;"); 95 | -------------------------------------------------------------------------------- /l10n/zh_TW.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No logged in user" : "無已登入的使用者", 3 | "Missing refresh token in Google response." : "Google 回應中缺少重新整理權杖。", 4 | "Error getting OAuth access token." : "取得 OAuth 存取權杖時發生錯誤", 5 | "Error during OAuth exchanges" : "OAuth 交換時發生錯誤", 6 | "Google" : "Google", 7 | "_%n photo was imported from Google._::_%n photos were imported from Google._" : ["從 Google 匯入 %n 張照片。"], 8 | "_%n file was imported from Google Drive._::_%n files were imported from Google Drive._" : ["從 Google 雲端硬碟匯入了 %n 個檔案。"], 9 | "OAuth access token refused" : "OAuth 存取權杖被拒絕", 10 | "Bad credentials" : "錯誤的憑證", 11 | "Google Calendar import" : "匯入 Google 日曆", 12 | "Private event" : "私人活動", 13 | "Connected accounts" : "已連結的帳號", 14 | "Data migration" : "資料遷移", 15 | "Google integration" : "Google 整合", 16 | "Import Google data into Nextcloud" : "將 Google 資料匯入至 Nextcloud", 17 | "Google integration allows you to automatically migrate your Google calendars, contacts, photos and files into Nextcloud." : "Google 整合讓您可以自動遷移您的 Google 日曆、聯絡人、照片與檔案至 Nextcloud。", 18 | "Google admin options saved" : "已儲存 Google 管理員選項", 19 | "Failed to save Google admin options" : "儲存 Google 管理員選項失敗", 20 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "若您想要讓您的 Nextcloud 使用者對 Google 進行身份驗證,請在您的 Google 設定中建立 OAuth 應用程式。", 21 | "Google API settings" : "Google API 設定", 22 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "前往「API 與服務」=>「憑證」然後點擊「建立憑證」->「OAuth 客戶端 ID」。", 23 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "將「應用程式類型」設定為「網路應用程式」,並為應用程式指定名稱。", 24 | "Google may require site verification for OAuth to work with your site, which can be done in Google's search console" : "Google 可能需要網站驗證才能讓 OAuth 與您的網站一起運作,這可以在 Google Search Console 中完成", 25 | "Google Search console" : "Google Search Console", 26 | "Make sure you set one \"Authorized redirect URI\" to" : "確保您將「已驗證重新導向 URI」設定為", 27 | "Put the \"Client ID\" and \"Client secret\" below." : "請在下方輸入「客戶端 ID」與「客戶端密碼」。", 28 | "Finally, go to \"APIs & Services\" => \"Library\" and add the following APIs: \"Google Drive API\", \"Google Calendar API\", \"People API\" and \"Photos Library API\"." : "最後,請到「API 與服務」=>「媒體庫」,然後新增以下 API:「Google Drive API」、「Google Calendar API」、「People API」與「Photos Library API」。", 29 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "您的 Nextcloud 使用者將會在他們的個人設定中看到「連結至 Google」按鈕", 30 | "Client ID" : "客戶端 ID", 31 | "Client ID of your Google application" : "您 Google 應用程式的客戶端 ID", 32 | "Client secret" : "客戶端密碼", 33 | "Client secret of your Google application" : "您 Google 應用程式的客戶端密碼", 34 | "Use a pop-up to authenticate" : "使用彈出式視窗進行驗證", 35 | "Last photo import job at {date}" : "上次照片匯入作業於 {date} 執行", 36 | "Photo import background process will begin soon." : "照片匯入背景流程即將開始。", 37 | "You can close this page. You will be notified when it finishes." : "您可以關閉此頁面。完成時會通知您。", 38 | "Last Google Drive import job at {date}" : "上次 Google 雲端硬碟匯入作業執行於 {date}", 39 | "Google Drive background import process will begin soon." : "Google 雲端硬碟匯入背景作業流程即將開始。", 40 | "Successfully connected to Google!" : "成功連結至 Google!", 41 | "Google connection error:" : "Google 連結錯誤:", 42 | "Google options saved" : "已儲存 Google 選項", 43 | "Failed to save Google options" : "儲存 Google 選項失敗", 44 | "Sign in with Google" : "使用 Google 登入", 45 | "Failed to save Google OAuth state" : "儲存 Google OAuth 狀態失敗", 46 | "Failed to get Google Drive information" : "取得 Google 雲端硬碟資訊失敗", 47 | "Failed to get calendar list" : "取得日曆清單失敗", 48 | "Failed to get number of Google photos" : "無法取得 Google 照片數量", 49 | "Failed to get number of Google contacts" : "無法取得 Google 聯絡人數量", 50 | "Failed to get address book list" : "取得通訊錄清單失敗", 51 | "_{nbSeen} Google contact seen. {nbAdded} added, {nbUpdated} updated in {name}_::_{nbSeen} Google contacts seen. {nbAdded} added, {nbUpdated} updated in {name}_" : ["在 {name} 已看到 {nbSeen} 個 Google 聯絡人。已新增 {nbAdded} 個 ,更新了 {nbUpdated} 個"], 52 | "_{total} event successfully imported in {name} ({nbAdded} created, {nbUpdated} updated)_::_{total} events successfully imported in {name} ({nbAdded} created, {nbUpdated} updated)_" : ["在 {name} 中成功匯入了 {total} 個事件(建立了 {nbAdded} 個,更新了 {nbUpdated} 個)"], 53 | "Failed to import Google calendar" : "匯入 Google 日曆失敗", 54 | "Starting importing photos in {targetPath} directory" : "開始將照片匯入至 {targetPath} 目錄", 55 | "Failed to start importing Google photos" : "無法開始匯入 Google 相簿", 56 | "Starting importing files in {targetPath} directory" : "開始匯入檔案至 {targetPath} 目錄", 57 | "Failed to start importing Google Drive" : "無法開始匯入 Google 雲端硬碟", 58 | "Choose where to write imported files" : "選擇要寫入匯入檔案的位置", 59 | "Choose where to write imported photos" : "選擇要寫入匯入照片的位置", 60 | "Google data migration" : "Google 資料遷移", 61 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "未設定 Google OAuth 應用程式。請要求您的 Nextcloud 管理員設定 Google 連結帳號管理員區塊。", 62 | "Authentication" : "驗證", 63 | "Connected as {user}" : "以 {user} 身份連線", 64 | "Disconnect from Google" : "已從 Google 斷開連結", 65 | "Contacts" : "聯絡人", 66 | "{amount} Google contacts" : "{amount} 位 Google 聯絡人", 67 | "Import Google Contacts in Nextcloud" : "在 Nextcloud 中匯入 Google 聯絡人", 68 | "Choose where to import the contacts" : "選擇要從哪裡匯入聯絡人", 69 | "New address book" : "新通訊錄", 70 | "address book name" : "通訊錄名稱", 71 | "Import in \"{name}\" address book" : "匯入於「{name}」通訊錄", 72 | "Calendars" : "日曆", 73 | "Import calendar" : "匯入日曆", 74 | "Photos" : "照片", 75 | "Ignore shared albums" : "戶略已分享的相簿", 76 | "Warning: Google does not provide location data in imported photos." : "警告:Google 不會在匯入的照片中提供位置資料。", 77 | "Import directory" : "匯入目錄", 78 | "Import Google photos" : "匯入 Google 相簿", 79 | "Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})" : "您 Google 相簿的大小預估大於剩餘空間({formSpace})", 80 | "Cancel photo import" : "取消照片匯入", 81 | "Drive" : "Drive", 82 | "Ignore shared files" : "忽略已分享的檔案", 83 | "Google documents import format" : "Google 文件匯入格式", 84 | "Your Google Drive ({formSize} + {formSharedSize} shared with you)" : "您的 Google 雲端硬碟({formSize} + 與您分享的 {formSharedSize})", 85 | "Your Google Drive ({formSize})" : "您的 Google 雲端硬碟({formSize})", 86 | "Import Google Drive files" : "匯入 Google 雲端硬碟檔案", 87 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "您的 Google 雲端硬碟大於剩餘空間({formSize})", 88 | "Cancel Google Drive import" : "取消 Google 雲端硬碟匯入", 89 | "_{amount} photo imported_::_{amount} photos imported_" : ["已匯入 {amount} 張照片"], 90 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["匯入了 {amount} 個檔案({progress}%)"] 91 | },"pluralForm" :"nplurals=1; plural=0;" 92 | } -------------------------------------------------------------------------------- /lib/AppInfo/Application.php: -------------------------------------------------------------------------------- 1 | 8 | * @copyright Julien Veyssier 2020 9 | */ 10 | 11 | namespace OCA\Google\AppInfo; 12 | 13 | use OCA\Google\Notification\Notifier; 14 | use OCP\AppFramework\App; 15 | use OCP\AppFramework\Bootstrap\IBootContext; 16 | use OCP\AppFramework\Bootstrap\IBootstrap; 17 | use OCP\AppFramework\Bootstrap\IRegistrationContext; 18 | 19 | class Application extends App implements IBootstrap { 20 | 21 | public const APP_ID = 'integration_google'; 22 | // consider that a job is not running anymore after N seconds 23 | public const IMPORT_JOB_TIMEOUT = 3600; 24 | 25 | public function __construct(array $urlParams = []) { 26 | parent::__construct(self::APP_ID, $urlParams); 27 | } 28 | 29 | public function register(IRegistrationContext $context): void { 30 | $context->registerNotifierService(Notifier::class); 31 | } 32 | 33 | public function boot(IBootContext $context): void { 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/BackgroundJob/ImportDriveJob.php: -------------------------------------------------------------------------------- 1 | service->importDriveJob($userId); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/BackgroundJob/ImportPhotosJob.php: -------------------------------------------------------------------------------- 1 | service->importPhotosJob($userId); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/Migration/Version03001001Date20241111105515.php: -------------------------------------------------------------------------------- 1 | config->getAppValue(Application::APP_ID, $key); 38 | if ($value === '') { 39 | continue; 40 | } 41 | $this->config->setAppValue(Application::APP_ID, $key, $this->crypto->encrypt($value)); 42 | } 43 | 44 | // user tokens 45 | $qbUpdate = $this->connection->getQueryBuilder(); 46 | $qbUpdate->update('preferences') 47 | ->set('configvalue', $qbUpdate->createParameter('updateValue')) 48 | ->where( 49 | $qbUpdate->expr()->eq('appid', $qbUpdate->createNamedParameter(Application::APP_ID, IQueryBuilder::PARAM_STR)) 50 | ) 51 | ->andWhere( 52 | $qbUpdate->expr()->eq('userid', $qbUpdate->createParameter('updateUserId')) 53 | ) 54 | ->andWhere( 55 | $qbUpdate->expr()->eq('configkey', $qbUpdate->createNamedParameter('token', IQueryBuilder::PARAM_STR)) 56 | ); 57 | 58 | $qbSelect = $this->connection->getQueryBuilder(); 59 | $qbSelect->select('userid', 'configvalue') 60 | ->from('preferences') 61 | ->where( 62 | $qbSelect->expr()->eq('appid', $qbSelect->createNamedParameter(Application::APP_ID, IQueryBuilder::PARAM_STR)) 63 | ) 64 | ->andWhere( 65 | $qbSelect->expr()->eq('configkey', $qbSelect->createNamedParameter('token', IQueryBuilder::PARAM_STR)) 66 | ) 67 | ->andWhere( 68 | $qbSelect->expr()->nonEmptyString('configvalue') 69 | ) 70 | ->andWhere( 71 | $qbSelect->expr()->isNotNull('configvalue') 72 | ); 73 | $req = $qbSelect->executeQuery(); 74 | while ($row = $req->fetch()) { 75 | $userId = $row['userid']; 76 | $storedClearToken = $row['configvalue']; 77 | $encryptedToken = $this->crypto->encrypt($storedClearToken); 78 | $qbUpdate->setParameter('updateValue', $encryptedToken, IQueryBuilder::PARAM_STR); 79 | $qbUpdate->setParameter('updateUserId', $userId, IQueryBuilder::PARAM_STR); 80 | $qbUpdate->executeStatement(); 81 | } 82 | $req->closeCursor(); 83 | 84 | // user refresh tokens 85 | 86 | $qbUpdate = $this->connection->getQueryBuilder(); 87 | $qbUpdate->update('preferences') 88 | ->set('configvalue', $qbUpdate->createParameter('updateValue')) 89 | ->where( 90 | $qbUpdate->expr()->eq('appid', $qbUpdate->createNamedParameter(Application::APP_ID, IQueryBuilder::PARAM_STR)) 91 | ) 92 | ->andWhere( 93 | $qbUpdate->expr()->eq('userid', $qbUpdate->createParameter('updateUserId')) 94 | ) 95 | ->andWhere( 96 | $qbUpdate->expr()->eq('configkey', $qbUpdate->createNamedParameter('refresh_token', IQueryBuilder::PARAM_STR)) 97 | ); 98 | 99 | $qbSelect = $this->connection->getQueryBuilder(); 100 | $qbSelect->select('userid', 'configvalue') 101 | ->from('preferences') 102 | ->where( 103 | $qbSelect->expr()->eq('appid', $qbSelect->createNamedParameter(Application::APP_ID, IQueryBuilder::PARAM_STR)) 104 | ) 105 | ->andWhere( 106 | $qbSelect->expr()->eq('configkey', $qbSelect->createNamedParameter('refresh_token', IQueryBuilder::PARAM_STR)) 107 | ) 108 | ->andWhere( 109 | $qbSelect->expr()->nonEmptyString('configvalue') 110 | ) 111 | ->andWhere( 112 | $qbSelect->expr()->isNotNull('configvalue') 113 | ); 114 | $req = $qbSelect->executeQuery(); 115 | while ($row = $req->fetch()) { 116 | $userId = $row['userid']; 117 | $storedClearToken = $row['configvalue']; 118 | $encryptedToken = $this->crypto->encrypt($storedClearToken); 119 | $qbUpdate->setParameter('updateValue', $encryptedToken, IQueryBuilder::PARAM_STR); 120 | $qbUpdate->setParameter('updateUserId', $userId, IQueryBuilder::PARAM_STR); 121 | $qbUpdate->executeStatement(); 122 | } 123 | $req->closeCursor(); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /lib/Notification/Notifier.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright Julien Veyssier 2020 11 | */ 12 | 13 | namespace OCA\Google\Notification; 14 | 15 | use InvalidArgumentException; 16 | use OCA\Google\AppInfo\Application; 17 | use OCP\IURLGenerator; 18 | use OCP\L10N\IFactory; 19 | use OCP\Notification\INotification; 20 | use OCP\Notification\INotifier; 21 | 22 | class Notifier implements INotifier { 23 | 24 | public function __construct( 25 | private IFactory $factory, 26 | private IURLGenerator $url, 27 | ) { 28 | } 29 | 30 | /** 31 | * Identifier of the notifier, only use [a-z0-9_] 32 | * 33 | * @return string 34 | * @since 17.0.0 35 | */ 36 | public function getID(): string { 37 | return 'integration_google'; 38 | } 39 | /** 40 | * Human readable name describing the notifier 41 | * 42 | * @return string 43 | * @since 17.0.0 44 | */ 45 | public function getName(): string { 46 | return $this->factory->get('integration_google')->t('Google'); 47 | } 48 | 49 | /** 50 | * @param INotification $notification 51 | * @param string $languageCode The code of the language that should be used to prepare the notification 52 | * @return INotification 53 | * @throws InvalidArgumentException When the notification was not prepared by a notifier 54 | * @since 9.0.0 55 | */ 56 | public function prepare(INotification $notification, string $languageCode): INotification { 57 | if ($notification->getApp() !== 'integration_google') { 58 | // Not my app => throw 59 | throw new InvalidArgumentException(); 60 | } 61 | 62 | $l = $this->factory->get('integration_google', $languageCode); 63 | 64 | switch ($notification->getSubject()) { 65 | case 'import_photos_finished': 66 | /** @var array{nbImported?:string, targetPath: string} $p */ 67 | $p = $notification->getSubjectParameters(); 68 | $nbImported = (int)($p['nbImported'] ?? 0); 69 | $targetPath = $p['targetPath']; 70 | $content = $l->n('%n photo was imported from Google.', '%n photos were imported from Google.', $nbImported); 71 | 72 | $notification->setParsedSubject($content) 73 | ->setIcon($this->url->getAbsoluteURL($this->url->imagePath(Application::APP_ID, 'app-dark.svg'))) 74 | ->setLink($this->url->linkToRouteAbsolute('files.view.index', ['dir' => $targetPath])); 75 | return $notification; 76 | 77 | case 'import_drive_finished': 78 | /** @var array{nbImported?:string, targetPath: string} $p */ 79 | $p = $notification->getSubjectParameters(); 80 | $nbImported = (int)($p['nbImported'] ?? 0); 81 | $targetPath = $p['targetPath']; 82 | $content = $l->n('%n file was imported from Google Drive.', '%n files were imported from Google Drive.', $nbImported); 83 | 84 | $notification->setParsedSubject($content) 85 | ->setIcon($this->url->getAbsoluteURL($this->url->imagePath(Application::APP_ID, 'app-dark.svg'))) 86 | ->setLink($this->url->linkToRouteAbsolute('files.view.index', ['dir' => $targetPath])); 87 | return $notification; 88 | 89 | default: 90 | // Unknown subject => Unknown notification => throw 91 | throw new InvalidArgumentException(); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/Service/SecretService.php: -------------------------------------------------------------------------------- 1 | config->setUserValue($userId, Application::APP_ID, $key, ''); 29 | return; 30 | } 31 | $encryptedValue = $this->crypto->encrypt($value); 32 | $this->config->setUserValue($userId, Application::APP_ID, $key, $encryptedValue); 33 | } 34 | 35 | /** 36 | * @param string $userId 37 | * @param string $key 38 | * @return string 39 | * @throws \Exception 40 | */ 41 | public function getEncryptedUserValue(string $userId, string $key): string { 42 | $storedValue = $this->config->getUserValue($userId, Application::APP_ID, $key); 43 | if ($storedValue === '') { 44 | return ''; 45 | } 46 | return $this->crypto->decrypt($storedValue); 47 | } 48 | 49 | /** 50 | * @param string $key 51 | * @param string $value 52 | * @return void 53 | */ 54 | public function setEncryptedAppValue(string $key, string $value): void { 55 | if ($value === '') { 56 | $this->config->setAppValue(Application::APP_ID, $key, ''); 57 | return; 58 | } 59 | $encryptedValue = $this->crypto->encrypt($value); 60 | $this->config->setAppValue(Application::APP_ID, $key, $encryptedValue); 61 | } 62 | 63 | /** 64 | * @param string $key 65 | * @return string 66 | * @throws \Exception 67 | */ 68 | public function getEncryptedAppValue(string $key): string { 69 | $storedValue = $this->config->getAppValue(Application::APP_ID, $key); 70 | if ($storedValue === '') { 71 | return ''; 72 | } 73 | return $this->crypto->decrypt($storedValue); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/Service/UserScopeService.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * @author Julius Härtl 7 | * 8 | * @license GNU AGPL version 3 or any later version 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU Affero General Public License as 12 | * published by the Free Software Foundation, either version 3 of the 13 | * License, or (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU Affero General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Affero General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | namespace OCA\Google\Service; 26 | 27 | use OCP\IUserManager; 28 | use OCP\IUserSession; 29 | 30 | class UserScopeService { 31 | 32 | public function __construct( 33 | private IUserSession $userSession, 34 | private IUserManager $userManager, 35 | ) { 36 | } 37 | 38 | /** 39 | * Set a valid user in IUserSession since lots of server logic is relying on obtaining 40 | * the current acting user from that 41 | * 42 | * @param string|null $uid 43 | */ 44 | public function setUserScope(?string $uid = null): void { 45 | if ($uid === null) { 46 | return; 47 | } 48 | 49 | $user = $this->userManager->get($uid); 50 | if ($user === null) { 51 | throw new \InvalidArgumentException('No user found for the uid ' . $uid); 52 | } 53 | $this->userSession->setUser($user); 54 | } 55 | 56 | /** 57 | * Setup the FS which is needed to emit hooks 58 | * 59 | * This is required for versioning/activity as the legacy filesystem hooks 60 | * are not emitted if filesystem operations are executed though \OCP\Files\Node\File 61 | * 62 | * @param string $owner 63 | */ 64 | public function setFilesystemScope(string $owner): void { 65 | \OC_Util::tearDownFS(); 66 | \OC_Util::setupFS($owner); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/Settings/Admin.php: -------------------------------------------------------------------------------- 1 | secretService->getEncryptedAppValue('client_id'); 26 | $clientSecret = $this->secretService->getEncryptedAppValue('client_secret'); 27 | $usePopup = $this->config->getAppValue(Application::APP_ID, 'use_popup', '0'); 28 | 29 | $adminConfig = [ 30 | 'client_id' => $clientID, 31 | 'client_secret' => $clientSecret === '' ? $clientSecret : 'dummySecret', 32 | 'use_popup' => ($usePopup === '1'), 33 | ]; 34 | $this->initialStateService->provideInitialState('admin-config', $adminConfig); 35 | return new TemplateResponse(Application::APP_ID, 'adminSettings'); 36 | } 37 | 38 | public function getSection(): string { 39 | return 'connected-accounts'; 40 | } 41 | 42 | public function getPriority(): int { 43 | return 10; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/Settings/AdminSection.php: -------------------------------------------------------------------------------- 1 | l->t('Connected accounts'); 34 | } 35 | 36 | /** 37 | * @return int whether the form should be rather on the top or bottom of 38 | * the settings navigation. The sections are arranged in ascending order of 39 | * the priority values. It is required to return a value between 0 and 99. 40 | */ 41 | public function getPriority(): int { 42 | return 80; 43 | } 44 | 45 | public function getIcon(): string { 46 | return $this->urlGenerator->imagePath('core', 'categories/integration.svg'); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /lib/Settings/Personal.php: -------------------------------------------------------------------------------- 1 | userId === null) { 39 | return new TemplateResponse(Application::APP_ID, 'personalSettings'); 40 | } 41 | $userName = $this->config->getUserValue($this->userId, Application::APP_ID, 'user_name'); 42 | $driveOutputDir = $this->config->getUserValue($this->userId, Application::APP_ID, 'drive_output_dir', '/Google Drive'); 43 | $driveOutputDir = $driveOutputDir ?: '/Google Drive'; 44 | $photoOutputDir = $this->config->getUserValue($this->userId, Application::APP_ID, 'photo_output_dir', '/Google Photos'); 45 | $photoOutputDir = $photoOutputDir ?: '/Google Photos'; 46 | $considerSharedFiles = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_shared_files', '0') === '1'; 47 | $considerSharedAlbums = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_shared_albums', '0') === '1'; 48 | $documentFormat = $this->config->getUserValue($this->userId, Application::APP_ID, 'document_format', 'openxml'); 49 | if (!in_array($documentFormat, ['openxml', 'opendoc'])) { 50 | $documentFormat = 'openxml'; 51 | } 52 | 53 | // for OAuth 54 | $clientID = $this->secretService->getEncryptedAppValue('client_id'); 55 | $clientSecret = $this->secretService->getEncryptedAppValue('client_secret') !== ''; 56 | $usePopup = $this->config->getAppValue(Application::APP_ID, 'use_popup', '0'); 57 | 58 | // get free space 59 | $userFolder = $this->root->getUserFolder($this->userId); 60 | $freeSpace = self::getFreeSpace($userFolder, $driveOutputDir); 61 | $user = $this->userManager->get($this->userId); 62 | 63 | // make a request to potentially refresh the token before the settings page is loaded 64 | $accessToken = $this->secretService->getEncryptedUserValue($this->userId, 'token'); 65 | if ($accessToken) { 66 | $this->googleAPIService->request($this->userId, 'oauth2/v1/userinfo', ['alt' => 'json']); 67 | } 68 | 69 | // Get scopes of user 70 | $userScopesString = $this->config->getUserValue($this->userId, Application::APP_ID, 'user_scopes', '{}'); 71 | /** @var bool|null|array $userScopes */ 72 | $userScopes = json_decode($userScopesString, true); 73 | if (!is_array($userScopes)) { 74 | $userScopes = ['nothing' => 'nothing']; 75 | } 76 | 77 | $userConfig = [ 78 | 'client_id' => $clientID, 79 | 'client_secret' => $clientSecret, 80 | 'use_popup' => ($usePopup === '1'), 81 | 'user_name' => $userName, 82 | 'free_space' => $freeSpace, 83 | 'user_quota' => $user === null ? '' : $user->getQuota(), 84 | 'consider_shared_files' => $considerSharedFiles, 85 | 'consider_shared_albums' => $considerSharedAlbums, 86 | 'document_format' => $documentFormat, 87 | 'drive_output_dir' => $driveOutputDir, 88 | 'photo_output_dir' => $photoOutputDir, 89 | 'user_scopes' => $userScopes, 90 | ]; 91 | $this->initialStateService->provideInitialState('user-config', $userConfig); 92 | return new TemplateResponse(Application::APP_ID, 'personalSettings'); 93 | } 94 | 95 | public function getSection(): string { 96 | return 'migration'; 97 | } 98 | 99 | public function getPriority(): int { 100 | return 10; 101 | } 102 | 103 | /** 104 | * @param \OCP\Files\Folder $userRoot 105 | * @param string $outputDir 106 | * @return bool|float|int 107 | * @throws NotFoundException 108 | */ 109 | public static function getFreeSpace(\OCP\Files\Folder $userRoot, string $outputDir) { 110 | try { 111 | // OutputDir can be on an external storage which can have more free space 112 | $freeSpace = $userRoot->get($outputDir)->getStorage()->free_space('/'); 113 | } catch (\Throwable $e) { 114 | $freeSpace = false; 115 | } 116 | return $freeSpace !== false && $freeSpace > 0 ? $freeSpace : $userRoot->getStorage()->free_space('/'); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /lib/Settings/PersonalSection.php: -------------------------------------------------------------------------------- 1 | l->t('Data migration'); 34 | } 35 | 36 | /** 37 | * @return int whether the form should be rather on the top or bottom of 38 | * the settings navigation. The sections are arranged in ascending order of 39 | * the priority values. It is required to return a value between 0 and 99. 40 | */ 41 | public function getPriority(): int { 42 | return 80; 43 | } 44 | 45 | /** 46 | * @return string The relative path to a an icon describing the section 47 | */ 48 | public function getIcon(): string { 49 | return $this->urlGenerator->imagePath('core', 'actions/download.svg'); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Bernhard Posselt 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | 4 | # Generic Makefile for building and packaging a Nextcloud app which uses npm and 5 | # Composer. 6 | # 7 | # Dependencies: 8 | # * make 9 | # * which 10 | # * curl: used if phpunit and composer are not installed to fetch them from the web 11 | # * tar: for building the archive 12 | # * npm: for building and testing everything JS 13 | # 14 | # If no composer.json is in the app root directory, the Composer step 15 | # will be skipped. The same goes for the package.json which can be located in 16 | # the app root or the js/ directory. 17 | # 18 | # The npm command by launches the npm build script: 19 | # 20 | # npm run build 21 | # 22 | # The npm test command launches the npm test script: 23 | # 24 | # npm run test 25 | # 26 | # The idea behind this is to be completely testing and build tool agnostic. All 27 | # build tools and additional package managers should be installed locally in 28 | # your project, since this won't pollute people's global namespace. 29 | # 30 | # The following npm scripts in your package.json install and update the bower 31 | # and npm dependencies and use gulp as build system (notice how everything is 32 | # run from the node_modules folder): 33 | # 34 | # "scripts": { 35 | # "test": "node node_modules/gulp-cli/bin/gulp.js karma", 36 | # "prebuild": "npm install && node_modules/bower/bin/bower install && node_modules/bower/bin/bower update", 37 | # "build": "node node_modules/gulp-cli/bin/gulp.js" 38 | # }, 39 | 40 | app_name=$(notdir $(CURDIR)) 41 | build_tools_directory=$(CURDIR)/build/tools 42 | source_build_directory=$(CURDIR)/build/artifacts/source 43 | sign_dir=$(CURDIR)/build/artifacts/sign 44 | cert_dir=$(HOME)/.nextcloud/certificates 45 | source_package_name=$(source_build_directory)/$(app_name) 46 | appstore_build_directory=$(CURDIR)/build/artifacts/appstore 47 | appstore_package_name=$(appstore_build_directory)/$(app_name) 48 | npm=$(shell which npm 2> /dev/null) 49 | composer=$(shell which composer 2> /dev/null) 50 | 51 | all: build 52 | 53 | # Fetches the PHP and JS dependencies and compiles the JS. If no composer.json 54 | # is present, the composer step is skipped, if no package.json or js/package.json 55 | # is present, the npm step is skipped 56 | .PHONY: build 57 | build: 58 | ifneq (,$(wildcard $(CURDIR)/composer.json)) 59 | make composer 60 | endif 61 | ifneq (,$(wildcard $(CURDIR)/package.json)) 62 | make npm 63 | endif 64 | ifneq (,$(wildcard $(CURDIR)/js/package.json)) 65 | make npm 66 | endif 67 | 68 | # Installs and updates the composer dependencies. If composer is not installed 69 | # a copy is fetched from the web 70 | .PHONY: composer 71 | composer: 72 | ifeq (, $(composer)) 73 | @echo "No composer command available, downloading a copy from the web" 74 | mkdir -p $(build_tools_directory) 75 | curl -sS https://getcomposer.org/installer | php 76 | mv composer.phar $(build_tools_directory) 77 | php $(build_tools_directory)/composer.phar install --prefer-dist 78 | else 79 | composer install --prefer-dist 80 | endif 81 | 82 | # Installs npm dependencies 83 | .PHONY: npm 84 | npm: 85 | ifeq (,$(wildcard $(CURDIR)/package.json)) 86 | cd js && $(npm) run build 87 | else 88 | npm ci 89 | npm run build 90 | endif 91 | 92 | .PHONY: pack-models 93 | pack-models: 94 | cd models; \ 95 | $(foreach lang,$(LANGS),tar cvzf $(lang).tar.gz $(lang);) 96 | 97 | # Removes the appstore build 98 | .PHONY: clean 99 | clean: 100 | rm -rf ./build 101 | 102 | # Same as clean but also removes dependencies installed by composer, bower and 103 | # npm 104 | .PHONY: distclean 105 | distclean: clean 106 | rm -rf vendor 107 | rm -rf node_modules 108 | rm -rf js/vendor 109 | rm -rf js/node_modules 110 | 111 | # Builds the source and appstore package 112 | .PHONY: dist 113 | dist: 114 | make source 115 | make appstore 116 | 117 | # Builds the source package 118 | .PHONY: source 119 | source: 120 | rm -rf $(source_build_directory) 121 | mkdir -p $(source_build_directory) 122 | tar cvzf $(source_package_name).tar.gz ../$(app_name) \ 123 | --exclude-vcs \ 124 | --exclude="../$(app_name)/build" \ 125 | --exclude="../$(app_name)/js/node_modules" \ 126 | --exclude="../$(app_name)/node_modules" \ 127 | --exclude="../$(app_name)/*.log" \ 128 | --exclude="../$(app_name)/js/*.log" \ 129 | 130 | # Builds the source package for the app store, ignores php and js tests 131 | .PHONY: appstore 132 | appstore: 133 | rm -rf $(sign_dir) 134 | mkdir -p $(sign_dir) 135 | rm -rf $(appstore_build_directory) 136 | mkdir -p $(appstore_build_directory) 137 | composer install --no-dev 138 | rsync -a --delete \ 139 | --include=/CHANGELOG.md \ 140 | --include=/README.md \ 141 | --include=/AUTHORS.md \ 142 | --include=/COPYING \ 143 | --include=/package.json \ 144 | --include=/package-lock.json \ 145 | --include=/composer.json \ 146 | --include=/composer.lock \ 147 | --include=/src \ 148 | --include=/lib \ 149 | --include=/css \ 150 | --include=/img \ 151 | --include=/appinfo \ 152 | --include=/templates \ 153 | --include=/vendor \ 154 | --include=/js \ 155 | --include=/l10n \ 156 | --exclude=/* \ 157 | $(CURDIR)/ $(sign_dir)/$(app_name) 158 | tar -czf $(appstore_package_name).tar.gz \ 159 | -C $(sign_dir) $(app_name) 160 | @if [ -f $(cert_dir)/$(app_name).key ]; then \ 161 | echo "Signing package…"; \ 162 | openssl dgst -sha512 -sign $(cert_dir)/$(app_name).key $(appstore_package_name).tar.gz | openssl base64; \ 163 | fi 164 | 165 | .PHONY: test 166 | test: composer 167 | $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.xml 168 | $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "integration_google", 3 | "version": "3.1.1", 4 | "description": "Google integration", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "build": "NODE_ENV=production webpack --progress --config webpack.js", 11 | "dev": "NODE_ENV=development webpack --progress --config webpack.js", 12 | "watch": "NODE_ENV=development webpack --progress --watch --config webpack.js", 13 | "lint": "eslint --ext .js,.vue src", 14 | "lint:fix": "eslint --ext .js,.vue src --fix", 15 | "stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css", 16 | "stylelint:fix": "stylelint src/**/*.vue src/**/*.scss src/**/*.css --fix" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/nextcloud/integration_google" 21 | }, 22 | "keywords": [ 23 | "google" 24 | ], 25 | "author": "Julien Veyssier", 26 | "license": "AGPL-3.0", 27 | "bugs": { 28 | "url": "https://github.com/nextcloud/integration_google/issues" 29 | }, 30 | "homepage": "https://github.com/nextcloud/integration_google", 31 | "browserslist": [ 32 | "extends @nextcloud/browserslist-config" 33 | ], 34 | "engines": { 35 | "node": "^16.0.0", 36 | "npm": "^7.0.0 || ^8.0.0" 37 | }, 38 | "dependencies": { 39 | "@nextcloud/auth": "^2.0.0", 40 | "@nextcloud/axios": "^2.0.0", 41 | "@nextcloud/dialogs": "^3.1.2", 42 | "@nextcloud/initial-state": "^2.0.0", 43 | "@nextcloud/l10n": "^1.4.0", 44 | "@nextcloud/moment": "^1.3.4", 45 | "@nextcloud/password-confirmation": "^5.3.1", 46 | "@nextcloud/router": "^2.0.0", 47 | "@nextcloud/vue": "8.x", 48 | "vue": "^2.6.14", 49 | "vue-material-design-icons": "^5.3.1" 50 | }, 51 | "devDependencies": { 52 | "@nextcloud/babel-config": "^1.0.0", 53 | "@nextcloud/browserslist-config": "^2.2.0", 54 | "@nextcloud/eslint-config": "8.x", 55 | "@nextcloud/stylelint-config": "^3.x", 56 | "@nextcloud/webpack-vue-config": "6.x", 57 | "eslint-webpack-plugin": "4.x", 58 | "stylelint-webpack-plugin": "5.x" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/adminSettings.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | /** 4 | * Nextcloud - google 5 | * 6 | * 7 | * This file is licensed under the Affero General Public License version 3 or 8 | * later. See the COPYING file. 9 | * 10 | * @author Julien Veyssier 11 | * @copyright Julien Veyssier 2020 12 | */ 13 | 14 | import Vue from 'vue' 15 | import './bootstrap.js' 16 | import AdminSettings from './components/AdminSettings.vue' 17 | 18 | // eslint-disable-next-line 19 | 'use strict' 20 | 21 | // eslint-disable-next-line 22 | new Vue({ 23 | el: '#google_prefs', 24 | render: h => h(AdminSettings), 25 | }) 26 | -------------------------------------------------------------------------------- /src/bootstrap.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { translate, translatePlural } from '@nextcloud/l10n' 3 | 4 | Vue.prototype.t = translate 5 | Vue.prototype.n = translatePlural 6 | Vue.prototype.OC = window.OC 7 | Vue.prototype.OCA = window.OCA 8 | -------------------------------------------------------------------------------- /src/components/AdminSettings.vue: -------------------------------------------------------------------------------- 1 | 67 | 68 | 141 | 142 | 173 | -------------------------------------------------------------------------------- /src/components/icons/GoogleIcon.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 41 | -------------------------------------------------------------------------------- /src/personalSettings.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | 3 | /** 4 | * Nextcloud - google 5 | * 6 | * 7 | * This file is licensed under the Affero General Public License version 3 or 8 | * later. See the COPYING file. 9 | * 10 | * @author Julien Veyssier 11 | * @copyright Julien Veyssier 2020 12 | */ 13 | 14 | import Vue from 'vue' 15 | import './bootstrap.js' 16 | import PersonalSettings from './components/PersonalSettings.vue' 17 | 18 | // eslint-disable-next-line 19 | 'use strict' 20 | 21 | // eslint-disable-next-line 22 | new Vue({ 23 | el: '#google_prefs', 24 | render: h => h(PersonalSettings), 25 | }) 26 | -------------------------------------------------------------------------------- /src/popupSuccess.js: -------------------------------------------------------------------------------- 1 | import { loadState } from '@nextcloud/initial-state' 2 | 3 | const state = loadState('integration_google', 'popup-data') 4 | const username = state.user_name 5 | 6 | if (window.opener) { 7 | window.opener.postMessage({ username }) 8 | window.close() 9 | } 10 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | let mytimer = 0 2 | export function delay(callback, ms) { 3 | return function() { 4 | const context = this 5 | const args = arguments 6 | clearTimeout(mytimer) 7 | mytimer = setTimeout(function() { 8 | callback.apply(context, args) 9 | }, ms || 0) 10 | } 11 | } 12 | 13 | export function humanFileSize(bytes, approx = false, si = false, dp = 1) { 14 | const thresh = si ? 1000 : 1024 15 | 16 | if (Math.abs(bytes) < thresh) { 17 | return bytes + ' B' 18 | } 19 | 20 | const units = si 21 | ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] 22 | : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] 23 | let u = -1 24 | const r = 10 ** dp 25 | 26 | do { 27 | bytes /= thresh 28 | ++u 29 | } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1) 30 | 31 | if (approx) { 32 | return Math.floor(bytes) + ' ' + units[u] 33 | } else { 34 | return bytes.toFixed(dp) + ' ' + units[u] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /stylelint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'stylelint-config-recommended-vue', 3 | rules: { 4 | 'selector-type-no-unknown': null, 5 | 'rule-empty-line-before': [ 6 | 'always', 7 | { 8 | ignore: ['after-comment', 'inside-block'], 9 | }, 10 | ], 11 | 'declaration-empty-line-before': [ 12 | 'never', 13 | { 14 | ignore: ['after-declaration'], 15 | }, 16 | ], 17 | 'comment-empty-line-before': null, 18 | 'selector-type-case': null, 19 | 'no-descending-specificity': null, 20 | 'selector-pseudo-element-no-unknown': [ 21 | true, 22 | { 23 | ignorePseudoElements: ['v-deep'], 24 | }, 25 | ], 26 | }, 27 | plugins: ['stylelint-scss'], 28 | } 29 | -------------------------------------------------------------------------------- /templates/adminSettings.php: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 | -------------------------------------------------------------------------------- /templates/personalSettings.php: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 | -------------------------------------------------------------------------------- /templates/popupSuccess.php: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 | -------------------------------------------------------------------------------- /webpack.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpackConfig = require('@nextcloud/webpack-vue-config') 3 | const ESLintPlugin = require('eslint-webpack-plugin') 4 | const StyleLintPlugin = require('stylelint-webpack-plugin') 5 | 6 | const buildMode = process.env.NODE_ENV 7 | const isDev = buildMode === 'development' 8 | webpackConfig.devtool = isDev ? 'cheap-source-map' : 'source-map' 9 | 10 | webpackConfig.stats = { 11 | colors: true, 12 | modules: false, 13 | } 14 | 15 | const appId = 'integration_google' 16 | webpackConfig.entry = { 17 | personalSettings: { import: path.join(__dirname, 'src', 'personalSettings.js'), filename: appId + '-personalSettings.js' }, 18 | adminSettings: { import: path.join(__dirname, 'src', 'adminSettings.js'), filename: appId + '-adminSettings.js' }, 19 | popupSuccess: { import: path.join(__dirname, 'src', 'popupSuccess.js'), filename: appId + '-popupSuccess.js' }, 20 | } 21 | 22 | webpackConfig.plugins.push( 23 | new ESLintPlugin({ 24 | extensions: ['js', 'vue'], 25 | files: 'src', 26 | failOnError: !isDev, 27 | }) 28 | ) 29 | webpackConfig.plugins.push( 30 | new StyleLintPlugin({ 31 | files: 'src/**/*.{css,scss,vue}', 32 | failOnError: !isDev, 33 | }), 34 | ) 35 | 36 | module.exports = webpackConfig 37 | --------------------------------------------------------------------------------